fix: keep existing compose volumes and add the two that were missing

This commit is contained in:
Linus Rath
2026-10-31 18:12:00 +01:00
parent fa9aad95b4
commit 5fe7d1a65a
2 changed files with 31 additions and 28 deletions
+24 -25
View File
@@ -9,31 +9,25 @@ services:
env_file:
- .env.local
volumes:
# Everything Bulwark keeps, in one volume:
# settings/ encrypted user settings (SETTINGS_DATA_DIR)
# admin/ config.json, policy.json, admin.json, plugins, themes,
# branding uploads (ADMIN_CONFIG_DIR)
# admin-state/ login timestamps, audit.log, setup token (ADMIN_STATE_DIR)
# plugin-secrets/ users' plugin credentials (PLUGIN_SECRETS_DIR)
# telemetry/ instance id and usage stats consent (TELEMETRY_DATA_DIR)
# version-check/ result of the last update check
# These six volumes together are everything Bulwark keeps under /app/data.
# A fresh install can use one `bulwark-data:/app/data` volume instead.
#
# To lock the admin config after the setup wizard, give admin/ its own
# mount with `:ro` and set ADMIN_CONFIG_READONLY=true.
#
# Upgrading from the four volumes this file used to have
# (bulwark-settings, bulwark-admin, bulwark-admin-state,
# bulwark-telemetry)? Copy them into the new one before the first start,
# or the wizard runs again. With the project name from `docker volume ls`:
# docker compose down && docker compose create
# docker run --rm -v <project>_bulwark-settings:/old/settings \
# -v <project>_bulwark-admin:/old/admin \
# -v <project>_bulwark-admin-state:/old/admin-state \
# -v <project>_bulwark-telemetry:/old/telemetry \
# -v <project>_bulwark-data:/new alpine \
# sh -c 'cp -a /old/. /new/ && chown -R 1001:1001 /new'
# docker compose up -d
- bulwark-data:/app/data
# Encrypted user settings (SETTINGS_DATA_DIR).
- bulwark-settings:/app/data/settings
# Admin configuration: config.json, policy.json, admin.json (passwordHash),
# plugins, themes, branding uploads (ADMIN_CONFIG_DIR). Can be mounted
# read-only after running the setup wizard - append `:ro` to lock it.
- bulwark-admin:/app/data/admin
# Admin runtime state: admin-state.json (login timestamps), audit.log,
# setup token (ADMIN_STATE_DIR). Always read-write.
- bulwark-admin-state:/app/data/admin-state
# Anonymous telemetry: instance id, consent state, login HMACs (TELEMETRY_DATA_DIR).
# Persisting this preserves the admin's consent choice and stable instance id across upgrades.
- bulwark-telemetry:/app/data/telemetry
# Users' plugin credentials, encrypted (PLUGIN_SECRETS_DIR).
- bulwark-plugin-secrets:/app/data/plugin-secrets
# Result of the last update check (VERSION_CHECK_DATA_DIR).
- bulwark-version-check:/app/data/version-check
healthcheck:
test:
[
@@ -51,4 +45,9 @@ services:
restart: unless-stopped
volumes:
bulwark-data:
bulwark-settings:
bulwark-admin:
bulwark-admin-state:
bulwark-telemetry:
bulwark-plugin-secrets:
bulwark-version-check:
+7 -3
View File
@@ -45,10 +45,14 @@ describe('docker data dirs', () => {
for (const dir of defaultDataDirs()) expect(created).toContain(`/app/data/${dir}`);
});
it('keeps all of /app/data in one volume in docker-compose.yml', () => {
it('persists every data dir in docker-compose.yml, by its own volume or one on /app/data', () => {
const compose = readFileSync(path.join(ROOT, 'docker-compose.yml'), 'utf8');
const mounts = [...compose.matchAll(/^\s*-\s*([\w.-]+):(\/app\/data[^\s:]*)/gm)].map((m) => m[2]);
expect(mounts).toEqual(['/app/data']);
const mounts = [...compose.matchAll(/^\s*-\s*[\w.-]+:(\/app\/data[^\s:]*)/gm)].map((m) => m[1].replace(/\/+$/, ''));
expect(mounts.length).toBeGreaterThan(0);
const unpersisted = defaultDataDirs().filter(
(dir) => !mounts.includes('/app/data') && !mounts.includes(`/app/data/${dir}`),
);
expect(unpersisted).toEqual([]);
});
});