Vaultwarden self-hosted: senhas da equipe com backup e custo 94% menor
POC interna para 6 pessoas (DevOps + DBA), deploy Vaultwarden + Caddy + SQLite em Proxmox com runbooks, backup/restore testado e economia ~R$ 2k/ano vs EC2.
DevOps Engineer (Estagiário) · Consultoria AWS Select Partner
- Vaultwarden
- Docker
- Caddy 2
- SQLite
- Proxmox VE
- Bash
TL;DR
- 6 pessoas (DevOps + DBA) atendidas por POC interna Vaultwarden + Caddy + SQLite em Proxmox.
- -94% no custo mensal (~R$ 10 alocação Proxmox vs R$ 175-205 em EC2 t3.small), documentado em ADR de provedor.
- 6 runbooks polished / ~2.279 linhas cobrindo instalação, backup, restore, troubleshooting e validação — a POC sobrevive ao autor.
Contexto
Equipe interna de 6 pessoas (DevOps + DBA) compartilhava credenciais de clientes por canais informais: anexos em chat, planilhas em drive pessoal, .env colado em DM. Isso acontece em time pequeno porque “resolve agora”, mas deixa três dívidas quietas: onboarding precisa de apresentação pessoa-a-pessoa das senhas, offboarding exige pedir a quem saiu que “esqueça” tudo, e revogar uma credencial exige caçar onde ela foi reencaminhada.
Alternativas SaaS foram avaliadas: 1Password Teams e Bitwarden Teams entregavam o produto pronto, mas o orçamento por seat × 6 seats saía da faixa que o líder técnico aceitava bancar num time desse porte sem uma justificativa de escala. O time já operava Proxmox VE com VMs ociosas e headroom sobrando — a pergunta virou “dá pra hospedar algo Bitwarden-compatível em casa?”.
Ação
A entrega foi uma POC interna estruturada em quatro fases (POC Local, Backup/Restore, Docs, App Desktop) com critério de “done” explícito em cada uma. Três frentes práticas:
Stack e deploy
Escolha consciente por simplicidade antes de escala:
- Vaultwarden (implementação Rust, compatível com clients Bitwarden) em Docker Compose.
- Caddy 2 como reverse proxy com HTTPS automático (ACME), escutando em
:8443. - SQLite embarcado — suficiente pra 6 usuários, zero operação de banco separado.
- Crypto: AES-256-CBC + PBKDF2-HMAC-SHA256 com 600.000 iterações (padrão Vaultwarden atual).
# docker-compose.yml — trecho ilustrativo, anonimizado
services:
vaultwarden:
image: vaultwarden/server:latest
restart: unless-stopped
environment:
DOMAIN: "https://senhas.empresa.tld"
SIGNUPS_ALLOWED: "false"
ADMIN_TOKEN: "${ADMIN_TOKEN}" # gerenciado fora do repo
volumes:
- ./data:/data
caddy:
image: caddy:2
restart: unless-stopped
ports:
- "8443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- ./certs:/data
Backup e restore
O que diferencia POC de produto que sobrevive é restore testado. Dois ciclos completos foram executados e registrados:
- 14/01/2026 — primeiro snapshot íntegro (SQLite +
data/rsa_key*.pem+attachments/). - 19/01/2026 — segundo ciclo com restore validado em VM limpa para provar que o runbook não depende da máquina original.
O script verificacao.sh (~54KB) checa pós-restore: Vaultwarden sobe, Caddy renova cert, admin panel responde, login real funciona com a senha master do responsável.
Docs que sobrevivem ao autor
A entrega de documentação foi o que diferenciou essa POC de uma “pastinha no Notion”:
- 6 markdowns polished, totalizando ~2.279 linhas / ~54KB:
- runbook de instalação
- runbook de backup/restore
- troubleshooting (erros comuns, ordem de verificação)
- checklist de validação pós-deploy
- doc-mãe (índice + contexto)
- guia de infraestrutura Proxmox (hosts, rede, armazenamento)
O critério interno: um colega pego de surpresa numa sexta-feira consegue restaurar o serviço seguindo o runbook sem me chamar.
Trade-offs e o que NÃO fiz
- Proxmox em vez de AWS EC2 (ADR custo): VM num host Proxmox compartilhado custa em torno de R$ 10/mês em alocação proporcional; o equivalente mais próximo em EC2 t3.small + EBS orçou entre R$ 175 e R$ 205/mês. Para uma POC de 6 usuários em rede corporativa, pagar 17× mais por elasticidade que não ia ser usada não fazia sentido — economia projetada na casa de ~R$ 2k/ano.
- SQLite em vez de Postgres: com 6 usuários e zero necessidade de HA, Postgres seria overhead de operação (backup separado, upgrades, autenticação). O momento de migrar seria se a POC virasse produto pra toda a consultoria — limite escrito na doc: ~50 usuários simultâneos ou qualquer sinal de escrita concorrente disputada.
- Self-host em vez de 1Password / Bitwarden Teams: o trade-off declarado é claro — ganhei custo, perdi responsabilidade de segurança. Significa que quem mantém precisa cuidar de patch, backup testado e rotação do
ADMIN_TOKEN; e a decisão foi registrada em ADR justamente para que um sucessor saiba o porquê antes de “só migrar pro SaaS”. - App desktop em WSL2 ficou bloqueada: durante testes do cliente oficial Bitwarden em WSL2 apareceu erro
Failed to fetchpersistente contra o servidor local. Foi documentado emtroubleshooting.mdcomo limitação conhecida — clientes CLI e mobile/web funcionam; desktop em WSL2 exige workaround ou uso via browser. Preferi publicar a limitação do que esconder. - Não automatizei provisionamento com Ansible/Terraform: para uma VM única em infra que já existe, o ganho seria superficial e a manutenção do IaC custaria mais que o deploy manual guiado por runbook.
Resultado
A POC entregou o que se propôs: um gerenciador de senhas corporativo autogerido, com HTTPS automático via Caddy, custo próximo de zero, e — mais importante — um restore que funcionou em máquina limpa num ciclo de 5 dias. O valor técnico está menos no Vaultwarden em si e mais no conjunto deploy + runbook + restore testado + trade-off documentado.
Sendo honesto sobre o escopo: trata-se de uma POC interna, não de um rollout corporativo. A adoção efetiva pela equipe e a migração formal para produção permanente ficaram fora do perímetro desta entrega — são o próximo ciclo, condicionado a decisão do líder técnico sobre manter self-host ou contratar SaaS com o custo total agora claro.
O que fica publicável desta fase: a arquitetura, a análise de custo comparada, os runbooks, e o fato de que a POC sobreviveu a um segundo restore sem precisar de mim na frente do teclado.