Návody a tutoriály

Instalace Vaultwarden: vlastní správce hesel

Zveřejněno 28. ledna 2025 · 12 min čtení

Tento článek je k dispozici ve francouzštině a angličtině.

Why Vaultwarden

Vaultwarden is a lightweight reimplementation of the Bitwarden API, written in Rust: compatible with every official Bitwarden client (browser, mobile, desktop), it runs in about 50 MB of RAM where the official server demands several gigabytes. It is the reference self-hosted password manager.

Prerequisites

An Ubuntu 24.04 VPS with Docker installed (see our guide "Install Docker on Ubuntu 24.04") and a domain vault.example.com pointing to the server. HTTPS is mandatory: Bitwarden clients rely on the browser's Web Crypto API, which doesn't exist on plain HTTP outside localhost.

Step 1 — Directory layout

mkdir -p /opt/vaultwarden/data
cd /opt/vaultwarden

Step 2 — Generate the Argon2 admin token

The /admin panel is protected by a token. Never store it in plaintext — generate an Argon2 hash:

docker run --rm -it vaultwarden/server:latest /vaultwarden hash

Enter a long passphrase; the command prints a string like $argon2id$v=19$m=65540,t=3,p=4$.... Keep it for the next step.

Step 3 — docker-compose.yml

Create /opt/vaultwarden/docker-compose.yml:

services:
  vaultwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden
    restart: unless-stopped
    environment:
      DOMAIN: 'https://vault.example.com'
      SIGNUPS_ALLOWED: 'false'
      ADMIN_TOKEN: '$$argon2id$$v=19$$m=65540,t=3,p=4$$your-hash-here'
    volumes:
      - ./data:/data
    ports:
      - '127.0.0.1:8080:80'

Two critical details: every $ must be doubled ($$) in a compose file, otherwise Docker attempts variable interpolation; and the container only listens on 127.0.0.1, the reverse proxy bridges it. SIGNUPS_ALLOWED: false doesn't block account creation via invitation from /admin, but it stops drive-by registrations.

Step 4 — Start the container

docker compose up -d
docker compose logs -f

Check locally: curl -I http://127.0.0.1:8080 should return 200.

Step 5 — Nginx reverse proxy and HTTPS

Create /etc/nginx/sites-available/vault.example.com:

server {
    listen 80;
    server_name vault.example.com;

    client_max_body_size 128M;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Enable and certify:

ln -s /etc/nginx/sites-available/vault.example.com /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx
apt install -y certbot python3-certbot-nginx
certbot --nginx -d vault.example.com

Step 6 — Create your account

Temporarily set SIGNUPS_ALLOWED to 'true', restart (docker compose up -d), create your master account at https://vault.example.com, then switch back to 'false' and restart. Your account exists, registrations are closed. You can still invite other users from /admin.

Importing your existing passwords

From Bitwarden, LastPass or 1Password, export your vault as CSV or JSON, then in Vaultwarden: Settings → Import Data. The vault stays end-to-end encrypted — only you hold the master password, the server stores nothing readable without it. Destroy the export file right after (shred -u export.csv): it contains every secret in plaintext.

On the client side, install the official Bitwarden extension (Chrome, Firefox) or the mobile app, and enter your server URL under the "Self-hosted" settings before the first login. All your devices then sync through your VPS, without touching a third-party cloud.

Backups

Everything lives in /opt/vaultwarden/data: db.sqlite3 (the encrypted vault), attachments/, rsa_key*. As with any SQLite database, use the native backup command rather than copying the file:

sqlite3 /opt/vaultwarden/data/db.sqlite3 ".backup '/opt/vaultwarden/data/db-backup.sqlite3'"
tar -czf /backups/vaultwarden-$(date +%F).tar.gz -C /opt/vaultwarden data

Schedule this script in a daily cron and ship the archive to external storage (rclone, a second VPS — see our guide on the 3-2-1 rule).

Hardening

  • The admin token is an Argon2 hash, never a plaintext value. If you don't use /admin, remove the ADMIN_TOKEN variable entirely: the panel is disabled.
  • Configure SMTP in environment (SMTP_HOST, SMTP_FROM, SMTP_SECURITY...) to receive invitations and login alerts.
  • Update weekly: docker compose pull && docker compose up -d.

Verification

  • https://vault.example.com shows the Bitwarden login screen.
  • The browser extension, pointed at your server URL, syncs the vault.
  • https://vault.example.com/admin asks for the token and shows diagnostics.

Troubleshooting

  • Blank page or crypto error: you're on HTTP — HTTPS is mandatory.
  • 502 Bad Gateway: docker compose ps to check the container is up, docker compose logs for the cause.
  • Admin token rejected: the hash's $ characters aren't doubled in the compose file.
  • Invitations never arrive: missing or wrong SMTP — test from /admin → Diagnostics.
  • High RAM usage over time: Vaultwarden itself stays light; check docker stats for runaway attachments syncs, and cap container memory with a mem_limit if your VPS hosts other services.
  • Lost admin token: remove the ADMIN_TOKEN line, restart the container, and generate a fresh Argon2 hash — vault data is never affected, the token only guards the diagnostics panel.

Tutoriály krok za krokem psané našimi inženýry, testované na naší infrastruktuře.

GLOBALCLOUDHOSTING →