Skip to content

Configuration

filex reads configuration in this order (highest precedence first):

  1. Environment variables (FILEX_*)
  2. config.yaml (path via --config, FILEX_CONFIG, or ~/.filex/config.yaml if present)
  3. Built-in defaults

For containers, environment variables are easiest. For rich setups (LDAP, proxy‑header auth, custom CORS) a config.yaml is handier because a few settings are file‑only (noted below). Individual storages are not configured here — they're database records; see STORAGE.md.

Booleans are true only for "1" or (case‑insensitive) "true". Any other non‑empty value is treated as false.


Server & networking

Env varDefaultDescription
FILEX_LISTEN0.0.0.0:5212Bind address.
FILEX_PUBLIC_URLhttp://localhost:5212The external URL users open. Baked into share links, the OIDC redirect and OnlyOffice fetch/callback — set it to your real https://… domain behind a proxy.
FILEX_DATA_DIR~/.filex (/data in Docker)Holds the SQLite DB, search index, thumbnail cache, first‑run secret.
FILEX_DEFAULT_LOCALEPin the initial UI language (en / tr) for users who haven't chosen one, overriding browser detection. A user's explicit language switch still wins.
FILEX_MULTI_TENANTfalseTurn on native multi-tenancy — one install serves N tenants, each a host-bound auth realm (provider) confined to its own storage(s). Off = a normal single-tenant install, behaviour unchanged. See MULTI-TENANCY.md.
FILEX_COOKIE_DOMAIN— (host-only)Domain attribute for the filex_session cookie, e.g. .example.com — subdomains of that domain then share the session. Applied on both set and clear, so logout removes the same cookie it created. Empty = host-only cookie (unchanged behaviour). Secure/SameSite/HttpOnly are unaffected. Multi-tenant: this is only the last-resort fallback — the cookie Domain resolves per tenant: the provider's cookie_domain field wins, else it is derived from the provider host by dropping its first label (files.example.com.example.com), else this global value. ⚠ A tenant served on its bare apex, or whose derivation would land on a public suffix (tenant.com.tr.com.tr, which browsers reject), must set cookie_domain explicitly. See MULTI-TENANCY.md.
FILEX_CONFIGPath to config.yaml (same as --config).

Logging

Env varDefaultDescription
FILEX_LOG_LEVELinfodebug · info · warn · error
FILEX_LOG_FORMATtexttext · json

Database

Env varDefaultDescription
FILEX_DB_DRIVERsqlitesqlite · postgres · mysql
FILEX_DB_DSNConnection string. Empty + sqlite → <data_dir>/instance.sqlite.

DSN examples:

  • postgres: postgres://user:pass@host:5432/dbname?sslmode=require
  • mysql: user:pass@tcp(host:3306)/dbname?parseTime=true&loc=UTC&charset=utf8mb4

Migrations run automatically on startup; also filex migrate up|down|status. SQLite (pure Go, CGO‑free) is a fine default; PostgreSQL is recommended for teams/HA. MySQL is supported for read‑mostly use (a few upsert paths are SQLite/Postgres‑only). See database drivers note above.


Authentication

Pick drivers with FILEX_AUTH_DRIVERS (comma list, tried in order, first match wins). The API‑token driver is always on regardless.

Env varDefaultDescription
FILEX_AUTH_DRIVERSlocale.g. local,oidc, local,ldap, proxy_header

OIDC / SSO (see SSO.md):

