Back to blog
Blog

Deploy Vaultwarden on a VPS With Nginx and HTTPS

Deploy Vaultwarden on a VPS with Docker Compose, Nginx HTTPS, backups, updates, and practical hardening for teams.

By Anurag Singh
Updated on Oct 19, 2026
Category: Blog
Share article
Deploy Vaultwarden on a VPS With Nginx and HTTPS

Passwords become operational debt when they end up in browser sync, chat threads, spreadsheets, or “temporary” ticket notes. If you want Bitwarden compatibility without handing your vault to a third party, deploy Vaultwarden on a VPS you control. You still get the web vault and the official mobile/desktop clients. You also keep custody of your data and your logs.

This guide is for people who run real servers. It focuses on trade-offs, common failure modes, and a production-friendly setup. You’ll use Docker Compose, Nginx with Let’s Encrypt, real backups, and update steps that won’t ruin your day.

What Vaultwarden is (and what it isn’t)

Vaultwarden is a community-maintained server that implements the Bitwarden server APIs. It’s written in Rust, runs lean, and works with the official Bitwarden clients. That compatibility is the whole point.

Your team keeps the same apps and extensions, but you own the backend.

  • Best fit: small teams, agencies, and operators who want a Bitwarden-compatible password manager without enterprise overhead.
  • Not the same thing as: the official Bitwarden self-hosted stack (which can be heavier and is designed for broader enterprise use cases).
  • Licensing: Vaultwarden is open source under the AGPL-3.0. That’s fine for internal use, but pay attention if you plan to offer it as a hosted service to others.

In practice, Vaultwarden is pleasantly “boring.” It’s a web app plus a database. SQLite is the default, or you can use PostgreSQL/MySQL for larger setups.

Add SMTP if you want invites, notifications, and smoother account flows.

Why teams replace hosted password managers with Vaultwarden

Hosted password managers are convenient—until they aren’t. Billing disputes, regional outages, locked accounts, and compliance questions still land on your desk. You can’t fix them from the outside.

Self-hosting Vaultwarden usually makes sense when:

  • You need data residency (keep vault data in a specific region or provider).
  • You want predictable costs and to avoid per-seat surprises for contractors or clients.
  • You prefer a smaller attack surface—one hardened VPS instead of a web of SaaS identities and OAuth connections.
  • You want auditable operations (your firewall rules, your access logs, your change control).

The downside is simple: you become the operator. Patching, backups, monitoring, and recovery planning are now your responsibility.

You can keep it lightweight, but you can’t ignore it.

Resource requirements for a production Vaultwarden VPS

Vaultwarden itself is light. The supporting pieces need most of the headroom. That includes TLS termination, backups, and basic monitoring.

In 2026, a sensible baseline looks like this:

  • CPU: 1 vCPU is fine for small teams; use 2 vCPU if you expect frequent client syncs and attachments.
  • RAM: 1 GB works; 2 GB is a safer floor if you run Nginx + certbot + monitoring and want swap avoidance.
  • Disk: 20–40 GB SSD/NVMe for the OS + Docker + backups. Plan more if you allow file attachments.
  • OS: Ubuntu or Debian LTS/stable are straightforward choices for Docker-based deployments.

If you want this to run quietly in the background, a managed VPS hosting plan can cost less than the time you’ll spend on patch windows and incident response.

If you prefer full control, a HostMyCode VPS gives you the raw infrastructure without the management layer.

Hosted vs self-hosted: a quick comparison

Here’s what most teams notice quickly.

Decision pointHosted password managerVaultwarden on your VPS
Client appsNative apps + browser extensionsSame official Bitwarden clients
Data controlProvider controls storage and logsYou control storage, logs, and retention
Compliance questionsDepends on vendor paperworkYou can prove infrastructure choices and region
Ops workMinimalPatch, backup, monitor, secure access
Cost modelOften per-userMostly fixed infrastructure cost

Deploy Vaultwarden on a VPS with Docker Compose (production layout)

The common production pattern is simple. Run Vaultwarden in a container. Put Nginx in front for HTTPS.

You can split proxy and app across hosts later. For most teams, one VPS is the right starting point.

Assumptions used below:

  • Ubuntu or Debian VPS
  • DNS A/AAAA record for vault.example.com pointing to the VPS
  • Docker and Docker Compose installed

Directory layout that stays tidy and is easy to back up:

  • /opt/vaultwarden/compose.yml
  • /opt/vaultwarden/data/ (persistent app data)

