Run with Docker
In progress
The image runs the sync server and the web vault on one port: /v1/… is the API (including the /v1/ws WebSocket), everything else is the web vault. Put it behind a reverse proxy that terminates TLS; the apps refuse servers without HTTPS.
Build the image
Section titled “Build the image”From the repository root:
docker build -f apps/server/Dockerfile -t octapass-server .The build compiles the crypto core to WebAssembly, builds the web vault and the server, and copies them into a distroless image that runs as a non-root user. Base images are pinned by digest.
Docker Compose
Section titled “Docker Compose”A complete example lives in deploy/octap.app: copy the folder, change the domain and the invited email, and run docker compose up -d --build. The essentials:
services: octapass: build: { context: ../.., dockerfile: apps/server/Dockerfile } restart: unless-stopped ports: ["127.0.0.1:8380:8080"] # only your proxy should reach it environment: OCTAPASS_PUBLIC_URL: https://vault.example.com OCTAPASS_WEB_ORIGINS: https://vault.example.com OCTAPASS_SIGNUPS: invite OCTAPASS_TRUST_PROXY: "true" OCTAPASS_SMTP_URL: ${OCTAPASS_SMTP_URL:-} OCTAPASS_EMAIL_TO_LOG: ${OCTAPASS_EMAIL_TO_LOG:-false} OCTAPASS_BACKUP_DIR: /backups volumes: - octapass-data:/data - octapass-backups:/backups read_only: true tmpfs: [/tmp] cap_drop: [ALL] security_opt: ["no-new-privileges:true"]
volumes: octapass-data: octapass-backups:Then forward https://vault.example.com to 127.0.0.1:8380 in your proxy (Caddy, Traefik, nginx or a Cloudflare Tunnel), with WebSockets allowed.
- Who can sign up. With
OCTAPASS_SIGNUPS=invite, only the emails inOCTAPASS_INVITES(comma-separated) can create an account. They’re invited at every start until their account exists;octapass-server admin inviteadds more without a restart. - The verification code. Sign-up needs a code sent by email. Set
OCTAPASS_SMTP_URL, or setOCTAPASS_EMAIL_TO_LOG=trueand read the code withdocker compose logs octapass | grep "verification code". The code is never returned to the browser outside dev mode. - The web vault always uses the server it’s served from. Its pages get a content security policy that allows only that origin plus
wasm-unsafe-eval(the crypto core), and cross-origin isolation headers. API responses keepdefault-src 'none'. - PostgreSQL instead of SQLite: add a
postgres:17service and setOCTAPASS_DATABASE_URL=postgres://octapass:<password>@db:5432/octapass. Scheduled backups are SQLite only; usepg_dumpthere.
Health checks
Section titled “Health checks”GET /healthz: the process is aliveGET /readyz: the database and storage are reachableoctapass-server healthcheckexits 0 when/healthzanswers. The image uses it as itsHEALTHCHECK, since it has no shell or curl.
Admin commands
Section titled “Admin commands”Run them in the container: docker compose exec octapass octapass-server admin …. See configuration.
Updating
Section titled “Updating”git pull && docker compose up -d --buildDatabase migrations run automatically at startup, behind a lock, so only one instance migrates at a time. Back up first: see backups.