Browse Source
- Document the supported Compose and SQLite deployment boundaries - Explain initial installation, socket permissions, and the separate image publishing process - Describe immutable image overrides, backup retention, and operator-controlled recovery - Link the updater guide from the container documentation and list local verification commandspull/7743/head
2 changed files with 144 additions and 0 deletions
@ -0,0 +1,141 @@ |
|||
# Admin Docker updates |
|||
|
|||
Diagnostics reuses the yellow **Update** badge beside **Server Installed** as a |
|||
button. While the host downloads the configured image, backs up the vault, and |
|||
replaces the container, it shows **Updating…**. |
|||
After the new container is healthy, the page reloads. Refreshing the browser does |
|||
not cancel the update. An unchanged image does not restart the service. |
|||
|
|||
The server operator must first deploy an image containing admin update support. |
|||
Compatible images carry the `org.vaultwarden.admin-updates=1` label. Older images |
|||
without this feature are rejected so an update cannot remove the admin endpoint. |
|||
|
|||
## Supported deployment |
|||
|
|||
- Linux host with Python 3.10+, Docker, and Docker Compose v2+. |
|||
- One existing Compose service, with its dedicated data directory bind-mounted at |
|||
`/data`, a healthy Docker health check, and SQLite/all persistent data under |
|||
`/data`. Named data volumes, external databases/storage, symlinks in data, and |
|||
additional writable mounts are deliberately rejected before the service stops. |
|||
- Custom environment files and file-based storage configuration are not supported. |
|||
`DATA_FOLDER` must be `/data` and `CONFIG_FILE` must use `/data/config.json`. |
|||
- The existing Compose files remain the source of truth for ports, environment, |
|||
mounts, networks, and restart policy. Do not modify them or redeploy the same |
|||
service while an update is active. |
|||
Unapplied Compose configuration changes are rejected before an update starts. |
|||
- Admin authentication is required. `DISABLE_ADMIN_TOKEN=true` disables updates. |
|||
|
|||
The updater runs on the Docker host and survives Vaultwarden container replacement. |
|||
Vaultwarden receives only the updater's Unix socket; it never receives the Docker |
|||
socket. The browser cannot choose images, commands, or target services. Protect the |
|||
updater configuration and socket as administrative interfaces. |
|||
|
|||
## One-time installation |
|||
|
|||
Adapt every example path, project name, and service name to the **existing** stack. |
|||
Do not replace the existing Compose file with a new stack. The example registry |
|||
name is a placeholder; replace it with the repository you publish or trust. |
|||
|
|||
1. Build and publish a compatible image to your registry. For an amd64 server, for example: |
|||
|
|||
```sh |
|||
docker buildx build --platform linux/amd64 -f docker/Dockerfile.debian \ |
|||
-t registry.example.com/vaultwarden:latest --push . |
|||
``` |
|||
|
|||
Use the server's actual architecture. Publish a versioned tag as well if you need |
|||
release history. Only move `latest` to a reviewed, tested image. Image publishing |
|||
is managed separately; the updater only deploys the configured image channel. |
|||
|
|||
2. Install `updater.py` at `/opt/vaultwarden-updater/updater.py`, copy |
|||
`config.example.json` to `/etc/vaultwarden-updater.json`, and fill in the actual |
|||
Compose files (in their existing order), project, service, data path, and image. |
|||
Use absolute paths. Keep `/var/lib/vaultwarden-updater` outside the data directory. |
|||
Keep the config and script root-owned and not writable by the application user. |
|||
Log in to a private registry on the host as the updater's OS user, if necessary. |
|||
|
|||
3. Install `vaultwarden-updater.service` in `/etc/systemd/system/`, then run: |
|||
|
|||
```sh |
|||
sudo systemctl daemon-reload |
|||
sudo systemctl enable --now vaultwarden-updater |
|||
``` |
|||
|
|||
4. Add only these settings to the existing Vaultwarden service, alongside its |
|||
existing configuration, and deploy the first compatible image through your existing |
|||
deployment procedure: |
|||
|
|||
```yaml |
|||
environment: |
|||
UPDATER_SOCKET: /run/vaultwarden-updater/updater.sock |
|||
volumes: |
|||
- /run/vaultwarden-updater:/run/vaultwarden-updater:ro |
|||
``` |
|||
|
|||
Mount the **directory**, so restarting the updater can replace its socket. |
|||
The service defaults to root:root socket permissions `0660`, matching the |
|||
default root Vaultwarden container. For a non-root container, set the unit's |
|||
`Group` and the container's supplemental numeric group to the same dedicated |
|||
group. The directory requires group traversal permission. |
|||
|
|||
5. Open **Admin → Diagnostics → Update**. Do the first update on a test deployment |
|||
and verify vault login, sync, and attachments before enabling production use. |
|||
|
|||
## Deployment and recovery |
|||
|
|||
The updater downloads the configured tag while the old service remains available. |
|||
It then pins the downloaded **image ID**, stops just the selected service, archives |
|||
all of `/data`, and recreates that service with `--no-deps --no-build --pull never`. |
|||
Backups are stored at `state_directory/backups/<deployment-id>/data.tar`, along with |
|||
the previous and target image IDs in `deployment.json`. Protect these archives as |
|||
vault data and manage their retention/free disk space on the host. |
|||
|
|||
The selected image is persisted in `state_directory/image.override.json`. Include |
|||
this file **last** in future manual Compose commands; otherwise a manual deployment |
|||
could restore the old image from the base Compose file. For example: |
|||
|
|||
```sh |
|||
docker compose --project-directory /opt/vaultwarden --project-name vaultwarden \ |
|||
-f /opt/vaultwarden/compose.yml \ |
|||
-f /var/lib/vaultwarden-updater/image.override.json ps |
|||
``` |
|||
|
|||
Failures before stopping the service leave it running. Failures after a stop was |
|||
requested, and updater interruptions, require host inspection and block subsequent |
|||
updates. `status.json` records the last completed stage. Full Docker output and |
|||
container environment values are never sent to the browser. |
|||
|
|||
Do not simply run an old image against a database migrated by a new image. To |
|||
recover, stop the updater, inspect the container and the saved deployment metadata, |
|||
and repair the deployment. If restoring the previous version is necessary, stop |
|||
the vault, preserve its current data separately, restore the selected `data.tar` |
|||
backup with its ownership and permissions, set `image.override.json` to the saved |
|||
previous image ID, and start the service. Restoration may discard writes accepted |
|||
after the backup, so it is an operator decision, never an automatic action. |
|||
|
|||
After checking the running service, clear the recovery lock while the updater |
|||
service is stopped, then start the updater again: |
|||
|
|||
```sh |
|||
sudo systemctl stop vaultwarden-updater |
|||
sudo python3 /opt/vaultwarden-updater/updater.py /etc/vaultwarden-updater.json \ |
|||
--acknowledge-recovery |
|||
sudo systemctl start vaultwarden-updater |
|||
``` |
|||
|
|||
This command verifies the container's health and data configuration before clearing |
|||
the lock. Keep previous images until the new release is stable; image pruning can |
|||
otherwise remove the saved rollback target. |
|||
|
|||
## Local verification |
|||
|
|||
```sh |
|||
python3 -m unittest discover -s docker/updater -v |
|||
cargo check --locked --features sqlite |
|||
node --check src/static/scripts/admin_updates.js |
|||
``` |
|||
|
|||
The Python flow tests use a controlled Docker adapter and real temporary backup |
|||
archives. They cover unchanged images, rejected images/storage, download/recreation/ |
|||
health failures, duplicate requests, and interrupted updater recovery. They do not |
|||
replace a test of an actual Docker deployment. |
|||
Loading…
Reference in new issue