Example /opt/vaultwarden/compose.yml using the official Vaultwarden image:

services:
  vaultwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden
    restart: unless-stopped
    environment:
      # Set your public URL so clients behave correctly.
      DOMAIN: "https://vault.example.com"

      # Email is strongly recommended for invites and notifications.
      # Add SMTP_* values once you have mail configured.
      # SMTP_HOST: "smtp.example.com"
      # SMTP_FROM: "vault@yourdomain.com"
      # SMTP_PORT: "587"
      # SMTP_SECURITY: "starttls"
      # SMTP_USERNAME: "vault@yourdomain.com"
      # SMTP_PASSWORD: "YOUR_SMTP_PASSWORD"

      # Prefer disabling signups after initial setup.
      SIGNUPS_ALLOWED: "false"

      # Do not expose admin without a token.
      ADMIN_TOKEN: "REPLACE_WITH_A_LONG_RANDOM_STRING"

    volumes:
      - ./data:/data
    ports:
      # Bind only to localhost; Nginx will proxy.
      - "127.0.0.1:8080:80"

Create the directory and start it:

sudo mkdir -p /opt/vaultwarden
sudo chown -R root:root /opt/vaultwarden
cd /opt/vaultwarden
sudo nano compose.yml
sudo docker compose up -d
sudo docker compose ps

Why bind to 127.0.0.1? It keeps the app port off the public internet. Your only public entry point should be Nginx on 80/443.

If you want a quick hardening refresher (firewall rules and safe inbound access), keep this open: Set up UFW on Ubuntu for a web server.

Even a minimal UFW policy cuts down exposure.

Nginx reverse proxy with HTTPS (Let’s Encrypt)

Vaultwarden encrypts data at the application level. You still need solid TLS at the edge.

Nginx gives you clean HTTP→HTTPS redirects and a predictable place for certificates. It also gives you room to add stricter headers later.

Install Nginx and certbot:

sudo apt update
sudo apt install -y nginx certbot python3-certbot-nginx

Create an Nginx server block at /etc/nginx/sites-available/vaultwarden:

server {
  listen 80;
  server_name vault.example.com;

  location / {
    proxy_pass http://127.0.0.1:8080;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;

    # WebSocket support (Vaultwarden uses it for some clients)
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
  }
}

Enable and test:

sudo ln -s /etc/nginx/sites-available/vaultwarden /etc/nginx/sites-enabled/vaultwarden
sudo nginx -t
sudo systemctl reload nginx

Issue a certificate:

sudo certbot --nginx -d vault.example.com

Certbot will add the TLS block and set up renewals. If you run into renewal failures, mixed content warnings, or ALPN errors, this guide has a solid troubleshooting path: Configure HTTPS with Let’s Encrypt on a VPS.

Admin hardening that actually matters

Most Vaultwarden incidents aren’t cryptography failures. They’re ops mistakes. Common ones include open signups, a reachable admin panel, weak SSH, or “backups” that never leave the box.

  • Keep signups closed: set SIGNUPS_ALLOWED=false after you create the initial users.
  • Protect the admin panel: always set ADMIN_TOKEN and treat it like root credentials. Store it in a password manager (yes, even before Vaultwarden is live).
  • Don’t publish the container port: keep it bound to 127.0.0.1 and proxy via Nginx.
  • Lock down SSH: disable password logins, use keys, and consider restricting access via a VPN.

If multiple people administer the server, or you bring in contractors, put admin access behind a small VPN. It reduces risk fast.

This pairs well with: Set up WireGuard VPN for admin access.

Also consider basic rate limiting in Nginx. Password-related endpoints attract credential stuffing, and one noisy IP can bury your logs. HostMyCode’s guide on Nginx rate limiting maps cleanly to Vaultwarden’s login traffic.

Backups: what to copy, where to store it, and how to restore

Backups are straightforward if you keep the deployment simple. The rule that matters: backups must leave the VPS. An archive on the same disk is not a backup.

What you need to back up:

  • /opt/vaultwarden/compose.yml (or your Compose file)
  • /opt/vaultwarden/data/ (includes database and attachments, depending on your config)

A practical routine is: stop briefly, archive, start again. For small teams, a 10–30 second blip is usually fine. It also keeps SQLite consistent.

# Optional: announce a short maintenance window
cd /opt/vaultwarden
sudo docker compose stop vaultwarden

