fix(filebrowser_quantum): write the v2 config format so 2.0.0 starts (#3110)

* fix(filebrowser_quantum): write the v2 config format so 2.0.0 starts

v2 rejects the string server.database, the 1.x server.port/listen/baseURL
keys and the FILEBROWSER_DATABASE variable, so both fresh installs and
upgrades died at startup. Write http.* and server.database.path, and point
migrateFrom at an existing 1.x BoltDB so upstream migrates it on first start.

Fixes #3109

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(filebrowser_quantum): reset 1.x configs to the v2 default on upgrade

Old installs carry a config copied from a 1.x image default, whose
userDefaults layout v2 rejects as unknown fields. Deleting keys one by one
cannot cover every 1.x variant, so back the file up and start from the v2
default, which the script then fills in as on a fresh install.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(filebrowser_quantum): clarify migrateFrom comment

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(filebrowser_quantum): follow the v2 migration guide and upstream healthcheck

Set migrateFrom only until the SQLite database exists, set
http.trustProxyHeaders for the nginx subpath, and check upstream's
${baseURL}health endpoint instead of an nginx-only stub.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(filebrowser_quantum): convert 1.x configs in place instead of resetting

Resetting to the v2 default dropped extra sources (breaking shares on them)
and auth/OIDC settings. Both 1.x and 2.0 reject unknown keys, so the keys a
1.5.x config can hold that 2.0 lacks are exactly the settings-struct diff:
move the server http keys under http and drop the removed ones.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(filebrowser_quantum): fix CHANGELOG entry

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(filebrowser_quantum): ask users to back up before the 2.0 upgrade

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(filebrowser_quantum): keep server.database siblings, sanitize direct XFF

Set only server.database.path (dropping migrateFrom) so user-set keys such
as activity survive, and replace X-Forwarded-For on the published 8071
listener now that FileBrowser trusts proxy headers for login rate limits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(filebrowser_quantum): drop panel_admin default flagged by the add-on linter

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Revert "fix(filebrowser_quantum): drop panel_admin default flagged by the add-on linter"

Keep panel_admin: true explicit, per maintainer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(filebrowser_quantum): simplify the healthcheck

Curl the app root: v2 answers 200, or 301 to the baseURL, which curl -f
accepts, so the baseURL no longer has to be read from the config.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Alexandre
2026-10-11 08:01:34 +02:00
committed by GitHub
parent 33b6392d02
commit 4199b7e292
7 changed files with 49 additions and 16 deletions

View File

@@ -1,4 +1,18 @@
## 2.0.0.1 (2026-10-11)
- ⚠️ **Back up before updating.** FileBrowser 2.0 changes the config format and the database. This add-on converts both automatically, but you should first create a Home Assistant backup of the add-on, or copy `/addon_configs/*filebrowser_quantum*/` (`config.yaml` and `database.db`). Your 1.x `database.db` is left untouched, but downgrading after the migration loses any changes made in 2.0.
- Fix startup on 2.0.0, for fresh installs and upgrades (#3109).
- The add-on now writes the v2 config format: `http.port`, `http.listen`, `http.baseURL` and `server.database.path`.
- The deprecated `FILEBROWSER_DATABASE` variable is dropped.
- Upgrade from 1.x: `/config/config.yaml` is converted in place. A backup is saved as `config.yaml.v1.bak`.
- Keys that 2.0 moved are now under `http:`.
- Keys that 2.0 removed are dropped: `userDefaults`, source `conditionals` and `indexingIntervalMinutes`, rule `fileNames` and `folderNames`, `trustedHeaders` and `exiftoolPath`.
- Everything else is kept, including extra sources and auth/OIDC settings.
- Users, shares and settings in `/config/database.db` are migrated to `/config/database.sqlite` on first start.
- `http.trustProxyHeaders` is set to `true`, because the add-on always runs behind nginx on a subpath.
- The container healthcheck now checks FileBrowser directly on port 8080 instead of an nginx stub.
- Direct access on port 8071 no longer passes on a client-supplied `X-Forwarded-For`, so the IP-based login lockout cannot be bypassed now that proxy headers are trusted. Ingress keeps the forwarded chain.
## 2.0.0 (2026-10-10)
- Update to latest version from gtsteffaniak/filebrowser (changelog : https://github.com/gtsteffaniak/filebrowser/releases)
- Local disks: `localdisks` can now mount a single folder of a disk with `disk/folder` (e.g. `sda1/public` or `NAS/public`, mounted at `/mnt/<disk>/<folder>`). Existing values are unchanged.

View File

@@ -116,4 +116,4 @@ LABEL \
#################
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
CMD curl -f http://localhost:3001/health || exit 1
CMD curl -fs -o /dev/null http://localhost:8080/ || exit 1

View File

@@ -74,7 +74,6 @@ devices:
environment:
FB_BASEURL: /filebrowser_quantum
FILEBROWSER_CONFIG: "/config/config.yaml"
FILEBROWSER_DATABASE: "/config/database.db"
PGID: "0"
PUID: "0"
image: ghcr.io/alexbelgium/filebrowser_quantum-{arch}
@@ -118,4 +117,4 @@ schema:
slug: filebrowser_quantum
udev: true
url: https://github.com/alexbelgium/hassio-addons
version: "2.0.0"
version: "2.0.0.1"

View File

@@ -79,6 +79,21 @@ mkdir -p /var/log/nginx && touch /var/log/nginx/error.log
mkdir -p /config /cache
# 1.x config (string server.database): both versions reject unknown keys, so
# move or drop the keys 2.0 removed and keep everything else (users and shares
# are in the database, imported below)
if [ -f "$FILEBROWSER_CONFIG" ] && [ "$(yq e '.server.database | tag' "$FILEBROWSER_CONFIG")" = "!!str" ]; then
bashio::log.warning "Converting FileBrowser 1.x config to 2.0, backup saved to ${FILEBROWSER_CONFIG}.v1.bak"
cp "$FILEBROWSER_CONFIG" "${FILEBROWSER_CONFIG}.v1.bak"
yq e -i '
.http *= (.server | pick(["socket", "tlsCert", "tlsKey", "externalUrl", "internalUrl", "disableWebDAV"])) |
del(.server.database, .server.port, .server.listen, .server.baseURL, .server.socket, .server.tlsCert, .server.tlsKey, .server.externalUrl, .server.internalUrl, .server.disableWebDAV) |
del(.http.trustedHeaders, .integrations.media.exiftoolPath, .userDefaults) |
del(.server.sources[].config.conditionals, .server.sources[].config.indexingIntervalMinutes) |
del(.server.sources[].config.rules[].fileNames, .server.sources[].config.rules[].folderNames)
' "$FILEBROWSER_CONFIG"
fi
# Copy default config if not existing
if [ ! -f "$FILEBROWSER_CONFIG" ]; then
cp /home/filebrowser/data/config.yaml "$FILEBROWSER_CONFIG"
@@ -88,9 +103,14 @@ bashio::log.info "Updating FileBrowser config..."
# --- Server (hardcoded values) ---
bashio::log.info "... set server"
yq e -i ".server.port = 8080" "$FILEBROWSER_CONFIG"
yq e -i ".server.listen = \"0.0.0.0\"" "$FILEBROWSER_CONFIG"
yq e -i ".server.database = \"/config/database.db\"" "$FILEBROWSER_CONFIG"
yq e -i ".http.port = 8080" "$FILEBROWSER_CONFIG"
yq e -i ".http.listen = \"0.0.0.0\"" "$FILEBROWSER_CONFIG"
yq e -i ".http.trustProxyHeaders = true" "$FILEBROWSER_CONFIG"
yq e -i ".server.database.path = \"/config/database.sqlite\" | del(.server.database.migrateFrom)" "$FILEBROWSER_CONFIG"
# Import the 1.x BoltDB until the SQLite database exists
if [ -s /config/database.db ] && [ ! -s /config/database.sqlite ]; then
yq e -i ".server.database.migrateFrom = \"/config/database.db\"" "$FILEBROWSER_CONFIG"
fi
yq e -i ".server.cacheDir = \"/cache\"" "$FILEBROWSER_CONFIG"
# --- Default user scope / source path ---
@@ -117,7 +137,7 @@ yq e -i ".server.sources[0].config.defaultUserScope = \"${DEFAULT_USER_SCOPE}\""
# --- Base URL (from env or config) ---
bashio::log.info "... set base URL to allow ingress"
BASE_URL=$(bashio::config 'base_url' "${FB_BASEURL:-/}")
yq e -i ".server.baseURL = \"${BASE_URL}\"" "$FILEBROWSER_CONFIG"
yq e -i ".http.baseURL = \"${BASE_URL}\"" "$FILEBROWSER_CONFIG"
# --- Auth method ---
AUTH_METHOD=$(bashio::config 'auth_method' 'password')

View File

@@ -10,7 +10,7 @@ proxy_set_header Accept-Encoding "";
proxy_set_header Connection $connection_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-For $fb_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-NginX-Proxy true;
proxy_set_header X-Real-IP $remote_addr;

View File

@@ -1,3 +1,11 @@
# FileBrowser trusts X-Forwarded-For (http.trustProxyHeaders) for login rate
# limits: keep the chain from the Supervisor ingress proxy, but replace
# whatever a client sends straight to the published port
map $server_port $fb_forwarded_for {
8072 $remote_addr;
default $proxy_add_x_forwarded_for;
}
server {
listen 0.0.0.0:8072 default_server;

View File

@@ -1,8 +0,0 @@
server {
listen 127.0.0.1:3001;
access_log off;
location /health {
return 200 'OK';
}
}