added filebrowser Quantum since the main Filebrowser is not going to continue
This commit is contained in:
@@ -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 |
|
||||
|
||||
@@ -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
|
||||
@@ -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>
|
||||
@@ -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"
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user