added filebrowser Quantum since the main Filebrowser is not going to continue

This commit is contained in:
Goyban
2026-08-27 16:17:16 +02:00
parent dc03dce2a2
commit 2476bd0b3b
5 changed files with 247 additions and 0 deletions
+1
View File
@@ -39,6 +39,7 @@ handled separately — see [Exposing services](#exposing-services).
| [audiobookshelf](audiobookshelf/) | 13378 | Audiobooks and podcasts, with per-user progress sync |
| [cloudflare-tunnel](cloudflare-tunnel/) | — | Outbound connector. Exposes other services without opening a port |
| [codeserver](codeserver/) | 8443 | VS Code in a browser. Effectively a remote shell — read its README before exposing |
| [filebrowser](filebrowser/) | 3672 | Web file manager for one directory tree (FileBrowser Quantum fork) |
| [jellyfin](jellyfin/) | 8096 | Media streaming. Also 7359/udp for auto-discovery |
| [openwebui](openwebui/) | 3033 | LLM chat UI. One `OWUI_TAG` switches between CPU, CUDA and bundled-Ollama |
| [overleaf](overleaf/) | 8020 | LaTeX editor. Four containers: app, Mongo (replica set), Redis, init |
+25
View File
@@ -0,0 +1,25 @@
# Copy to .env and adjust. .env is git-ignored; this file is not.
# ─── Required ───────────────────────────────────────────────────────
# The directory to browse. Mounted at /srv inside the container, which is
# what init/config.yaml points at.
#
# Add `:ro` to the volume line in compose.yaml if you want a viewer rather
# than a file manager -- worth considering, since anyone who logs in can
# delete whatever they can see.
BROWSE_PATH=/srv/downloads
# ─── Paths ──────────────────────────────────────────────────────────
# SQLite database: users, shares, search index. Back this up. Small.
#DATA_PATH=./data
# ─── Identity ───────────────────────────────────────────────────────
# The image runs as its own non-root user, uid/gid 1000, and reads no
# PUID/PGID -- these feed Docker's `user:` directive instead. They must be
# able to read BROWSE_PATH and write DATA_PATH.
#PUID=1000
#PGID=1000
#TZ=Europe/Paris
# ─── Ports ──────────────────────────────────────────────────────────
#PORT=3672
+163
View File
@@ -0,0 +1,163 @@
# File Browser
Web file manager for a single directory tree — browse, preview, upload,
download, share links. Handy for reaching a downloads folder from a phone
without exposing SMB or SSH.
This is **[FileBrowser Quantum](https://github.com/gtsteffaniak/filebrowser)**,
the maintained fork. See below for why not the original.
## Quick start
```bash
cp .env.example .env
$EDITOR .env # BROWSE_PATH is required
docker compose up -d
```
Open `http://<host>:3672` and log in as **`admin` / `admin`** — then change the
password immediately, see below.
## Ports
| Port | Proto | Purpose |
|------|-------|---------|
| 3672 | http | Web UI (container listens on 80) |
## Change the default password first
First start creates an admin account with a default password and says so:
```
[INFO ] Resetting admin user to default username and password.
```
Change it in the UI under user settings, or from the CLI. **The database is
locked while the server runs**, so the container has to be stopped first:
```bash
docker compose stop
docker compose run --rm filebrowser set -u "admin,your-new-password" -a
docker compose start
```
Running that against a live container fails with *"the database is locked,
please close all other instances"*, which is easy to misread as corruption.
## Why not `filebrowser/filebrowser`
The original project was wound down on **2026-09-01**. Its own binary announced
it on every start:
```
NOTICE: File Browser is being wound down.
NOTICE: The project is archived on 2026-09-01, after which there will be no
NOTICE: further releases and no security fixes.
```
At that point its advisory page listed around 30 published issues, including a
high-severity one where recursive copy, rename and delete ignored rules that
should have denied access to descendants. Those are now permanent.
Quantum is the actively developed fork. It keeps the same idea but has its own
configuration format — a YAML file rather than `FB_*` environment variables —
so it is not a drop-in swap of the image name.
## Why it looks like this
**The config is a committed file, not environment variables.** Quantum reads a
YAML config and exits `FATAL` if it can't find one. Without
`FILEBROWSER_CONFIG` it looks for `config.yaml` *inside the data directory*,
which means the file you must write by hand and the database it generates end
up in the same place. Pointing it at `/config/config.yaml` keeps the two
separate: [`init/config.yaml`](init/config.yaml) is version-controlled and
mounted read-only, `DATA_PATH` holds only generated state.
**`minLength: 5` in the config is deliberate.** Raise it and the first start
dies before serving anything:
```
[FATAL] store.Users.Save: password must be at least 8 characters long
```
That's the *default admin* being created — its password is shorter than the
limit you just set. Raise `minLength` only after setting a real password.
**No `PUID`/`PGID`.** The image runs as its own `filebrowser` user (uid/gid
1000) and reads neither those nor `UID`/`GID`. Ownership is set with Docker's
`user:` directive, the same as [audiobookshelf](../audiobookshelf/).
**One source, mounted at `/srv`.** `config.yaml` declares `sources: [/srv]` and
the compose file binds your directory there, so the path inside the container
never changes and the config stays generic.
## Gotchas
- **Anyone who logs in can delete anything they can see.** Mount `BROWSE_PATH`
with `:ro` if you only want to look and download.
- **Share links bypass login by design.** That's the feature, but it means a
leaked link is public access to that file.
- **The database is locked while the container runs** — user management needs
it stopped.
- **Back up `DATA_PATH`.** It holds users and share links; losing it means
recreating both.
- **A missing config file looks like a broken config file.** The error names
`Sources` as invalid rather than saying the file is absent.
- **Tags are `1.5.3-stable`, not `v1.5.3`.** The `v` prefix 404s, and `stable`
and `latest` are moving tags.
## Running it on OpenMediaVault
OMV's compose plugin deploys the compose file and the env file, nothing else.
Two things follow, and both cost me a round trip.
**Put `config.yaml` in `init/`, not the stack root.** The compose mounts
`./init/config.yaml`, so that exact path must exist as a *file* before the
first start. Docker creates a **directory** for a missing bind-mount source,
and filebrowser then reports a validation failure rather than a missing file:
```
could not validate config: Key: 'Settings.Server.Sources'
Error:Field validation for 'Sources' failed on the 'required' tag
```
That message sends you looking for a mistake in your config when the config
isn't being read at all. Check the host first:
```bash
stat -c '%F %n' init/config.yaml # must say "regular file"
```
If it says `directory`, `rmdir` it, put the real file there, and **recreate**
the container — a restart isn't enough, the mount is fixed at creation.
**Make `DATA_PATH` writable by `PUID:PGID`.** Docker creates it as root, but
the container runs as your `PUID:PGID` — which on OMV is often `1000:100`
(the `users` group), not `1000:1000`. Otherwise:
```
[FATAL] could not open database: open /data/database.db: permission denied
```
```bash
chown -R 1000:100 data
```
Also: OMV names the env file `filebrowser.env`, so manual `docker compose`
commands fail on `BROWSE_PATH` unless you pass `--env-file filebrowser.env`.
Use plain `docker exec` / `docker logs` for one-offs.
## Exposing it
- [Reverse proxy with Caddy](../docs/reverse-proxy.md) — the minimum.
- [Single sign-on with Authentik](../docs/authentik-sso.md) — worth it here.
Forward auth means a stranger has to get past Authentik before reaching a
login form that guards your filesystem.
- [Cloudflare Tunnel](../cloudflare-tunnel/) — mind the ~100 MB upload cap, and
don't route large media downloads through it.
## Links
- Upstream: <https://github.com/gtsteffaniak/filebrowser>
- Image: `ghcr.io/gtsteffaniak/filebrowser`
- The wound-down original: <https://github.com/filebrowser/filebrowser/security/advisories>
+32
View File
@@ -0,0 +1,32 @@
services:
filebrowser:
# FileBrowser Quantum -- the maintained fork. The original
# filebrowser/filebrowser was wound down on 2026-09-01 with ~30 unfixed
# security advisories; see the README before reaching for it again.
image: ghcr.io/gtsteffaniak/filebrowser:1.5.3-stable
container_name: filebrowser
restart: unless-stopped
# The image already runs as its own non-root `filebrowser` user, uid/gid
# 1000. It reads no PUID/PGID, so ownership is set the Docker way. Change
# this if the files it must read are owned by someone else.
user: "${PUID:-1000}:${PGID:-1000}"
environment:
- TZ=${TZ:-Etc/UTC}
# Without these it looks for config.yaml *inside* the data directory and
# exits FATAL when it is missing. Splitting them keeps the committed
# config separate from the database it generates.
- FILEBROWSER_CONFIG=/config/config.yaml
- FILEBROWSER_DATABASE=/data/database.db
volumes:
- ./init/config.yaml:/config/config.yaml:ro
# SQLite database: users, shares, the search index. Back this up.
- ${DATA_PATH:-./data}:/data
# The directory you actually want to browse. Add `:ro` to make this a
# viewer rather than a file manager.
- "${BROWSE_PATH:?set BROWSE_PATH to the directory you want to browse}:/srv"
ports:
- "${PORT:-3672}:80"
+26
View File
@@ -0,0 +1,26 @@
# FileBrowser Quantum configuration.
#
# Mounted read-only at /config/config.yaml; the container is pointed at it with
# FILEBROWSER_CONFIG. `./filebrowser -c` inside the image prints the full
# annotated default if you want to see every available option.
server:
port: 80
baseURL: "/"
logging:
- levels: "info|warning|error"
# What gets browsed. The compose file bind-mounts your directory here.
sources:
- path: "/srv"
auth:
methods:
password:
enabled: true
# Leave at 5. The first run creates a default admin whose password is
# shorter than 8 characters, and raising this makes that creation fail
# with a FATAL before the server ever starts. Raise it only after you
# have set a real password -- see the README.
minLength: 5
# No self-registration. Users are created by an admin.
signup: false