Env var (legacy FILEX_AUTH_OIDC_* also accepted)Description
FILEX_OIDC_ISSUERIdP issuer URL
FILEX_OIDC_CLIENT_IDClient ID
FILEX_OIDC_CLIENT_SECRETClient secret
FILEX_OIDC_REDIRECT_URL<public>/api/auth/oidc/callback
FILEX_OIDC_ROLE_CLAIMClaim carrying roles/groups
FILEX_OIDC_ADMIN_GROUPValue that elevates to admin
FILEX_OIDC_AUTO_REDIRECTSSO-first login (default false): the login page starts the OIDC flow immediately instead of showing the password form. Local login stays available behind a "Sign in with password" link (/admin/login?local=1) for break-glass/admin@local. The redirect is skipped on ?local=1, after a failed IdP round-trip (?error=oidc) and on ?maintenance=1, so a broken IdP can never cause a redirect loop. Requires oidc in FILEX_AUTH_DRIVERS. Multi-tenant: the flag is instance-global; the flow itself already dispatches per request host to the right tenant realm.

LDAP (enable with FILEX_AUTH_DRIVERS=local,ldap):

Env varDescription
FILEX_LDAP_URLDirectory URL, e.g. ldaps://ldap.example.com
FILEX_LDAP_BIND_DNService bind DN
FILEX_LDAP_BIND_PASSWORDService bind password
FILEX_LDAP_BASE_DNSearch base for users
FILEX_LDAP_USER_FILTERUser filter, e.g. (mail=%s)
FILEX_LDAP_EMAIL_ATTRAttribute holding the email (e.g. mail)
FILEX_LDAP_START_TLStrue to upgrade a plain connection with StartTLS

Proxy‑header — trust an authenticating reverse proxy (enable with FILEX_AUTH_DRIVERS=proxy_header):

Env varDescription
FILEX_HEADER_EMAILHeader carrying the authenticated email (e.g. X-Auth-Email)
FILEX_HEADER_GROUPHeader carrying roles/groups (e.g. X-Auth-Roles)
FILEX_HEADER_TRUSTED_IPSComma list of proxy CIDRs allowed to set the headers
FILEX_HEADER_ADMIN_GROUPGroup value that elevates a user to admin

LDAP and proxy‑header can still be set under auth.ldap.* / auth.header_proxy.* in config.yaml; the env vars above override those. See SSO.md → other auth drivers.

Local auth uses the filex_session cookie (12 h), bcrypt passwords, optional TOTP 2FA. First boot creates admin@local (or seed a known admin — see Zero‑touch seeding and INSTALLATION.md).


Zero-touch seeding

These variables seed the database once, on first boot, only when the target record is absent. They let a fresh docker compose up / helm install come up fully configured from env alone — no admin‑UI clicks. Once a record exists, later operator edits in the UI always win; changing the env afterwards does not re‑seed or overwrite. (OIDC/LDAP/header auth are read live from env every boot and so are configured in Authentication, not here.)

First admin — created if the user table is empty:

Env varDefaultDescription
FILEX_ADMIN_EMAILadmin@localEmail of the seeded admin account.
FILEX_ADMIN_PASSWORD(random, printed once)Password for that admin. Omit both to get a random admin@local (see INSTALLATION.md → first run).

SMTP (mailer) — seeded when host, port and from are all set:

Env varDescription
FILEX_SMTP_HOSTSMTP server host.
FILEX_SMTP_PORTSMTP server port.
FILEX_SMTP_USERNAMEAuth username (optional).
FILEX_SMTP_PASSWORDAuth password (optional).
FILEX_SMTP_FROMFrom address on outbound mail.
FILEX_SMTP_TLSstarttls · tls · none.

Branding & trash:

Env varDescription
FILEX_SITE_NAMEInstance display name shown in the UI.
FILEX_TRASH_RETENTION_DAYSDays to keep trashed items before purge (see TRASH-VERSIONING.md).

Default storage — seeds one initial storage when no storage exists yet, so a fresh install already has a working place for files. Leave FILEX_DEFAULT_STORAGE_DRIVER empty to seed nothing. (See STORAGE.md for the storage model.)

