FileZ
Drive-like app with Go backend + Bun/React frontend.
What is implemented
- Public registration disabled
- Admin-only account creation from web admin panel
- Admin credentials loaded from root
/.env(ADMIN_PASSWORD_HASH) - Secure auth: Argon2id password hashing, short-lived JWT access cookie, rotating hashed refresh tokens
- Per-account data isolation in user-specific roots
- File manager with upload, folder create, delete, preview, download
- Folder download as archive (ZIP by default, optional RAR)
- Markdown editor with live preview (
.md,.markdown) - In-app image/video preview dialog
- Resumable downloads via HTTP Range (
Accept-Ranges: bytes) - Expiring share links with optional max download count
- Programmer color schemes per user:
dracula|nord|monokai|solarized|github+light|dark|auto - Separate Web UI URLs:
/drive(files) and/admin(admin) - Landing page at
/ - UI uses Radix-based components (shadcn-style wrappers)
- Auto language detection with English/Russian translations
- Optional per-user FTP and FTPS access (same FileZ usernames/passwords)
- Optional Google OAuth login (auto-provisions user on first sign-in or links to existing signed-in user)
Task-style commands
Run from repository root:
npx --yes concurrently -n setup-backend,setup-frontend "cd backend && go mod tidy" "cd frontend && bun install"
Start both API and Web UI:
cd frontend && bun run dev:full
Build checks:
npx --yes concurrently -n build-api,build-web "cd backend && go build ./..." "cd frontend && bun run build"
Open URLs:
https://file.example.com/https://file.example.com/drivehttps://file.example.com/admin
Docker (no nginx)
This stack does not run nginx. Frontend is served by Bun (vite preview) and backend is Go.
All container runtime images are Alpine-based where possible.
Edit ports in root /.env:
APP_HOST_PORTAPP_INTERNAL_PORTBACKEND_HOST_PORTBACKEND_INTERNAL_PORTFRONTEND_HOST_PORTFRONTEND_INTERNAL_PORT
Use default app/backend config from root /.env.
Build and start:
make up
Run attached (foreground logs):
make run-all
Run locally without Docker (backend + frontend dev):
make run-local
Build and start as a single container (single binary backend with embedded frontend):
docker compose --profile single up -d --build
Stop:
make down
Single binary build (local)
Build one Linux binary that includes backend + frontend assets:
make build-all
Output binary:
dist/driveflow-allinone
Backend env
Defaults are already provided in root /.env.
Important values:
ADMIN_LOGINADMIN_PASSWORD_HASHJWT_SECRETDB_PATHSTORAGE_ROOTALLOWED_HOSTCORS_ALLOWED_ORIGINAPP_DOMAINMAX_BODY_MBRATE_LIMIT_PER_MINAUTH_RATE_LIMIT_PER_MINGOOGLE_AUTH_ENABLEDGOOGLE_CLIENT_ID,GOOGLE_CLIENT_SECRET- optional
GOOGLE_REDIRECT_URL(default:https://<host>/api/auth/google/callback) - optional overrides
GOOGLE_AUTH_URL,GOOGLE_TOKEN_URL,GOOGLE_USERINFO_URL FTP_ENABLEDFTP_HOST,FTP_PORT,FTP_PUBLIC_IP,FTP_PASSIVE_PORTSFTPS_ENABLEDFTPS_HOST,FTPS_PORT,FTPS_PUBLIC_IP,FTPS_PASSIVE_PORTSFTPS_CERT_FILE,FTPS_KEY_FILE,FTPS_EXPLICIT,FTPS_FORCE_TLSFTPS_LETSENCRYPT_DOMAIN,FTPS_LETSENCRYPT_DIR
Generate admin hash:
cd backend && go run . hash-admin "your-strong-password"
Host/CORS policy:
- Requests are allowed only when host matches
ALLOWED_HOST(example:file.example.com) - CORS allows only
CORS_ALLOWED_ORIGIN - If
ALLOWED_HOST/CORS_ALLOWED_ORIGINare empty, backend derives them fromAPP_DOMAIN
API security hardening:
- Security headers (CSP, HSTS, X-Frame-Options, etc.)
- Request body size limits for non-upload API endpoints
- Built-in per-IP rate limiting (general and stricter auth limits)
- Panic recovery middleware
Folder archive notes:
- User can choose archive format in UI Settings modal
ZIPworks out of the boxTAR.GZworks out of the boxRARrequiresrarbinary installed on the backend host/containerLZ4requireslz4binary installed on the backend host/container
File tags:
- Users can assign tags to files/folders directly in Drive
- Tags are stored per-user and can be used as a sidebar filter
Optional FTP server mode (same credentials as Web login):
FTP_ENABLED=trueFTP_HOST=0.0.0.0FTP_PORT=2121- Optional passive mode config:
FTP_PUBLIC_IP,FTP_PASSIVE_PORTS
Optional FTPS server mode (same credentials as Web login, per-user roots):
FTPS_ENABLED=trueFTPS_HOST=0.0.0.0FTPS_PORT=2990FTPS_CERT_FILE=/path/to/fullchain.pemFTPS_KEY_FILE=/path/to/privkey.pem- OR Let's Encrypt paths auto-discovery:
FTPS_LETSENCRYPT_DOMAIN=file.example.com- optional
FTPS_LETSENCRYPT_DIR=/etc/letsencrypt/live
- Optional passive mode config:
FTPS_PUBLIC_IP,FTPS_PASSIVE_PORTS FTPS_EXPLICIT=trueenables explicit FTPS (AUTH TLS)FTPS_FORCE_TLS=truerequires TLS for authenticated sessions
Optional Google OAuth login:
GOOGLE_AUTH_ENABLED=trueGOOGLE_CLIENT_ID=...GOOGLE_CLIENT_SECRET=...GOOGLE_REDIRECT_URL=https://file.example.com/api/auth/google/callback(recommended)- Add redirect URI in Google Cloud Console to match your callback URL