Back to home

Secure Self-Hosted Password Manager - Deploying Vaultwarden with Tailscale and Docker

5 min read
Homelab

If you’ve ever tried self-hosting a password manager like Vaultwarden, you’ll quickly realize that getting HTTPS set up is half the battle. Vaultwarden, a lightweight Bitwarden-compatible server, requires HTTPS for browser extensions and mobile apps to function — but setting up SSL certificates, reverse proxies, and DNS can be a hassle. And if you don’t have a custom domain? Things get even messier.

Luckily, there’s a clean, modern solution: Tailscale.

In this post, I’ll show you how to deploy Vaultwarden securely and privately using Tailscale’s MagicDNS and HTTPS proxying features, all within Docker containers — no domain name, no NGINX, no open ports.

Why Use Tailscale for Vaultwarden?

  • HTTPS Without Headaches: Tailscale’s built-in HTTPS proxy (via tailscale serve) gives you a valid HTTPS endpoint without needing a domain or SSL certs.
  • Private Remote Access: Access Vaultwarden from anywhere in the world — securely — while keeping it isolated from the public internet.
  • Simple Networking: Tailscale creates a peer-to-peer mesh network across your devices with stable IPs and DNS — no port forwarding, no firewalls to configure.
  • No Host Exposure: We’ll use Docker’s network_mode: service:<name> to route Vaultwarden’s traffic through Tailscale, keeping it isolated from the host network.

What You’ll Need

Before we get started:

  1. A home server (can be Unraid, Raspberry Pi, Ubuntu, etc.) with Docker installed
  2. A Tailscale account and an active Tailnet
  3. MagicDNS and HTTPS certificates enabled in your Tailscale admin panel
  4. A Tailscale auth key (generated from Settings > Personal Settings > Keys > Auth Keys)

Docker Compose Setup

Here’s a ready-to-use docker-compose.yml that runs both Vaultwarden and Tailscale in a secure network:

version: "3"
services:
  vaultwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden
    network_mode: service:tailscale # Vaultwarden shares the network stack with Tailscale
    restart: unless-stopped
    depends_on:
      - tailscale
    volumes:
      - <PATH_TO_VAULTWARDEN_DATA>:/data:rw
    environment:
      - ADMIN_TOKEN=<YOUR_SECRET_KEY>
      - WEBSOCKET_ENABLED=false
      - SIGNUPS_ALLOWED=true

  tailscale:
    image: ghcr.io/tailscale/tailscale:v1.74.1
    restart: unless-stopped
    environment:
      - TS_AUTHKEY=<TAILSCALE_AUTH_KEY>
      - TS_SERVE_CONFIG=/config/serve.json
      - TS_HOSTNAME=vaultwarden
    volumes:
      - <PATH_TO_TAILSCALE_CONFIG>:/config
      - /dev/net/tun:/dev/net/tun
    cap_add:
      - net_admin
      - sys_module

Replace the following placeholders:

  • <PATH_TO_VAULTWARDEN_DATA> with the path on your server to store Vaultwarden data
  • <PATH_TO_TAILSCALE_CONFIG> with a persistent volume for Tailscale settings
  • <YOUR_SECRET_KEY> with your desired admin token
  • <TAILSCALE_AUTH_KEY> with your generated Tailscale auth key

Tailscale Serve Configuration

Create the following file in the path <PATH_TO_TAILSCALE_CONFIG>/serve.json

{
  "TCP": {
    "443": {
      "HTTPS": true
    }
  },
  "Web": {
    "${TS_CERT_DOMAIN}:443": {
      "Handlers": {
        "/": {
          "Proxy": "http://127.0.0.1:80"
        }
      }
    }
  }
}

A few things to note:

  • This instructs Tailscale to serve HTTPS traffic on port 443 and proxy it to Vaultwarden (which listens on port 80).
  • ${TS_CERT_DOMAIN} is automatically matched by Tailscale based on your Tailnet.
  • Make sure this file is located at /config/serve.json inside the container, because that's the location the Tailscale daemon will look for it. That’s why the volume mount - <PATH_TO_TAILSCALE_CONFIG>:/config is essential in the Docker Compose file.

Launching the Stack

To deploy:

docker compose up -d

After a few seconds, visit your Tailscale dashboard — you should see a new device named vaultwarden. From any device on your Tailnet, visit:

https://vaultwarden.<yourname>.ts.net

And that’s it — a fully self-hosted, HTTPS-secure password manager running in your private network!

Why This Works So Well

This method solves the biggest headaches of self-hosting Vaultwarden:

  • ✅ No need to expose your home IP to the public internet
  • ✅ No NGINX, Caddy, or Certbot required
  • ✅ No domain name needed
  • ✅ Seamless HTTPS support for mobile + browser extensions
  • ✅ Simple remote access with end-to-end encryption

And best of all — it’s 100% self-hosted, and 100% yours.

Final Thoughts

If you’ve ever hesitated to host a password manager due to the HTTPS complexity, Tailscale unlocks an incredibly elegant solution. It’s secure by default, easy to scale, and keeps your most sensitive data away from prying eyes.

Whether you’re running a full-blown homelab or just dipping your toes into self-hosting, this is one project that’s absolutely worth it.

Want to learn how to add 2FA, backups, or use Vaultwarden with browser extensions? Follow me or check back soon for the next guide in the series!