# ============================================================================= # VAULTWARDEN PASSWORD MANAGER - CRITICAL SECURITY SERVICE # ============================================================================= # # SERVICE OVERVIEW: # - Self-hosted Bitwarden-compatible password manager # - CRITICAL: Contains ALL homelab passwords and secrets # - Two-container setup: PostgreSQL database + Vaultwarden server # - Accessible via https://pw.vish.gg (external domain) # # DISASTER RECOVERY PRIORITY: MAXIMUM CRITICAL # - This service contains passwords for ALL other services # - Loss of this data = loss of access to entire homelab # - BACKUP FREQUENCY: Multiple times daily # - BACKUP LOCATIONS: Local + offsite + encrypted cloud # # RECOVERY TIME OBJECTIVE (RTO): 15 minutes (CRITICAL) # RECOVERY POINT OBJECTIVE (RPO): 1 hour (MAXIMUM) # # SECURITY CONSIDERATIONS: # - Admin token required for configuration changes # - SMTP configured for password reset emails # - Database encrypted at rest # - All communications over HTTPS only # # DEPENDENCIES: # - Volume2 for data storage (separate from Volume1 for redundancy) # - External domain (pw.vish.gg) for remote access # - SMTP access for email notifications # - Reverse proxy for HTTPS termination # # ============================================================================= version: "3.9" services: # ========================================================================== # POSTGRESQL DATABASE - Password Vault Storage # ========================================================================== db: # DATABASE IMAGE: # - postgres:16-bookworm: Latest stable PostgreSQL with Debian base # - Version 16: Latest major version with improved performance # - bookworm: Debian 12 base for security and stability image: postgres:16-bookworm # CONTAINER IDENTIFICATION: # - Vaultwarden-DB: Clear identification for monitoring/logs # - vaultwarden-db: Internal hostname for service communication container_name: Vaultwarden-DB hostname: vaultwarden-db # RESOURCE LIMITS: # - mem_limit: 512MB maximum memory (sufficient for password database) # - cpu_shares: 768 (medium priority, less than Vaultwarden app) # - Prevents database from consuming excessive resources mem_limit: 512m cpu_shares: 768 # SECURITY CONFIGURATION: # - no-new-privileges: Prevents privilege escalation attacks # - user: 1026:100 (Synology user/group for file permissions) # - CRITICAL: Must match NAS permissions for data access security_opt: - no-new-privileges:true user: 1026:100 # HEALTH MONITORING: # - pg_isready: PostgreSQL built-in health check command # - Checks database connectivity and readiness # - timeout: 45s (generous timeout for startup) # - interval: 10s (frequent checks for quick failure detection) # - retries: 10 (allows for slow startup during high load) healthcheck: test: ["CMD", "pg_isready", "-q", "-d", "vaultwarden", "-U", "vaultwardenuser"] timeout: 45s interval: 10s retries: 10 # DATA PERSISTENCE: # - /volume2/metadata/docker/vaultwarden/db: Database storage location # - CRITICAL: Volume2 used for redundancy (separate from Volume1) # - Contains ALL password vault data # - BACKUP CRITICAL: This directory contains encrypted password database volumes: - /volume2/metadata/docker/vaultwarden/db:/var/lib/postgresql/data:rw # DATABASE CONFIGURATION: # - POSTGRES_DB: Database name for Vaultwarden # - POSTGRES_USER: Database user (matches DATABASE_URL in Vaultwarden) # - POSTGRES_PASSWORD: "REDACTED_PASSWORD" password (SECURITY: Change in production) # - NOTE: These credentials are for database access, not vault access environment: POSTGRES_DB: vaultwarden POSTGRES_USER: vaultwardenuser POSTGRES_PASSWORD: "REDACTED_PASSWORD" # pragma: allowlist secret # RESTART POLICY: # - on-failure:5: Restart up to 5 times on failure # - Prevents infinite restart loops while ensuring availability # - Database failures are typically resolved by restart restart: on-failure:5 # ========================================================================== # VAULTWARDEN SERVER - Password Manager Application # ========================================================================== vaultwarden: # APPLICATION IMAGE: # - vaultwarden/server: Official Vaultwarden image # - Rust-based, lightweight Bitwarden server implementation # - latest: Auto-updates (consider pinning for production) image: vaultwarden/server:testing # CONTAINER IDENTIFICATION: # - Vaultwarden: Main application container # - vaultwarden: Internal hostname for service communication container_name: Vaultwarden hostname: vaultwarden # RESOURCE ALLOCATION: # - mem_limit: 256MB maximum (Rust is memory-efficient) # - mem_reservation: 96MB guaranteed memory # - cpu_shares: 1024 (high priority - critical service) mem_limit: 256m mem_reservation: 96m cpu_shares: 1024 # SECURITY HARDENING: # - no-new-privileges: Prevents privilege escalation # - user: 1026:100 (Synology permissions for data access) security_opt: - no-new-privileges:true user: 1026:100 # NETWORK CONFIGURATION: # - 4080:4020: External port 4080 maps to internal port 4020 # - Port 4080: Accessible via reverse proxy for HTTPS # - Port 4020: Internal Rocket web server port ports: - 4080:4020 # DATA PERSISTENCE: # - /volume2/metadata/docker/vaultwarden/data: Application data # - Contains: Vault data, attachments, icons, logs # - BACKUP CRITICAL: Contains encrypted user vaults # - Separate from database for additional redundancy volumes: - /volume2/metadata/docker/vaultwarden/data:/data:rw environment: # WEB SERVER CONFIGURATION: # - ROCKET_PORT: Internal web server port (matches container port) # - Must match the internal port in ports mapping ROCKET_PORT: 4020 # DATABASE CONNECTION: # - DATABASE_URL: PostgreSQL connection string # - Format: postgresql://user:REDACTED_PASSWORD@host:port/database # - Connects to 'db' service via Docker networking DATABASE_URL: postgresql://vaultwardenuser:REDACTED_PASSWORD@vaultwarden-db:5432/vaultwarden # pragma: allowlist secret # ADMIN INTERFACE SECURITY: # - ADMIN_TOKEN: Argon2 hashed admin password # - Required for admin panel access (/admin) # - SECURITY: Generated with strong password and Argon2 hashing # - DISABLE_ADMIN_TOKEN: false (admin panel enabled) # - CRITICAL: Change this token in production ADMIN_TOKEN: $$argon2id$$v=19$$m=65540,t=3,p=4$$azFxdU5ubEJvaDN6VkRSTENkbElYOFVWd1dmaDU3K0ZTNnI4ME45WHI3Yz0$$XdCzw6jqk8PY8vGEdd+LNhrpyUHbucTv2AIzZMzN4aQ # pragma: allowlist secret DISABLE_ADMIN_TOKEN: false # EXTERNAL ACCESS CONFIGURATION: # - DOMAIN: External domain for Vaultwarden access # - Used for: Email links, HTTPS redirects, CORS headers # - CRITICAL: Must match reverse proxy configuration DOMAIN: https://pw.vish.gg # EMAIL CONFIGURATION (Password Reset & Notifications): # - SMTP_HOST: Gmail SMTP server for email delivery # - SMTP_FROM: Sender email address for notifications # - SMTP_PORT: 587 (STARTTLS port for Gmail) # - SMTP_SECURITY: starttls (encrypted email transmission) # - SMTP_USERNAME: Gmail account for sending emails # - SMTP_PASSWORD: "REDACTED_PASSWORD" # pragma: allowlist secret # - SECURITY: Use app-specific password, not account password SMTP_HOST: smtp.gmail.com SMTP_FROM: your-email@example.com SMTP_PORT: 587 SMTP_SECURITY: starttls SMTP_USERNAME: your-email@example.com SMTP_PASSWORD: "REDACTED_PASSWORD" # pragma: allowlist secret # SSO CONFIGURATION (Authentik OIDC): SSO_ENABLED: true SSO_ONLY: false SSO_AUTHORITY: https://sso.vish.gg/application/o/vaultwarden/ SSO_CLIENT_ID: vaultwarden SSO_CLIENT_SECRET: "REDACTED_CLIENT_SECRET" # pragma: allowlist secret SSO_ALLOW_UNKNOWN_EMAIL_VERIFICATION: true SSO_SIGNUPS_MATCH_EMAIL: true # RESTART POLICY: # - on-failure:5: Restart up to 5 times on failure # - Critical service must be highly available # - Prevents infinite restart loops restart: on-failure:5 # SERVICE DEPENDENCIES: # - depends_on: Ensures database starts before Vaultwarden # - condition: service_started (waits for container start, not readiness) # - Database must be available for Vaultwarden to function depends_on: db: condition: service_started # ============================================================================= # DISASTER RECOVERY PROCEDURES - VAULTWARDEN # ============================================================================= # # CRITICAL BACKUP COMMANDS: # # Database backup (encrypted vault data): # docker exec Vaultwarden-DB pg_dump -U vaultwardenuser vaultwarden > /volume2/backups/vaultwarden-db-$(date +%Y%m%d-%H%M).sql # # # Application data backup: # tar -czf /volume2/backups/vaultwarden-data-$(date +%Y%m%d-%H%M).tar.gz /volume2/metadata/docker/vaultwarden/data/ # # # Complete backup (database + data): # docker-compose exec db pg_dump -U vaultwardenuser vaultwarden | gzip > /volume2/backups/vaultwarden-complete-$(date +%Y%m%d-%H%M).sql.gz # # EMERGENCY RESTORE PROCEDURE: # 1. Stop services: docker-compose down # 2. Restore database: # docker-compose up -d db # docker exec -i Vaultwarden-DB psql -U vaultwardenuser vaultwarden < backup.sql # 3. Restore data: tar -xzf vaultwarden-data-backup.tar.gz -C /volume2/metadata/docker/vaultwarden/ # 4. Fix permissions: chown -R 1026:100 /volume2/metadata/docker/vaultwarden/ # 5. Start services: docker-compose up -d # 6. Verify: Access https://pw.vish.gg and test login # # OFFLINE PASSWORD ACCESS: # - Export vault data before disasters # - Keep encrypted backup of critical passwords # - Store master password in secure physical location # - Consider KeePass backup for offline access # # MONITORING & HEALTH CHECKS: # - Health check: curl -f http://localhost:4080/alive # - Database check: docker exec Vaultwarden-DB pg_isready # - Admin panel: https://pw.vish.gg/admin (requires admin token) # - Logs: docker logs Vaultwarden && docker logs Vaultwarden-DB # # SECURITY INCIDENT RESPONSE: # 1. Immediately change admin token # 2. Force logout all users via admin panel # 3. Review access logs for suspicious activity # 4. Update all critical passwords stored in vault # 5. Enable 2FA for all accounts if not already enabled # # =============================================================================