Vaultwarden with Docker + HTTPS (Caddy)
Doc-based, not yet hands-on tested. This guide is written from the official documentation and has not yet been tested hands-on by us. Check the current official docs before running anything.
Versions/date: Vaultwarden 1.37.4 (latest GitHub release, published 2026-10-06 08:40 JST — https://github.com/dani-garcia/vaultwarden/releases/tag/1.37.4); Caddy v2.11.7 (latest GitHub release, published 2026-10-03 14:58 JST — https://github.com/caddyserver/caddy/releases/tag/v2.11.7). Docker Hub has the tags
vaultwarden/server:1.37.4andcaddy:2.11.7. Last checked: 2026-10-24.Transparency note (HomelabWise): This guide is based on official documentation only and was not hands-on tested by us. Check the linked docs before you run anything.
Vaultwarden is "an alternative server implementation of the Bitwarden Client API, written in Rust and compatible with official Bitwarden clients". Its README states: "This project is not associated with Bitwarden or Bitwarden, Inc." (README)
Why HTTPS is required
The wiki says HTTPS "is pretty much required nowadays". The Bitwarden web vault uses Web Crypto APIs, and most browsers only allow those over HTTPS. The recommended approach is a reverse proxy. Vaultwarden's built-in Rocket TLS is "not recommended" (Enabling HTTPS). If you have no preference, the wiki suggests trying Caddy first, because it gets Let's Encrypt certificates automatically.
Prerequisites (per the wiki)
- Docker with Compose (install)
- A domain (
<YOUR_DOMAIN>, e.g.vaultwarden.example.com) pointing at your server - A server that's publicly reachable on ports 80 and 443, for the ACME HTTP-01 challenge
This page contains affiliate placeholders. See our affiliate disclosure.
[AFFILIATE: DigitalOcean or Hostinger — VPS with public IP]
compose.yaml (official "Caddy with HTTP challenge" example)
From Using Docker Compose. We changed only the image tags (to pinned versions); the wiki uses vaultwarden/server:latest and caddy:2:
services:
vaultwarden:
image: vaultwarden/server:1.37.4
container_name: vaultwarden
restart: always
environment:
DOMAIN: "https://<YOUR_DOMAIN>"
SIGNUPS_ALLOWED: "true" # set to "false" once your account exists
volumes:
- ./vw-data:/data
caddy:
image: caddy:2.11.7
container_name: caddy
restart: always
ports:
- 80:80
- 443:443
- 443:443/udp
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- ./caddy-config:/config
- ./caddy-data:/data
environment:
DOMAIN: "https://<YOUR_DOMAIN>"
EMAIL: "<YOUR_EMAIL>" # used for Let's Encrypt
LOG_FILE: "/data/access.log"Caddyfile (official; the wiki says it doesn't need editing)
{$DOMAIN} {
log {
level INFO
output file {$LOG_FILE} {
roll_size 10MB
roll_keep 10
}
}
tls {$EMAIL}
encode zstd gzip
reverse_proxy vaultwarden:80 {
header_up X-Real-IP {remote_host}
}
}The wiki notes that encode zstd gzip "may have compatibility issues with some browsers (e.g., attachment downloading on Firefox)". If you run into that, try disabling it.
Start it
docker compose up -dOnly Caddy is exposed publicly; Compose creates a private network for the two services. To update later: docker compose pull && docker compose up -d. If you pinned tags, change them first.
Official security notes (Hardening Guide)
- Disable signups once your account exists. By default, anyone can register. Set
SIGNUPS_ALLOWED: "false"and recreate the container. You can optionally disable invitations too. - Hide password hints: Vaultwarden shows hints on the login page, which attackers could abuse. You can turn this off.
- Don't use Rocket TLS on public instances. It doesn't support strict SNI or ECC certificates.
- **Redact
access_tokenin proxy logs:** WebSocket notification requests put a JWT in the URL. If you keep or ship access logs (as the Caddyfile above does), redact that parameter. - Consider a non-root user (
user: 1000:1000). Mount only the data you need, and use:rowhere possible. Never mount/var/run/docker.sockwithout a good reason. - Brute-force mitigation: without 2FA, passwords can in theory be brute-forced. The wiki suggests fail2ban, but be careful behind several proxies.
- Admin page: an
ADMIN_TOKENacts as the admin password. Keep it secret, and preferably store it hashed as an argon2id PHC string, generated withvaultwarden hash(admin page docs). If you don't set it, the admin page stays disabled.
⚠️ Caution: signups are open (
SIGNUPS_ALLOWED: "true") until you change them, and the server is public as soon as Caddy has a certificate. Create your account immediately, then disable signups. We haven't tested certificate issuance or a vault restore.
Backups: a password vault needs tested backups. Follow the wiki's backup page (editor: add it from the official wiki; not covered here).
Sources
- https://github.com/dani-garcia/vaultwarden/wiki/Using-Docker-Compose
- https://github.com/dani-garcia/vaultwarden/wiki/Enabling-HTTPS
- https://github.com/dani-garcia/vaultwarden/wiki/Hardening-Guide
- https://github.com/dani-garcia/vaultwarden/wiki/Enabling-admin-page
- https://github.com/dani-garcia/vaultwarden/releases/tag/1.37.4
- https://github.com/caddyserver/caddy/releases/tag/v2.11.7