π Vaultwarden + Tailscale Setup Guide (Docker Compose) β
This guide explains how to securely deploy Vaultwarden (a Bitwarden-compatible password manager) behind Tailscale using Docker Compose. This setup ensures your Vaultwarden instance is accessible only via your private Tailscale network, with no public exposure.
π§© Overview β
This setup includes two services:
- Tailscale β Creates a secure, private VPN connection to your server.
- Vaultwarden β A lightweight, Bitwarden-compatible password manager running on the Tailscale network.
The Vaultwarden service runs inside the Tailscale network namespace (via network_mode: service:tailscale), meaning it is only reachable over Tailscale.
π Project Structure β
vaultwarden-tailscale/
β
βββ docker-compose.yml
βββ .env
βββ tailscale_state/ # Persistent Tailscale data
βββ vw-data/ # Vaultwarden database and configsβοΈ Environment Variables (.env) β
Create a .env file in the same directory as your docker-compose.yml:
# ---------------------------
# General Settings
# ---------------------------
SERVICE=vaultwarden
# ---------------------------
# Tailscale Configuration
# ---------------------------
TS_VERSION=latest
TS_AUTHKEY=tskey-xxxxxxxxxxxxxxxxx # Generate from https://login.tailscale.com/admin/settings/keys
# ---------------------------
# Vaultwarden Configuration
# ---------------------------
VAULTWARDEN_VERSION=latest
VAULTWARDEN_PORT=8080π³ Docker Compose File β
services:
tailscale:
image: tailscale/tailscale:${TS_VERSION}
container_name: tailscale-${SERVICE}
restart: unless-stopped
environment:
- TS_STATE_DIR=/var/lib/tailscale
volumes:
- ./tailscale_state:/var/lib/tailscale
- /dev/net/tun:/dev/net/tun
cap_add:
- NET_ADMIN
- SYS_MODULE
dns:
- 1.1.1.1
- 8.8.8.8
command: >
sh -c "
tailscaled & sleep 8 &&
tailscale up --authkey=${TS_AUTHKEY} --hostname=${SERVICE} &&
echo 'Waiting for ${SERVICE}...' &&
while ! nc -z 127.0.0.1 ${VAULTWARDEN_PORT}; do sleep 2; done &&
tailscale serve --bg http://127.0.0.1:${VAULTWARDEN_PORT} &&
tail -f /dev/null
"
vaultwarden:
image: vaultwarden/server:${VAULTWARDEN_VERSION}
container_name: ${SERVICE}
restart: unless-stopped
depends_on:
- tailscale
network_mode: service:tailscale
environment:
ROCKET_PORT: ${VAULTWARDEN_PORT}
ROCKET_ADDRESS: 0.0.0.0
SIGNUPS_ALLOWED: "true"
WEBSOCKET_ENABLED: "true"
volumes:
- ./vw-data:/dataπ Setup Instructions β
Install Docker & Docker Compose
If not already installed:
bashsudo apt update sudo apt install docker.io docker-compose -y sudo systemctl enable --now dockerCreate the Directory Structure
bashmkdir -p ~/vaultwarden-tailscale/{tailscale_state,vw-data} cd ~/vaultwarden-tailscaleCreate the
.envFileFollow the example above and add your Tailscale auth key.
Launch the Stack
bashsudo docker compose up -dCheck Status
bashsudo docker compose ps sudo docker logs tailscale-vaultwarden -fTIP
When you see something like:
Serving http://127.0.0.1:8080 over Tailscale......your setup is working!
π§ Access Vaultwarden β
Once the container is up and connected, you can access your Vaultwarden instance using your Tailscale hostname or IP:
http://vaultwarden.tailnet-name.ts.net
To find your Tailscale hostname or IP:
sudo docker exec -it tailscale-vaultwarden tailscale statusπ§Ή Maintenance Commands β
| Command | Description |
|---|---|
docker compose up -d | Start containers |
docker compose down | Stop containers |
docker compose logs -f | View logs |
docker exec -it tailscale-vaultwarden tailscale status | Check Tailscale connection |
docker exec -it tailscale-vaultwarden tailscale ip -4 | Get Tailscale IP |
π οΈ Notes β
INFO
- The Vaultwarden service does not expose any public ports.
- Tailscale Serve makes Vaultwarden accessible via HTTPS on your Tailscale domain (e.g.,
https://vaultwarden.tailnet-name.ts.net). - If you want to use HTTPS certificates, enable HTTPS in Tailscale Serve via the Tailscale admin console.
π Optional Hardening Tips β
Disable public signups by setting:
SIGNUPS_ALLOWED=falseUse environment variables for admin settings:
ADMIN_TOKEN=<your-strong-admin-token>Restrict access via Tailscale ACLs if needed.
β Example Output β
tailscale serve statusServing:
https://vaultwarden.tailnet-name.ts.net β http://127.0.0.1:8080You can now open Vaultwarden from any device in your Tailscale network at that HTTPS URL.