GREEN PACKAGE SKILL · ONCE · VAULTWARDEN · LITESTREAM

vaultwarden

Deploy Vaultwarden on a Basecamp ONCE server with Green and continuous Litestream replication to Cloudflare R2.

  • Vaultwarden 1.35.4
  • Litestream 0.5.16
  • Automatic restore
  • Closed signup

#Introduction

This Package Skill provisions one Basecamp ONCE server and deploys a pinned Vaultwarden image. It reuses ONCE for compute, DNS, SMTP, HTTPS, host convergence, and optional GitHub deployment credentials while adding Vaultwarden-specific validation and application configuration. The official public image requires no repository access.

Safe first stepsbuild renders local files and create --dry-run walks the workflow without contacting providers. Review both before approving a real operation.

#Quick start

npx skills add getcolors/vaultwarden
cp .agents/skills/package-vaultwarden-green/green ./green
./green build
./green create --dry-run
# after approval:
./green create

#Runtime architecture

HTTPS request ─ ONCE proxy ─ Vaultwarden ─ /storage/db.sqlite3
                                      │
                                      └─ Litestream ─ Cloudflare R2

entrypoint ─ restore if absent ─ Hivemind ─ services + weekly restore check

The public image ghcr.io/getcolors/vaultwarden:1.0.0 pins Vaultwarden 1.35.4, Litestream 0.5.16, and Hivemind 1.1.0. Startup restores SQLite before Vaultwarden when the local database is absent. The ONCE /up proxy exposes the health contract expected by the platform.

#Desired state

AreaImportant choices
ProvidersCompute, DNS, SMTP, and local, S3, or R2 state backend
ApplicationHostname, pinned image, initial owner email, and optional operator-owned repository
AccessPublic signup disabled and steady-state admin endpoint disabled
ReplicationR2 bucket, endpoint, prefix, retention, and snapshot interval
VerificationSystemd calendar for an isolated replica restore check
SafetyUnique profile and compute-prevent-destroy: true

See the configuration reference for all keys, constraints, and credential mappings.

#Deployment lifecycle

The first create provisions the ONCE server, publishes DNS, configures SMTP and HTTPS, deploys the application, and sends an invitation to the configured owner. A temporary admin endpoint is available only over loopback during bootstrap and is removed before the deployment reaches steady state.

Invitation is the bootstrap boundaryPublic registration remains disabled. Confirm the owner email and SMTP settings before the first real create.

#Backup and recovery

Litestream continuously replicates /storage/db.sqlite3 to Cloudflare R2. A fresh container restores the newest replica automatically when its local database is absent. Every Sunday at 03:00 UTC by default, the image restores into a separate temporary file and runs SQLite integrity checking without replacing live data.

litestream restore -config /etc/vaultwarden/litestream.yml \
  -o /tmp/vaultwarden-restore.db /storage/db.sqlite3
sqlite3 /tmp/vaultwarden-restore.db 'pragma integrity_check;'
Never test over the live databaseRestore to a separate path. Preserve the R2 replica when deleting compute unless its removal is separately authorized.

#Command reference

CommandEffect
./green buildValidate desired state and render all stages
./green create --dry-runWalk the deployment graph without side effects
./green createProvision, converge, deploy, and verify
./green deleteGuarded destruction of deployment infrastructure

#Credentials and safety

  • Store credentials only in gitignored .envrc.private as COLORS_PAR_* variables.
  • Never export COLORS_PAR_PROFILE; the profile selects remote state.
  • Never edit or commit generated .colors/ output.
  • Keep compute-prevent-destroy: true in committed desired state.
  • Omit vaultwarden-repo for the official public image; never publish server access into a repository you do not control.
  • A real create or delete requires explicit authorization.

#Troubleshooting

The service does not start after replacing the container

Check R2 credentials and endpoint reachability, then inspect Litestream restore output before changing the local database.

The initial invitation does not arrive

Confirm the owner email and SMTP provider settings. Public signup remains intentionally unavailable.

The admin endpoint is unavailable

That is expected after convergence. It exists only on loopback during first-invitation bootstrap and is absent in steady state.