# Create a timestamped archive
sudo tar -C /opt -czf /root/vaultwarden-backup-$(date +%F).tgz vaultwarden

sudo docker compose start vaultwarden

Then push the archive offsite. S3-compatible object storage, a second VPS, or a backup repository tool all work.

If you want a complete recovery workflow (including restore drills), keep this bookmarked: build a tested VPS disaster recovery runbook.

Restore should be boring too. The core steps are:

  1. Provision a new VPS (or clean the old one).
  2. Install Docker + Nginx.
  3. Copy the backup archive onto the server.
  4. Extract back to /opt/vaultwarden and run docker compose up -d.
  5. Re-issue TLS (or restore /etc/letsencrypt if you also backed it up).

Run a restore test at least quarterly. A password manager is the last place you want “untested backup” surprises.

Safe updates: how to patch without breaking client sync

Updating a container is easy: pull, restart. Staying safe comes down to habits. That matters more when the service holds every credential you care about.

  • Back up first. Every time. No exceptions.
  • Read release notes. Most Vaultwarden updates are smooth, but breaking changes do happen.
  • Keep your Compose file under version control. Even a private Git repo makes change review painless.

Update flow:

cd /opt/vaultwarden
sudo docker compose pull
sudo docker compose up -d
sudo docker image prune -f

After updating, verify three basics:

  • Web vault loads over HTTPS.
  • A mobile client can sync.
  • Logs look clean: sudo docker logs --since=10m vaultwarden

If you already use maintenance windows for other services, treat Vaultwarden the same way. Downtime is rarely the problem. Surprise downtime is.

Operational checks you’ll be glad you set up

You don’t need a full observability stack. You do need early warnings for downtime, low disk, and TLS renewal failures.

Two checks catch most real-world issues:

  • Uptime check: probe https://vault.example.com every minute and alert if it fails twice.
  • Disk monitoring: alert at 80% and 90% usage; Docker layers and backup archives creep over time.

If you want a ready-to-use pattern for VPS alerting, follow HostMyCode’s monitoring setup guide: build alerts for your VPS with Netdata and uptime checks. It focuses on signals you’ll actually act on.

Email, DNS, and deliverability (don’t ignore this)

Vaultwarden will run without email. You’ll lose invites, notifications, and some recovery-related messages.

If you enable SMTP, treat deliverability as part of the deployment. Password-manager mail gets filtered aggressively.

Minimum DNS hygiene for your sending domain:

  • SPF record that authorizes your sending host
  • DKIM signing enabled at the sender
  • DMARC policy set (even p=none is better than nothing)

HostMyCode’s walkthrough on DKIM, SPF, and DMARC is a good starting point. If you still need a domain and clean DNS management, start here: domains at HostMyCode.

Want Vaultwarden to run like a production service? Put it on infrastructure that’s meant for always-on workloads. A HostMyCode VPS gives you full control for Docker, Nginx, and hardened SSH. If you’d rather offload patching and routine maintenance, managed VPS hosting gets you the same outcome with less day-to-day ops work.

FAQ: running Vaultwarden in production

Can I run Vaultwarden on shared hosting?

Realistically, no. You need Docker (or at least a system service), the ability to run a reverse proxy, and control over ports and TLS. Vaultwarden is a VPS or dedicated-server workload.

Should I use SQLite or PostgreSQL?

SQLite is fine for many small teams, especially with short maintenance windows and consistent backups. If you expect higher concurrency, heavy attachment use, or you want easier database tooling, PostgreSQL is a better long-term choice.

Do I need to expose Vaultwarden directly to the internet?

Users need to reach it, but admin access should be constrained. Consider restricting the admin URL by IP, using a VPN for admin tasks, and keeping the container port on 127.0.0.1 behind Nginx.

What’s the biggest operational risk?

Bad backups. The second biggest is delayed updates. Treat your password manager like production infrastructure: tested offsite backups, patch cadence, and monitoring for disk and downtime.

Summary: keep it simple, keep it owned

If your team already uses Bitwarden clients, Vaultwarden is the smallest self-hosted move that still feels professional. You keep compatibility and keep operations predictable. You also decide where your secrets live.

When you’re ready to deploy Vaultwarden on a VPS and run it like any other critical service, start with a HostMyCode VPS. If you want the same setup with less day-to-day operational load, use managed VPS hosting and stay focused on your actual work.