Innovation Labs
Self-Hosted Private File Vault
The back-room storeroom behind Download District. A private, self-hosted web app for storing and retrieving installer and tool files โ organised by category, fast to search, zero cloud. Built for one person who knows what they need.
Overview
The Depot is a single Docker container running on the home lab, reachable from any device on the local network. Its one job: store .exe and .zip files, organised by category, and make them fast to find and download when a job needs them. No login, no cloud, no accounts. Local network only. Just files, organised, available.
The smart bit is the auto-describe feature โ when you drop a file, The Depot guesses a clean name, web-searches it, and suggests a one-line description and best-guess category. Both go into the form for you to keep or edit. Nothing is committed automatically. A "Look it up" button re-runs the search on demand.
Every upload is SHA-256 hashed. Re-uploading the same bytes is blocked with a clear message, even under a different filename. Two genuinely different files that happen to share a name still coexist fine.
What It Does
/ jumps to search, Esc cancels upload or clears searchCategories
Fixed list in code โ keeps the UI clean. New categories are a one-line code change.
Architecture
The entire UI lives in a single templates/index.html file โ CSS and JS inline, no framework, no build step. After initial load, all search, filter, and sort operations are client-side and never round-trip to the server.
The Flask backend handles only what it needs to: file I/O, database writes, hashing, and the one external call โ a DuckDuckGo Instant Answer lookup using Python's standard library (urllib only, no API key). Everything else is fully local.
Files are stored on disk as <id>_<originalname> โ the ID prefix prevents collisions while the original name is preserved in the database and handed back verbatim on every download. In Docker both the files and the SQLite database live in a single /app/data directory that is bind-mounted to the host, so data survives every rebuild.
API Routes
Database Schema
Older databases are auto-migrated to add the sha256 column on startup โ no manual migration needed.
Design Decisions
/app/data directory. Binding the DB as a lone file would cause Docker to silently create a directory instead, breaking SQLite.app.py, not stored in the database. Keeps the UI clean. New categories are a one-line code change, not a UI feature.Tech Stack
Screenshot