All apps · 0 apps
DiscVault
Docker app from helmerznl's Repository
Overview
Readme
View on GitHubDiscVault Launcher
DiscVault Launcher is a small deployment manager for DiscVault Docker channels.
It can run the legacy single-container app for latest/legacy, or the
PostgreSQL-backed DiscVault 26 stack for v26 channels. It is intentionally
separate from the DiscVault application image and from the standalone Docker
Compose stack.
The split is deliberate:
helmerznl/discvaultis the DiscVault app image.helmerznl/discvault-launcheris the optional management/proxy image.stack/docker-compose.ymlcan be used directly without the launcher.unraid/discvault.xmllets Unraid Community Apps install one container that manages the full DiscVault stack behind the scenes.
Architecture
Unraid Community Apps
-> DiscVault Launcher container
-> Docker socket
-> legacy latest: discvault
-> v26 stack: postgres + next-api + next-worker
-> Nginx proxy on the Unraid WebUI port
The launcher keeps running as the public web endpoint and proxies requests to
the managed DiscVault container. Legacy mode proxies to the all-in-one
container on port 80; v26 stack mode proxies to next-api:5000. The managed
containers do not bind their own host ports in launcher mode, so an existing
Unraid WebUI port such as 6080 stays stable.
Standalone Docker Compose
Use this when you do not need the launcher:
cd stack
cp .env.example .env
# Edit POSTGRES_PASSWORD, JWT_SECRET, RP_ID and RP_ORIGINS.
docker compose up -d
Open http://localhost:6180 by default.
For an existing DiscVault beta data directory, set:
DISCVAULT_DATA_DIR=/mnt/user/appdata/discvault
DiscVault Next reads /data/discvault.db and existing media folders through the
migration UI.
Launcher Docker Run
Use this when you want the launcher to create and update the stack:
docker run -d \
--name discvault-launcher \
-p 6080:80 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /mnt/user/appdata/discvault-launcher:/config \
-e DISCVAULT_DATA_DIR_HOST=/mnt/user/appdata/discvault \
-e DISCVAULT_POSTGRES_DATA_DIR_HOST=/mnt/user/appdata/discvault-postgres \
-e RP_ID=localhost \
-e RP_ORIGINS=http://localhost:6080 \
ghcr.io/helmerznl/discvault-launcher:v26-beta
The first start writes generated secrets to /config/stack.env. Keep that file
stable; it contains the PostgreSQL password and JWT secret used by the stack.
In legacy latest/legacy mode, the same generated JWT_SECRET, RP_ID,
RP_ORIGIN, and RP_ORIGINS values are passed through to the actual
discvault:latest app container so existing passkeys keep working after a
launcher restart.
Unraid Community Apps
Publish unraid/discvault.xml to the Unraid template repository. The template
name is DiscVault on purpose, so it can become the Community Apps path for
existing DiscVault beta users.
Recommended appdata paths:
/mnt/user/appdata/discvault existing beta data and SQLite database
/mnt/user/appdata/discvault-postgres PostgreSQL data
/mnt/user/appdata/discvault-launcher launcher config and generated secrets
After installation, open the WebUI and follow /api/next/migration when the app
reports that legacy migration is required.
Update Model
Unraid can only check the container image that Community Apps installed. It
cannot see updates for the child Compose containers that the launcher manages.
For that reason the launcher repository contains Stack Image Update Watch.
That workflow checks the DiscVault channel digest and republishes the launcher
tag when the stack image changes.
Stack Image Update Watchsees a newhelmerznl/discvaultdigest and republishes the matching launcher channel.- Unraid detects the launcher image update.
- Community Apps or the Auto Update plugin updates the launcher container.
- The launcher starts and pulls only the resolved DiscVault app image.
- For
latest/legacy, the launcher starts only the legacy DiscVault all-in-one container. - For
dev,v26-beta,v26, and immutablev26.x.ytags, the launcher runs the PostgreSQL-backed v26 stack. - In v26 mode,
next-apiapplies PostgreSQL migrations before serving traffic. - The existing beta data stays in place and is imported by the migration UI.
The launcher resolves image rollouts in this order:
DISCVAULT_NEXT_IMAGE(primary override for v26 stack deployments).DISCVAULT_IMAGE(fallback, includingautobehavior).- Launcher-packaged default image for the current channel.
If no override is set, the safe default is ghcr.io/helmerznl/discvault:latest.
Manual GitHub Actions launcher publishes should therefore default to baking in
discvault:latest unless a different DiscVault image is intentionally selected.
Supported shorthand values are:
auto->ghcr.io/helmerznl/discvault:latestprod->ghcr.io/helmerznl/discvault:latestlatest->ghcr.io/helmerznl/discvault:latestv26->ghcr.io/helmerznl/discvault:latestbeta->ghcr.io/helmerznl/discvault:betav26-beta->ghcr.io/helmerznl/discvault:v26-beta
For mutable tags such as v26-beta, the launcher resolves the current remote
digest and treats that digest as the deployment source-of-truth. For digest
pinned refs (repo@sha256:... or repo:tag@sha256:...), it uses the pinned
digest exactly.
Rollout decisions compare desired digest versus local digest and running
container digest/image-id (next-api, next-worker, next-mcp). Any mismatch
forces pull + recreate for the relevant services. packaged and
/config/last-stack-digest values are retained for metadata/logging only and
never block newer remote digests.
After recreate, the launcher verifies runtime digest, image label
org.opencontainers.image.revision, and (by default) /api/next/health.sha.
Any mismatch exits with a non-zero error instead of reporting a vague
"up-to-date" state.
For troubleshooting or aggressive test deployments, set
DISCVAULT_ALWAYS_RECREATE_STACK=true. That forces --force-recreate on every
launcher start after pulling.
Temporary workaround / explicit pinning
Until your target image channel has the fix live, you can force a deterministic
build by pinning a digest in /config/stack.env:
DISCVAULT_NEXT_IMAGE=ghcr.io/helmerznl/discvault:v26-beta@sha256:<digest>
Then recreate by restarting the launcher container.
Launcher boot-session logs
Each launcher startup writes a timestamped boot-session logfile to:
/config/logs/launcher-boot-<UTC timestamp>-<pid>.log
The same lines are also emitted to stdout for easy Unraid log viewing. Logs
always include timestamps and rollout digest/sha decisions. Environment
snapshots are logged too, but secret values (passwords/secrets/tokens/keys) are
always redacted. Default retention is the latest 50 boot sessions
(DISCVAULT_BOOT_LOG_RETENTION=50).
Manual testing with the current Next channel can republish the beta launcher
when the development stack image changes. Use this while the Unraid template is
still installed as discvault-launcher:v26-beta but DISCVAULT_NEXT_IMAGE
points to ghcr.io/helmerznl/discvault:dev:
gh workflow run "Stack Image Update Watch" \
-f stack_image=ghcr.io/helmerznl/discvault:dev \
-f launcher_tag=v26-beta \
-f force=true
For predictable development updates, use matching development tags in Unraid:
Repository: ghcr.io/helmerznl/discvault-launcher:dev
DISCVAULT_NEXT_IMAGE: auto
DISCVAULT_IMAGE: auto
The scheduled watcher publishes discvault-launcher:latest for
discvault:latest, discvault-launcher:dev for discvault:dev,
discvault-launcher:v26-beta for discvault:v26-beta, and
discvault-launcher:v26 for discvault:v26. Immutable release tags such as
v26.0.0 can publish matching launcher and app images. With
DISCVAULT_NEXT_IMAGE=auto and DISCVAULT_IMAGE=auto, the launcher starts the
DiscVault app image baked into its own channel. Set DISCVAULT_NEXT_IMAGE to a
full image reference only when you want to override that channel intentionally.
ghcr.io/helmerznl/discvault:latest is the legacy single-container app. When
the launcher resolves to discvault:latest or discvault:legacy, it starts
only that one container and does not pull or start PostgreSQL, next-api, or
next-worker.
For legacy passkeys, configure these values on the launcher and keep them stable:
RP_ID=app.discvault.eu
RP_ORIGIN=https://app.discvault.eu
RP_ORIGINS=https://app.discvault.eu
JWT_SECRET=<stable random secret, or leave empty once so the launcher persists one in /config/stack.env>
RP_ID must be the public domain only. RP_ORIGIN and RP_ORIGINS must match
the exact browser origin used for registration and login.
Channel mapping:
discvault-launcher:latest -> discvault:latest (legacy single container)
discvault-launcher:legacy -> discvault:latest (legacy single container)
discvault-launcher:dev -> discvault:dev
discvault-launcher:v26-beta -> discvault:v26-beta
discvault-launcher:v26 -> discvault:v26
discvault-launcher:v26.0.0 -> discvault:v26.0.0
Manual launcher builds can publish any matching channel:
gh workflow run "Build & Publish DiscVault Launcher" \
-f stack_image=ghcr.io/helmerznl/discvault:v26.0.0 \
-f launcher_tag=v26.0.0
Manual Stack Removal
Removing the launcher container does not delete the managed stack. That protects PostgreSQL data from accidental app removal.
To stop the managed stack manually:
docker compose --env-file /mnt/user/appdata/discvault-launcher/stack.env \
-f /mnt/user/appdata/discvault-launcher/docker-compose.yml \
-p discvault_stack down
Install DiscVault on Unraid in a few clicks.
Find DiscVault in Community Apps on your Unraid server, review the template, and click Install. Unraid handles the Docker app or plugin setup from the published template.
Categories
Related apps
Explore more like this
Explore allDetails
ghcr.io/helmerznl/discvault-launcher:v26-betaRuntime arguments
- Web UI
http://[IP]:[PORT:80]- Network
bridge- Shell
sh- Privileged
- false
Template configuration
DiscVault web interface. The launcher proxies this port to the DiscVault Next API/UI.
- Target
- 80
- Default
- 6080
- Value
- 6080
Existing DiscVault beta appdata path. Kept for compatibility with the current beta container template.
- Target
- /data
- Default
- /mnt/user/appdata/discvault
- Value
- /mnt/user/appdata/discvault
Launcher state, generated Compose file, and generated secrets.
- Target
- /config
- Default
- /mnt/user/appdata/discvault-launcher
- Value
- /mnt/user/appdata/discvault-launcher
Required so the launcher can create and update the DiscVault stack containers.
- Target
- /var/run/docker.sock
- Default
- /var/run/docker.sock
- Value
- /var/run/docker.sock
Host path of the existing DiscVault beta appdata. Must match Data Path so the managed stack can mount the same data from the Docker host.
- Target
- DISCVAULT_DATA_DIR_HOST
- Default
- /mnt/user/appdata/discvault
- Value
- /mnt/user/appdata/discvault
Host path where the launcher stores PostgreSQL data for DiscVault Next.
- Target
- DISCVAULT_POSTGRES_DATA_DIR_HOST
- Default
- /mnt/user/appdata/discvault-postgres
- Value
- /mnt/user/appdata/discvault-postgres
Primary DiscVault image override for v26 stack rollouts. Accepts shorthand values auto/prod/latest/v26 - discvault:latest, beta - discvault:beta, v26-beta - discvault:v26-beta, or a full image reference. Supports digest pinning, for example ghcr.io/helmerznl/discvault:v26-beta@sha256:digest.
- Target
- DISCVAULT_NEXT_IMAGE
Fallback DiscVault image when DISCVAULT_NEXT_IMAGE is empty. Shorthand values auto/prod/latest/v26 map to discvault:latest, beta maps to discvault:beta, and v26-beta maps to discvault:v26-beta.
- Target
- DISCVAULT_IMAGE
- Default
- auto
- Value
- auto
Stable Docker Compose project name for the managed stack.
- Target
- DISCVAULT_PROJECT_NAME
- Default
- discvault_stack
- Value
- discvault_stack
Shared Docker network for launcher, API, worker, and PostgreSQL.
- Target
- DISCVAULT_NETWORK
- Default
- discvault-stack
- Value
- discvault-stack
When true, the launcher recreates the managed DiscVault stack on every start after pulling images. Useful for development and troubleshooting.
- Target
- DISCVAULT_ALWAYS_RECREATE_STACK
- Default
- false
- Value
- false
When true, the launcher validates /api/next/health sha against the deployed image revision and fails startup on mismatch.
- Target
- DISCVAULT_CHECK_HEALTH_SHA
- Default
- true
- Value
- true
How many launcher boot-session log files to keep in /config/logs.
- Target
- DISCVAULT_BOOT_LOG_RETENTION
- Default
- 50
- Value
- 50
Maximum wait time for the launcher rollout lock before startup fails to avoid parallel update races.
- Target
- DISCVAULT_ROLLOUT_LOCK_TIMEOUT
- Default
- 300
- Value
- 300
Container and stack timezone.
- Target
- TZ
- Default
- Europe/Amsterdam
- Value
- Europe/Amsterdam
WebAuthn relying party ID (domain only, no protocol/port).
- Default
- localhost
- Value
- localhost
Comma-separated WebAuthn allowed origins. Use your real DiscVault URL when using a reverse proxy.
- Default
- http://localhost:6080
- Value
- http://localhost:6080
Optional stable PostgreSQL password. Leave empty and the launcher generates one in /config/stack.env on first start.
- Target
- POSTGRES_PASSWORD
Optional stable JWT signing secret. Leave empty and the launcher generates one in /config/stack.env on first start.
- Target
- JWT_SECRET