Install Vaultwarden on Proxmox VE

Why Proxmox for Vaultwarden?

Proxmox VE gives you proper isolation for security-critical services. Running Vaultwarden in a dedicated LXC container means it gets its own filesystem, network stack, and resource limits — completely separated from everything else on the host. The footprint is tiny: 1 vCPU, 512 MB RAM, and 4 GB of disk. Proxmox Backup Server can snapshot the entire container on a schedule, giving you reliable, consistent backups of your password vault without any in-container scripting.

Prerequisites

  • Proxmox VE 8.x installed and accessible via web UI
  • A CT template downloaded (Ubuntu 22.04 or Debian 12 recommended)
  • 512 MB RAM available on the Proxmox host
  • 4 GB disk space on your storage pool
  • Network configured (bridge vmbr0 or a dedicated VLAN for security)
  • A domain name with HTTPS for Bitwarden client access

Create the LXC Container

Via Proxmox Web UI

  1. Go to your Proxmox node, click Create CT
  2. Set the following:
    • Hostname: vaultwarden
    • Password: set a root password
    • Template: Ubuntu 22.04 or Debian 12
    • Disk: 4 GB (enough for Vaultwarden + Docker)
    • CPU: 1 core
    • Memory: 512 MB
    • Swap: 256 MB
    • Network: DHCP or static IP on vmbr0
    • DNS: use host settings
  3. Under Options, check Nesting (required for Docker inside LXC)
  4. Do NOT check Unprivileged if you plan to run Docker — privileged containers are simpler for Docker socket access

Via CLI

# On the Proxmox host
pveam download local ubuntu-22.04-standard_22.04-1_amd64.tar.zst

pct create 110 local:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.zst \
  --hostname vaultwarden \
  --memory 512 \
  --swap 256 \
  --cores 1 \
  --rootfs local-lvm:4 \
  --net0 name=eth0,bridge=vmbr0,ip=dhcp \
  --features nesting=1 \
  --unprivileged 0 \
  --start 1

Install Docker Inside the LXC

Enter the container:

pct enter 110

Install Docker:

apt update && apt install -y ca-certificates curl gnupg
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo $VERSION_CODENAME) stable" > /etc/apt/sources.list.d/docker.list
apt update && apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

Verify Docker works:

docker run --rm hello-world

Docker Compose Configuration

Create the project directory:

mkdir -p /opt/vaultwarden && cd /opt/vaultwarden

Create docker-compose.yml:

services:
  vaultwarden:
    image: vaultwarden/server:1.35.4
    container_name: vaultwarden
    restart: unless-stopped
    environment:
      # REQUIRED: Set your actual domain (must be HTTPS)
      - DOMAIN=https://vault.example.com
      # Admin panel token — generate with: openssl rand -base64 48
      - ADMIN_TOKEN=${ADMIN_TOKEN}
      # Disable signups after creating your account
      - SIGNUPS_ALLOWED=true
      # WebSocket for instant sync
      - WEBSOCKET_ENABLED=true
      # Rate limiting for brute-force protection
      - LOGIN_RATELIMIT_MAX_BURST=5
      - LOGIN_RATELIMIT_SECONDS=60
      # Logging
      - LOG_LEVEL=warn
      - EXTENDED_LOGGING=true
    volumes:
      - vaultwarden-data:/data
    ports:
      - "8080:80"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:80/alive"]
      interval: 30s
      timeout: 10s
      retries: 3

volumes:
  vaultwarden-data:

Generate the .env file:

echo "ADMIN_TOKEN=$(openssl rand -base64 48)" > .env

Start Vaultwarden:

docker compose up -d

Verify:

docker compose ps
curl -s http://localhost:8080/alive && echo " OK"

First-Time Setup

  1. Set up HTTPS via a reverse proxy on your Proxmox network. You can run Nginx Proxy Manager in a separate LXC, use a Caddy container, or route through Cloudflare Tunnel. See the Reverse Proxy guide.

  2. Navigate to https://vault.example.com and create your account.

  3. Disable signups:

# Edit docker-compose.yml: SIGNUPS_ALLOWED=true -> SIGNUPS_ALLOWED=false
cd /opt/vaultwarden
sed -i 's/SIGNUPS_ALLOWED=true/SIGNUPS_ALLOWED=false/' docker-compose.yml
docker compose up -d
  1. Access the admin panel at https://vault.example.com/admin with your token from .env.

Proxmox-Specific Configuration

Network Isolation

For maximum security, put Vaultwarden on an isolated VLAN or internal bridge. Only the reverse proxy should be able to reach it:

# On the Proxmox host — create an internal bridge
# Edit /etc/network/interfaces or use the web UI
auto vmbr1
iface vmbr1 inet manual
    bridge-ports none
    bridge-stp off
    bridge-fd 0

Then add a second NIC to the LXC on vmbr1 with an internal-only IP. Your reverse proxy LXC gets interfaces on both vmbr0 (external) and vmbr1 (internal).

Proxmox Backup Server Integration

Proxmox Backup Server (PBS) can back up entire LXC containers, including the Vaultwarden data volume. This is the cleanest backup approach on Proxmox because it captures everything atomically.

  1. In Proxmox web UI, go to Datacenter > Storage > Add > Proxmox Backup Server
  2. Configure your PBS connection
  3. Go to Datacenter > Backup > Add:
    • Node: your node
    • Storage: your PBS storage
    • Schedule: daily
    • Selection mode: Include selected VMs — select CT 110
    • Retention: keep-daily=7, keep-weekly=4, keep-monthly=3

The backup captures the container filesystem including Docker volumes. Restoring is a one-click operation.

Resource Monitoring

Watch LXC resource usage from the Proxmox host:

# CPU and memory for CT 110
pct exec 110 -- free -m
pct exec 110 -- uptime

# Or from Proxmox web UI: select the container -> Summary

Vaultwarden barely registers. You will see ~50 MB memory used and near-zero CPU.

Troubleshooting

Docker won’t start inside LXC — “permission denied” or “cgroup” errors

The LXC needs the nesting feature enabled:

# On the Proxmox host
pct set 110 --features nesting=1
pct restart 110

If using an unprivileged container, Docker may fail on certain operations. Switch to a privileged container or use --features nesting=1,keyctl=1.

Container can’t reach the internet

Check the network configuration:

pct exec 110 -- ping -c 3 1.1.1.1
pct exec 110 -- cat /etc/resolv.conf

Ensure the bridge (vmbr0) has a gateway configured and your Proxmox host can route traffic.

Backup fails with “container is running”

Proxmox supports live backup of running LXC containers. If it still fails, check that the storage backend supports snapshots (LVM, ZFS, or Ceph — directory storage does not support live snapshots and requires a stop/start cycle).

Vaultwarden data is lost after container recreation

Docker volumes inside an LXC are stored in the container’s filesystem. If you destroy and recreate the LXC, the volumes are gone. Always use Proxmox backups or bind-mount a directory that is on persistent storage:

    volumes:
      - /opt/vaultwarden/data:/data  # Bind mount instead of named volume

LXC uses more memory than expected

Docker’s memory overhead inside an LXC adds ~100 MB on top of Vaultwarden’s ~50 MB. If you set the LXC to 512 MB, you will use about 200-250 MB total. This is normal.

Resource Requirements

  • LXC allocation: 1 vCPU, 512 MB RAM, 4 GB disk
  • Actual usage: ~50 MB RAM for Vaultwarden, ~100 MB for Docker overhead
  • CPU: Near zero. Vaultwarden is idle 99.9% of the time.
  • Disk: ~200 MB used (Docker + Vaultwarden image + data)

Comments