Installation
Pick the path that matches how far you want to go:
| Path | What you get | Best for |
|---|---|---|
| Minimal | One container, SQLite, a local folder. No external services. | Trying it out, small/personal use |
| Full stack (Compose) | filex + PostgreSQL + Redis + OnlyOffice + MinIO + Caddy (auto‑HTTPS). | Real self‑hosting, teams |
| Kubernetes (Helm) | Helm chart with toggles for the same components. | Clusters |
| App stores | Ready-made packages for Umbrel, CasaOS, Runtipi, Unraid, Portainer. | Home servers / NAS |
| Binary | A single static binary. | No Docker, systemd, edge devices |
All paths end at the same place: the admin UI at …/admin, with a first‑run admin account (see First run).
Images. ghcr.io/brf-tech/filex:latest is the full‑featured image (thumbnails for image/video/pdf/office included). …:slim is a smaller image without the thumbnail toolchain — thumbnails then degrade to placeholder cards. The binary inside both is identical; only the runtime tooling differs.
Minimal
The fastest way to a running instance — SQLite, embedded search + thumbnails, one local storage folder, nothing external.
docker run -d --name filex -p 5212:5212 \
-e FILEX_PUBLIC_URL=http://localhost:5212 \
-v filex-data:/data \
ghcr.io/brf-tech/filex:latestOpen http://localhost:5212/admin and grab the first‑run password from the logs (docker logs filex).
Prefer Compose? Use deploy/compose/docker-compose.minimal.yml:
cd deploy/compose
docker compose -f docker-compose.minimal.yml up -d
docker compose -f docker-compose.minimal.yml logs -f # first-run credsIt also mounts ./files into the container at /srv/files — after logging in, add a local storage in the UI pointing at /srv/files and drop files there (see STORAGE.md).
Set
FILEX_PUBLIC_URLto the URL people actually open. Behind a reverse proxy that's yourhttps://…domain — it's baked into share links, the OIDC redirect, and OnlyOffice callbacks.
Full stack (Docker Compose)
A production‑shaped, one‑command stack: filex + PostgreSQL (database) + Redis (queue) + OnlyOffice (document editing) + MinIO (S3 storage) + Caddy (reverse proxy with automatic HTTPS). Files in deploy/compose/.
1. Configure.
cd deploy/compose
cp .env.example .env
$EDITOR .env # set domains + secretsSet FILEX_DOMAIN / ONLYOFFICE_DOMAIN and strong secrets (openssl rand -hex 24). The ONLYOFFICE_JWT_SECRET must be identical between filex and OnlyOffice — the compose file already wires the same variable to both.
Zero‑touch config. The admin account, SSO/LDAP/header auth, SMTP, branding and an initial storage can all be set through
FILEX_*env in.env, so the stack comes up already configured (no first‑run UI clicks). See CONFIGURATION.md (Authentication + Zero‑touch seeding) and thedeploy/compose/examples.
2. DNS. Point FILEX_DOMAIN and ONLYOFFICE_DOMAIN (and MINIO_CONSOLE_DOMAIN if you keep the console) at the host. Open ports 80 and 443 so Caddy can issue certificates.
3. Launch.
docker compose -f docker-compose.full.yml --env-file .env up -d
docker compose -f docker-compose.full.yml logs -f filex # first-run credsCaddy fetches HTTPS certs automatically; open https://<FILEX_DOMAIN>/admin.
4. Wire the bundled MinIO as a storage. Create a bucket in the MinIO console (https://<MINIO_CONSOLE_DOMAIN>), then Storages → Add an S3 storage:
- endpoint
http://minio:9000(filex reaches MinIO over the internal network) path_style= true,region=autobucket= your bucket,prefix=filexaccess_key/secret_key= yourMINIO_ROOT_USER/MINIO_ROOT_PASSWORD
OnlyOffice is already connected — open any Office file to edit it. See ONLYOFFICE.md and STORAGE.md.
Want a lighter "full"? Delete the services you don't need from the compose file and drop the matching
FILEX_*env from thefilexservice — everything is additive.
Kubernetes (Helm)
A Helm chart lives at deploy/helm/filex/. It deploys filex with a PVC for /data and an Ingress, and can pull in PostgreSQL, Redis, OnlyOffice and MinIO as optional dependencies.
# Minimal: filex + SQLite + a local PVC.
helm install filex ./deploy/helm/filex \
--set ingress.host=files.example.com
# Full: enable the bundled dependencies.
helm install filex ./deploy/helm/filex -f deploy/helm/filex/values-full.yaml \
--set ingress.host=files.example.com \
--set onlyoffice.ingress.host=office.example.comKey values.yaml toggles: postgresql.enabled, redis.enabled, onlyoffice.enabled, minio.enabled, persistence.size, ingress.*, resources. See the chart's values.yaml for the full list.
Zero‑touch config. Auth (OIDC/LDAP/header), the first admin, SMTP, branding and a default storage can all be supplied as
FILEX_*env in the chart values, so a fresh release boots fully configured with no admin‑UI setup. See CONFIGURATION.md (Authentication + Zero‑touch seeding) and thedeploy/helm/filex/values examples.
App stores
Ready-made packages for the common home-server platforms live under deploy/ — each directory has a README with install steps. All of them run the same single container (SQLite + local storage) and end at the same first run.
- Umbrel —
deploy/umbrel/filex/: community app-store package (app-proxy pattern); login isadmin@local+ the password Umbrel shows in the app dialog. - CasaOS —
deploy/casaos/: compose with thex-casaosstore metadata; paste it via Install a customized app. - Runtipi —
deploy/runtipi/filex/: dynamic compose app; the install form asks for the (optional) first admin. - Unraid —
deploy/unraid/: Community Applications template XML; map a share to/srv/filesand set the Public URL. - Portainer —
deploy/portainer/: App Templates v3 JSON; add the raw URL under Settings → App Templates.
Binary
filex ships as a single static binary (CGO‑free) for linux/macOS/Windows × amd64/arm64. Download the archive for your platform from the Releases page, extract, then:
./filex serveConfiguration is via FILEX_* environment variables (see CONFIGURATION.md) or a config.yaml (filex serve --config /path/to/config.yaml, or the FILEX_CONFIG env). Data goes to ~/.filex by default (override with FILEX_DATA_DIR).
systemd (Linux):
# /etc/systemd/system/filex.service
[Unit]
Description=filex file manager
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=filex
ExecStart=/usr/local/bin/filex serve
Restart=on-failure
RestartSec=5s
Environment=FILEX_DATA_DIR=/var/lib/filex
Environment=FILEX_LISTEN=127.0.0.1:5212
Environment=FILEX_PUBLIC_URL=https://files.example.com
[Install]
WantedBy=multi-user.targetsudo useradd --system --home /var/lib/filex --create-home filex
sudo install -m 0755 filex /usr/local/bin/filex
sudo systemctl enable --now filexPut it behind a reverse proxy for TLS (see Behind a reverse proxy).
Build from source
Requires Go 1.25+, Node 20+, pnpm 9+.
git clone https://github.com/BRF-Tech/filex.git
cd filex
pnpm install
pnpm run build:all # packages -> admin UI -> embed -> Go binary
./bin/filex serveCGO_ENABLED=0 means you can cross‑compile without a C toolchain (GOOS=linux GOARCH=arm64 go build ./backend/cmd/filex).
First run
On the very first start (empty user table) filex creates an admin account and prints the password once:
First run detected. Initial admin user created:
Email: admin@local
Password: <generated 16-char password>
Saved to: <data-dir>/.first-run.txt (mode 0600, shown ONCE)Sign in at …/admin, then change the password at Profile. Lost it? Reset from the CLI:
filex admin random-password --email admin@local
# in Docker: docker exec filex filex admin random-password --email admin@localEnable TOTP 2FA per user under Profile → Security. Add SSO/LDAP via SSO.md / CONFIGURATION.md.
Behind a reverse proxy
filex serves everything from one origin on port 5212 — the SPA, the API, public share (/s/…) and file‑drop (/d/…) pages, /embed.js, /healthz. Forward / to filex:5212 and:
- set
FILEX_PUBLIC_URLto the externalhttps://…URL, - pass the real client IP (
X-Real-IP/X-Forwarded-For) — used for audit and file‑drop rate limiting, - allow large bodies (e.g.
5G) and long timeouts for uploads, - allow WebSocket/SSE upgrades (the MCP stream at
/api/ai/mcp), - enable gzip for the admin SPA.
The bundled Caddy config (deploy/compose/Caddyfile) already does all of this; an nginx example is in DEPLOYMENT.md.
Data & backup
Everything filex owns lives under FILEX_DATA_DIR (/data in Docker):
instance.sqlite— the database (unless you use PostgreSQL/MySQL),search.bleve/— the full‑text index (rebuildable),thumbs/— the thumbnail cache (regenerable),.first-run.txt— the initial admin secret.
Back up the database (the SQLite file, or your Postgres) and your storage backends. The search index and thumbnail cache can be rebuilt (POST /api/admin/search/rebuild, filex thumb backfill), so backing them up is optional.
Upgrading
Pull the new image (or binary) and restart — migrations run automatically on startup. Back up the database first. To roll a schema back one step manually: filex migrate down.
See also
- CONFIGURATION.md — every
FILEX_*variable - STORAGE.md · SSO.md · ONLYOFFICE.md
- DEPLOYMENT.md — reverse proxy, HTTPS, scaling, backup
