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 |
|
| [audiobookshelf](audiobookshelf/) | 13378 | Audiobooks and podcasts, with per-user progress sync |
|
||||||
| [cloudflare-tunnel](cloudflare-tunnel/) | — | Outbound connector. Exposes other services without opening a port |
|
| [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 |
|
| [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 |
|
| [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 |
|
| [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 |
|
| [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