Vaultwarden: Bitwarden self-hosted no Linux

Tux em HQ diante do logo do Vaultwarden e do escudo do Bitwarden

O Vaultwarden é um servidor compatível com os clientes oficiais do Bitwarden, escrito em Rust. Cabe num Raspberry Pi, gasta dezenas de MB de RAM e libera no self-host o que o Bitwarden oficial cobra: TOTP, Send, organizações, emergency access. Não é o Bitwarden Inc. — é o projeto da comunidade (ex-bitwarden_rs), AGPL-3.0, hoje na 1.37.2.

Se você já tem um Linux na internet e não quer mandar o cofre para a nuvem de ninguém, este é o caminho curto: um container, HTTPS na frente, apps oficiais apontando para o seu domínio.

O que é (e o que não é)

Os apps (Android, iOS, desktop, extensão, CLI) falam a API do Bitwarden. O Vaultwarden implementa essa API. O cofre continua criptografado no cliente (zero-knowledge): o servidor guarda blobs que ele não consegue ler.

  • Serve para você, a família, o homelab, um time pequeno. Roda em SQLite (padrão), MySQL ou PostgreSQL. ~50 MB de RAM em idle.
  • Não serve para empresa que precisa de SOC 2, SLA e suporte da Bitwarden Inc. O projeto não tem auditoria formal equivalente. Você é o backup, o patch e o firewall.

A 1.37.2 (agosto de 2026) é obrigatória para clientes Bitwarden 2026.8.0+. SSO via OpenID Connect existe (wiki); SCIM/Secrets Manager oficiais, não.

Subir com Docker e Caddy

A via recomendada pelo projeto é o container. HTTPS é obrigatório: o web vault usa Web Crypto, que o browser só libera em contexto seguro. Caddy pede o certificado sozinho. (Se Docker ainda é novidade, tem o curso de Docker.)

Gere o token do painel admin (Argon2) antes do compose:

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

Cole a string $argon2id$... no YAML. No Compose cada $ vira $$.

mkdir -p /opt/vaultwarden && cd /opt/vaultwarden
# /opt/vaultwarden/compose.yaml
services:
  vaultwarden:
    image: vaultwarden/server:1.37.2
    container_name: vaultwarden
    restart: unless-stopped
    environment:
      DOMAIN: "https://vault.exemplo.com.br"
      SIGNUPS_ALLOWED: "true"
      ADMIN_TOKEN: "$$argon2id$$v=19$$m=65540,t=3,p=4$$COLE_O_HASH"
    volumes:
      - ./vw-data:/data

  caddy:
    image: caddy:2
    container_name: vw-caddy
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy_data:/data
      - caddy_config:/config
    depends_on:
      - vaultwarden

volumes:
  caddy_data:
  caddy_config:
# /opt/vaultwarden/Caddyfile
vault.exemplo.com.br {
    encode zstd gzip
    reverse_proxy vaultwarden:80
}
# DNS do domínio → IP desta máquina, depois:
docker compose up -d
docker compose logs -f

Quem já tem nginx (ISPConfig, etc.) dispensa o serviço Caddy: publique o Vaultwarden só em 127.0.0.1:8000 e faça proxy + Let’s Encrypt no nginx. WebSocket vai na mesma porta 80 do container — não precisa mais da 3012.

Primeiro login e travar o cadastro

Abra https://vault.exemplo.com.br, crie a sua conta. Depois feche a porta:

SIGNUPS_ALLOWED: "false"
docker compose up -d

Convites posteriores saem do painel /admin (o token que você gerou). Sem ADMIN_TOKEN, o painel nem existe — e é assim que deve ficar se você não for usar.

Ligue 2FA no cofre (TOTP ou FIDO2) no primeiro dia. É o mesmo app Bitwarden; a diferença é só o servidor.

Apontar os clientes oficiais

Em qualquer app Bitwarden: engrenagem → Self-hosted → cole https://vault.exemplo.com.br. Login com o e-mail da conta que você criou. Extensão do browser, celular e CLI (bw config server) usam o mesmo URL.

Não reporte bug do Vaultwarden no suporte da Bitwarden Inc. O README é explícito: issue e discussão vão para o GitHub/Matrix do projeto.

Backup — se não tem, não tem cofre

O volume ./vw-data é o cofre: db.sqlite3, anexos, ícones. Sem isso, senha nenhuma volta. Um cron diário basta:

# pare o write, copie a pasta, suba de novo
cd /opt/vaultwarden
docker compose stop vaultwarden
tar -C /opt/vaultwarden -czf /backup/vw-$(date +%F).tar.gz vw-data
docker compose start vaultwarden

Guarde a cópia fora da máquina (outro disco, outro VPS, fita, o que for). Teste restaurar uma vez. O systemd OnCalendar= resolve o agendamento se você não quiser cron.

Referências

Um binário Rust, um volume e HTTPS. O cofre fica no hardware que você controla — e o app no bolso continua o mesmo.