Install Vaultwarden with Docker and Caddy on Ubuntu 20.04
Vaultwarden is a community-driven alternative to the Bitwarden server, developed in Rust. It maintains compatibility with official Bitwarden clients and consumes fewer system resources than Bitwarden’s official server. This guide walks you through the setup of Vaultwarden using Docker and docker-compose on Ubuntu 20.04, and secures it with Caddy.
System Requirements
Ensure the following before proceeding:
- Launch an Ubuntu 20.04 environment.
- Bring your server up to date.
- Set up a user account with sudo rights that isn’t root.
- Access the server as that non-root user.
- Allow traffic on port 443.
- Create a DNS A record that connects a domain or subdomain to your server’s IP. Caddy requires a resolvable domain to obtain a TLS/SSL certificate.
Install Docker Engine
Begin by removing older versions of Docker and its components:
$ sudo apt remove docker docker.io containerd runc
Update snapd to the latest version:
$ sudo snap install core; sudo snap refresh core
Next, install Docker via snap:
$ sudo snap install docker
Vaultwarden Setup
Docker Container Preparation
Create a dedicated directory for Vaultwarden and navigate into it:
$ mkdir ~/vaultwarden
$ cd ~/vaultwarden
Now, generate and open the docker-compose.yml
file:
$ nano docker-compose.yml
Insert the following configuration into the file:
version: '3'
services:
vaultwarden:
image: vaultwarden/server:latest
container_name: vaultwarden
restart: always
environment:
- WEBSOCKET_ENABLED=true
volumes:
- ./vw-data:/data
caddy:
image: caddy:2
container_name: caddy
restart: always
ports:
- 80:80
- 443:443
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- ./caddy-config:/config
- ./caddy-data:/data
environment:
- DOMAIN=
- EMAIL=
- LOG_FILE=/data/access.log
Specify your actual domain or subdomain by updating the DOMAIN
variable within the environment settings for the Caddy container:
environment:
- DOMAIN=https://example.com
Also add a valid email address to the EMAIL
variable for certificate provisioning via Let’s Encrypt:
environment:
- DOMAIN=https://example.com
- EMAIL=user@example.com
To close and save your changes in the nano editor, press Ctrl + X, then confirm with Y, and finalize with Enter.
Setting Up the Caddyfile
Start by creating and editing a new Caddy configuration file:
$ nano Caddyfile
Paste the following configuration into the Caddyfile:
{$DOMAIN}:443 {
log {
level INFO
output file {$LOG_FILE} {
roll_size 10MB
roll_keep 10
}
}
# Get a cert by using the ACME HTTP-01 challenge.
tls {$EMAIL}
encode gzip
# Headers to improve security.
header {
# Enable HSTS
Strict-Transport-Security "max-age=31536000;"
# Enable cross-site filter (XSS)
X-XSS-Protection "1; mode=block"
# Disallow the site to be rendered within a frame (clickjacking protection)
X-Frame-Options "DENY"
# Prevent search engines from indexing
X-Robots-Tag "none"
# Remove Caddy branding
-Server
}
# Redirect notifications to the WebSocket.
reverse_proxy /notifications/hub vaultwarden:3012
reverse_proxy vaultwarden:80 {
header_up X-Real-IP {remote_host}
}
}
Exit and save the Caddyfile by pressing Ctrl + X, then Y, followed by Enter.
This configuration instructs Caddy to route incoming HTTPS traffic on port 443 to Vaultwarden. It also applies several HTTP headers for added protection, including HSTS for strict transport security, anti-XSS settings, frame blocking to prevent clickjacking, search engine indexing restrictions, and branding removal.
Launching Vaultwarden
To start Vaultwarden, use docker-compose
in detached mode. The startup process might take a few moments:
$ sudo docker-compose up -d
Verify the container is up and running by inspecting the status with docker ps
:
$ sudo docker ps
Look for a status indicating that the container is “Up” for a certain duration (e.g., seconds or minutes).
Enhancing Security Settings
Vaultwarden offers further options to tighten security through its configuration.
Turning Off User Registration
By default, your Vaultwarden instance permits anyone to register. While this is beneficial during setup, it may become a liability later.
Once your personal account is created, you can prevent new registrations by updating the SIGNUPS_ALLOWED
variable to false
in docker-compose.yml
:
services:
vaultwarden:
... other configuration ...
environment:
- SIGNUPS_ALLOWED=false
... other configuration ...
Disabling the Invitation Feature
Vaultwarden lets existing users send invitations to others. If your deployment is for a single user or small, trusted group, this may not be necessary.
You can switch this feature off by setting INVITATIONS_ALLOWED
to false
:
services:
vaultwarden:
... other configuration ...
environment:
- INVITATIONS_ALLOWED=false
... other configuration ...
Hiding Password Hints
In the official Bitwarden server, password hints are typically emailed. Vaultwarden, built for self-hosted environments, shows these hints on a webpage instead—no email setup required.
If you prefer to disable this behavior, add SHOW_PASSWORD_HINT
and set it to false
in your docker-compose.yml
file:
services:
vaultwarden:
... other configuration ...
environment:
- SHOW_PASSWORD_HINT=false
... other configuration ...
Final Notes
By following the steps above, you will have a fully functioning Vaultwarden instance running securely with Docker and Caddy on Ubuntu 20.04. All key security settings can be fine-tuned directly within your docker-compose.yml
file, providing flexibility and control over account creation, invitation permissions, and password hint visibility.
Make sure to keep your Docker containers updated and monitor access logs regularly for any suspicious behavior. Caddy’s logging system writes to the file you specified via the LOG_FILE
variable, making it easy to audit access patterns and maintain oversight.
If you plan to expand your setup or integrate with external systems, refer to the official Vaultwarden and Docker documentation for advanced configurations such as environment variable tuning, backup strategies, or multi-user deployments.