Env varApplies toDescription
FILEX_DEFAULT_STORAGE_DRIVERbothlocal · s3 (empty = seed no storage).
FILEX_DEFAULT_STORAGE_NAMEbothDisplay name / top‑level folder label.
FILEX_DEFAULT_STORAGE_MOUNTbothLogical mount point (default /).
FILEX_DEFAULT_STORAGE_PATHlocalOn‑disk directory to serve.
FILEX_DEFAULT_STORAGE_S3_BUCKETs3Bucket name.
FILEX_DEFAULT_STORAGE_S3_PREFIXs3Key prefix = storage root (keep non‑empty — root guard).
FILEX_DEFAULT_STORAGE_S3_ENDPOINTs3Custom endpoint (MinIO/R2/Hetzner …); omit for AWS.
FILEX_DEFAULT_STORAGE_S3_REGIONs3e.g. us-east-1; auto for R2/MinIO.
FILEX_DEFAULT_STORAGE_S3_ACCESS_KEYs3Access key.
FILEX_DEFAULT_STORAGE_S3_SECRET_KEYs3Secret key.
FILEX_DEFAULT_STORAGE_S3_PATH_STYLEs3true for path‑style addressing (MinIO/Hetzner/B2/R2).

External services

Each is optional — an empty URL disables it. Set via env or external_services.*.

Env varDescription
FILEX_ONLYOFFICE_URLOnlyOffice Document Server URL (see ONLYOFFICE.md)
FILEX_ONLYOFFICE_JWTShared JWT secret — must match the Document Server
FILEX_DRAWIO_URLDrawio embed URL (diagram editing)
FILEX_CONVERT_URLExternal universal converter URL

Mermaid needs no service. Mermaid diagrams render entirely client‑side in the browser via a bundled mermaid library — there is nothing to deploy and no URL to set (the former FILEX_MERMAID_URL was removed).


Storage sync

Global fallback cadence for the sync worker. Per‑storage sync_interval_s overrides this.

Env varDefaultDescription
FILEX_SYNC_INTERVAL15mGo duration (30s, 15m, 1h).
FILEX_SYNC_WORKERS4Concurrent storage sync workers.

⚠ The variable is FILEX_SYNC_INTERVAL, not FILEX_SYNC_DEFAULT_INTERVAL.


Thumbnails

Env varDefaultDescription
FILEX_THUMBS_ENABLEDtrueMaster switch.
FILEX_THUMB_BACKFILL_ON_BOOTSet once to backfill missing thumbnails on startup.

Kinds and their tool requirements (auto‑detected on PATH; the full Docker image bundles them): images = built‑in; video/audio = ffmpeg; PDF = gs or pdftoppm; office = libreoffice; SVG = rsvg-convert. Missing tool → that kind gets a generic placeholder card. Cache dir + formats are config.yaml only (thumbs.cache_dir, thumbs.formats). See thumbnails.md.


Env varDefaultDescription
FILEX_SEARCH_ENABLEDtrueEmbedded Bleve full‑text index.

Index path is config.yaml only (search.index_path, default <data_dir>/search.bleve). See SEARCH.md.


Queue

Env varDefaultDescription
FILEX_QUEUE_DRIVERsqlitesqlite · postgres · redis
FILEX_QUEUE_DSNpostgres://… or redis://… (ignored for sqlite — shares the app DB)
FILEX_QUEUE_WORKERS4Worker pool size.
FILEX_QUEUE_ENABLEDtrueDisable to run without the persistent queue.

Use redis or postgres for multi‑node deployments (postgres uses SELECT … FOR UPDATE SKIP LOCKED). sqlite is fine single‑node.


Notifications

Env varDefaultDescription
FILEX_NOTIFY_ENABLEDtrueIn‑app bell + webhook.
FILEX_WEBHOOK_URLGeneric JSON POST per event (empty = in‑app only).
FILEX_WEBHOOK_TOKENSent as Authorization: Bearer to the webhook.

See NOTIFICATIONS.md.


CORS

Env varDefaultDescription
FILEX_CORS_ALLOWED_ORIGINS*Comma list. Restrict when embedding the component from specific origins.

