DEV Community

Elder Fernandes
Elder Fernandes

Posted on Originally published at selfhoststack-8z4.pages.dev

How We Replaced 1Password & HashiCorp Vault with Self-Hosted Vaultwarden + Infisical

How We Replaced 1Password & HashiCorp Vault with Self-Hosted Vaultwarden + Infisical

For small teams and developers, secret management and password sharing usually start with commercial SaaS tools like 1Password Teams ($19.95/mo+), Bitwarden Cloud ($40/yr/user), or HashiCorp Vault Cloud ($0.50/hr+ / $360/mo).

Beyond the monthly seat tax, third-party cloud vaults introduce compliance friction, vendor lock-in, and exposure to centralized cloud outages.

In this guide, we break down how to run Vaultwarden (the lightweight Rust implementation of Bitwarden) alongside Infisical (the modern open-source secrets manager) on a single €4/mo Hetzner VPS with automatic encrypted backups and TLS certificates.


The Architecture

Layer Tool Replaces RAM Footprint
User Passwords & 2FA Vaultwarden 1Password / Bitwarden Cloud ~35 MB
App Secrets & Env Vars Infisical HashiCorp Vault / Doppler / AWS Secrets Mgr ~180 MB
Reverse Proxy & TLS Caddy v2 Cloudflare Zero Trust / Nginx ~25 MB
Relational Database PostgreSQL 16 (for Infisical) RDS / Managed DB ~70 MB
Encrypted Backups Restic / SQLite3 Backup Cloud Snapshots ~15 MB

Total Resource Consumption: < 350 MB RAM at idle, ~600 MB under burst loads.


1. Production Docker Compose (docker-compose.yml)

Create a dedicated directory on your VPS (/opt/secure-vault) and save the following compose manifest:

version: "3.8"

networks:
  vault-net:
    driver: bridge

volumes:
  vaultwarden-data:
  infisical-db:
  infisical-data:
  caddy-data:
  caddy-config:

services:
  # --- Reverse Proxy with Auto-HTTPS ---
  caddy:
    image: caddy:2-alpine
    container_name: vault-caddy
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy-data:/data
      - caddy-config:/config
    networks:
      - vault-net
    depends_on:
      - vaultwarden
      - infisical

  # --- Bitwarden-Compatible Password Manager ---
  vaultwarden:
    image: vaultwarden/server:latest-alpine
    container_name: vaultwarden
    restart: unless-stopped
    environment:
      - WEBSOCKET_ENABLED=true
      - SIGNUPS_ALLOWED=false # Set to true on first boot to register admin, then lock
      - INVITATIONS_ALLOWED=true
      - ADMIN_TOKEN=${VAULTWARDEN_ADMIN_TOKEN}
      - DOMAIN=https://passwords.yourdomain.com
      - ROCKET_PORT=8080
    volumes:
      - vaultwarden-data:/data
    networks:
      - vault-net

  # --- Modern Secrets & Env Management ---
  infisical-db:
    image: postgres:16-alpine
    container_name: infisical-db
    restart: unless-stopped
    environment:
      - POSTGRES_DB=infisical
      - POSTGRES_USER=infisical
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
    volumes:
      - infisical-db:/var/lib/postgresql/data
    networks:
      - vault-net
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U infisical -d infisical"]
      interval: 5s
      timeout: 5s
      retries: 5

  infisical:
    image: infisical/infisical:latest
    container_name: infisical-app
    restart: unless-stopped
    depends_on:
      infisical-db:
        condition: service_healthy
    environment:
      - NODE_ENV=production
      - ENCRYPTION_KEY=${INFISICAL_ENCRYPTION_KEY}
      - AUTH_SECRET=${INFISICAL_AUTH_SECRET}
      - DB_CONNECTION_URI=postgres://infisical:${POSTGRES_PASSWORD}@infisical-db:5432/infisical
      - SITE_URL=https://secrets.yourdomain.com
      - TELEMETRY_CAPTURING_ENABLED=false
    networks:
      - vault-net