allowed_methods / allowed_headers are config.yaml only. Default allowed headers: Authorization, Content-Type, X-Filex-Pin. If you use API‑token root confinement from a browser, add X-Filex-Token / X-Filex-Root.


Error reporting

Optional Sentry‑wire reporting (works with self‑hosted GlitchTip). Empty DSN = off.

Env varDefaultDescription
FILEX_SENTRY_DSNSentry/GlitchTip DSN.
FILEX_SENTRY_ENVIRONMENTTag events (e.g. production).

Demo mode

Env varDefaultDescription
FILEX_DEMO_MODEfalseRenders an "Open the demo" CTA on the login page.
FILEX_DEMO_USERdemo@demo.comDemo credentials the CTA submits.
FILEX_DEMO_PASSdemo(Keep the DB user in sync.)

config.yaml

Every field is optional; pass with --config /path/to/config.yaml.

yaml
listen: "0.0.0.0:5212"
public_url: "https://files.example.com"
data_dir: "/data"

log:   { level: info, format: text }
db:    { driver: sqlite, dsn: "" }

auth:
  drivers: [local, oidc]           # local | oidc | ldap | proxy_header
  oidc:
    issuer: https://id.example.com/realms/main
    client_id: filex
    client_secret: "…"
    redirect_url: https://files.example.com/api/auth/oidc/callback
    role_claim: realm_access.roles
    admin_group: filex-admin
  ldap:                            # also overridable via FILEX_LDAP_*
    url: ldaps://ldap.example.com
    bind_dn: "cn=svc,dc=example,dc=com"
    bind_password: "…"
    base_dn: "ou=people,dc=example,dc=com"
    user_filter: "(mail=%s)"
    email_attr: mail
    start_tls: false
  header_proxy:                    # trust an auth proxy — also FILEX_HEADER_*
    email_header: X-Auth-Email
    group_header: X-Auth-Roles
    trusted_ips: ["10.0.0.0/8"]
    admin_group: admin

external_services:
  onlyoffice: { url: https://office.example.com, jwt_secret: "…" }
  drawio:     { url: "" }        # mermaid renders client-side — no service
  convert:    { url: "" }

sync:   { default_interval: 15m, workers: 4 }
thumbs: { enabled: true, formats: [image, video, pdf, office], cache_dir: "" }
search: { enabled: true, index_path: "" }
cors:
  allowed_origins: ["*"]
  allowed_methods: [GET, POST, PUT, DELETE, PATCH, OPTIONS]
  allowed_headers: [Authorization, Content-Type, X-Filex-Pin]
queue:  { driver: sqlite, dsn: "", workers: 4, enabled: true }
notify: { enabled: true, webhook_url: "", webhook_token: "" }
demo:   { mode: false, user: demo@demo.com, pass: demo }
sentry: { dsn: "", environment: "" }

seed:                              # first-boot only-if-absent (see Zero-touch seeding)
  admin_email: ""
  admin_password: ""
  site_name: ""
  trash_retention_days: ""
  smtp:    { host: "", port: "", username: "", password: "", from: "", tls: starttls }
  storage: { driver: "", name: "", mount_path: "/", path: "",
             bucket: "", prefix: "", endpoint: "", region: "",
             access_key: "", secret_key: "", path_style: false }

Some settings (branding, default thumbnail policy) live in the database settings table and are managed from the admin UI, not here.


Gotchas

  • FILEX_SYNC_DEFAULT_INTERVAL is not read — the correct var is FILEX_SYNC_INTERVAL.
  • FILEX_DEFAULT_STORAGE_* only takes effect on a fresh install (it seeds a default storage when none exists yet); it never edits or replaces an existing storage. See Zero‑touch seeding.
  • Booleans accept only "1" / "true"; anything else is false.
  • LDAP and proxy‑header now have env vars (FILEX_LDAP_* / FILEX_HEADER_*); the env value overrides the matching config.yaml field.

Released under the MIT License.