Enter fullscreen mode Exit fullscreen mode

2. Reverse Proxy Configuration (Caddyfile)

Caddy automatically provisions and renews Let's Encrypt certificates without any manual certbot crons:

passwords.yourdomain.com {
    encode gzip zstd

    # Websocket notifications for instant sync across devices
    reverse_proxy /notifications/hub vaultwarden:3012
    reverse_proxy vaultwarden:8080 {
        header_up X-Real-IP {remote_host}
    }
}

secrets.yourdomain.com {
    encode gzip zstd
    reverse_proxy infisical:8080 {
        header_up X-Real-IP {remote_host}
    }
}
Enter fullscreen mode Exit fullscreen mode

3. Environment Variables (.env)

Generate strong cryptographic keys:

# Generate keys with openssl
openssl rand -hex 32 # Use for VAULTWARDEN_ADMIN_TOKEN
openssl rand -hex 16 # Use for INFISICAL_ENCRYPTION_KEY (32 hex chars = 16 bytes)
openssl rand -base64 32 # Use for INFISICAL_AUTH_SECRET
openssl rand -hex 24 # Use for POSTGRES_PASSWORD
Enter fullscreen mode Exit fullscreen mode

Write to .env:

VAULTWARDEN_ADMIN_TOKEN=your_generated_admin_token_here
INFISICAL_ENCRYPTION_KEY=your_16_byte_hex_key
INFISICAL_AUTH_SECRET=your_auth_secret
POSTGRES_PASSWORD=your_db_password
Enter fullscreen mode Exit fullscreen mode

4. Automated Encrypted Backups

Never host critical data without tested automated backups. Add a daily cron job that safely dumps the SQLite database and syncs to encrypted off-site storage (Cloudflare R2 or Backblaze B2):

#!/usr/bin/env bash
# /opt/secure-vault/backup.sh
set -euo pipefail

BACKUP_DIR="/opt/secure-vault/backups"
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
mkdir -p "$BACKUP_DIR"

# 1. Atomic SQLite backup for Vaultwarden
docker exec vaultwarden sqlite3 /data/db.sqlite3 ".backup '/data/backup_${TIMESTAMP}.sqlite3'"
docker cp vaultwarden:/data/backup_${TIMESTAMP}.sqlite3 "$BACKUP_DIR/"
docker exec vaultwarden rm "/data/backup_${TIMESTAMP}.sqlite3"

# 2. PostgreSQL backup for Infisical
docker exec infisical-db pg_dump -U infisical infisical | gzip > "$BACKUP_DIR/infisical_${TIMESTAMP}.sql.gz"

# 3. Encrypt and upload via Restic or AWS CLI (S3-compatible)
# aws s3 sync "$BACKUP_DIR" s3://my-offsite-backup-bucket/vault/ --delete
Enter fullscreen mode Exit fullscreen mode

5. Cost Comparison & Return on Investment

Metric Cloud SaaS (1Password + Doppler/Vault) Self-Hosted (Vaultwarden + Infisical)
5-User Team Cost ~$95 / month ($1,140 / year) €3.79 / month (€45.48 / year)
Annual Savings $1,094 / year (96% reduction)
Data Sovereignty Stored in US multi-tenant cloud 100% on your own VPS with isolated DB
Browser Extensions Official Bitwarden extension / CLI Official Bitwarden extension / CLI
CI/CD Integration Doppler / HashiCorp CLI Infisical CLI (infisical run -- app)

Explore More Stacks

Want to explore and benchmark more open-source alternatives to commercial SaaS?

Need ready-to-run, hardened configurations? Grab the Self-Hosted Starter Stack Pack ($29) with 50+ vetted Docker Compose templates, Caddy TLS setups, and automated backup crons.

Top comments (0)