Netcup.Sale
Self-hosting

Self-host Vaultwarden on Netcup — a 6 € password vault for your whole household

Vaultwarden is a Rust rewrite of the Bitwarden server that idles at 30 MB of RAM. A 6 € Netcup VPS hosts your entire family's vault with headroom to spare.

// @mvossMay 4, 202613 min read

A golden padlock resting on a laptop keyboard — fitting metaphor for a self-hosted password vault.

Self-host Vaultwarden on Netcup — a 6 € password vault for your whole household

Self-host Vaultwarden on a Netcup VPS to run a Bitwarden-compatible password manager without paying per-seat fees and without trusting a third party with your encrypted vault. Vaultwarden is a single-binary Bitwarden alternative written in Rust, and it idles at roughly 30 MB of RAM — small enough that the cheapest Netcup VPS is more than enough to host the whole family.

TL;DR: Running Vaultwarden on Netcup in 5 minutes

Vaultwarden is an unofficial, AGPL-licensed reimplementation of the Bitwarden server in Rust. It speaks the official Bitwarden API, so the official mobile and browser clients connect to it transparently. Because it skips the upstream server's MSSQL + microservice sprawl, it fits in a Docker container that fits on the smallest tier Netcup sells.

  • What it is: a self-hosted password manager server compatible with all official Bitwarden clients.
  • What it competes with: Bitwarden's hosted plan, 1Password, LastPass, the official Bitwarden self-hosted server.
  • Hosting profile: ~10 to 50 MB RAM idle, ~100 MB under realistic load, single binary, SQLite by default.
  • Default port: 80 inside the container, mapped to a local port and put behind Caddy or another reverse proxy.
  • Database: SQLite out of the box; MariaDB and PostgreSQL if you outgrow it.
  • License: AGPL-3.0, no telemetry, no phone-home.
mkdir -p /opt/vaultwarden && cd /opt/vaultwarden
cat > docker-compose.yml <<'YAML'
services:
  vaultwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden
    restart: unless-stopped
    environment:
      DOMAIN: "https://vault.example.com"
      SIGNUPS_ALLOWED: "false"
    volumes:
      - ./data:/data
    ports:
      - "127.0.0.1:8000:80"
YAML
docker compose up -d

Primary pick: VPS 500 G12 — 2 vCPU, 4 GB RAM, 128 GB NVMe, around 5.91 €/month. Vaultwarden barely registers on this tier, leaving room for Caddy, a backup cron, and three or four other small services if you want a household stack.

  • 5 € off any order: 36nc17718015540
  • Second code: 36nc17718015545
  • Third code: 36nc17718015549

There is no dedicated VPS 500 G12 coupon category — the 5 € off-any-order coupon stacks against this tier just fine, since 5.91 € minus 5 € is essentially a month free.

Introduction

Most people who reach for Bitwarden's hosted plan are doing the right thing: a managed password vault is dramatically better than a spreadsheet, a browser keychain that syncs to a single vendor, or a sticky note. The friction starts at the family-and-friends boundary. Adding a partner, a parent, and three kids to the family plan is a fixed monthly cost forever, paid in dollars to a US company that has had bad PR weeks. Self-hosting flips that bill into a single 6 €/month line item that includes hosting twenty other small services on the same box.

Vaultwarden is the right tool for that job because it is not the upstream Bitwarden server. The official server is fine, but it is built for organisations: MSSQL, multiple microservices, a recommended floor of 4 GB of RAM. Vaultwarden, written by Daniel García in Rust, is a single binary that holds full API compatibility with Bitwarden's clients while idling at less than 50 MB. That's the difference between needing a 20 €/month box and being able to run on a 6 €/month box that you also use for something else.

Netcup is the natural host for this. The data centres are in Nuremberg and Vienna — German and Austrian jurisdictions, owned hardware, NVMe across the entire VPS lineup, and pricing that has not chased the cloud-hyperscaler rate card. The smallest VPS G12 has 2 vCPU and 4 GB of RAM, which is comically over-provisioned for Vaultwarden but cheap enough that you can run it that way for years and not feel it.

This article walks through what Vaultwarden is, how a self-hosted password manager changes your day-to-day, the actual install on a fresh Netcup box, and which tier to pick if you want headroom for whatever comes next.

What is Vaultwarden?

Vaultwarden is a self-hosted, Bitwarden-compatible server reimplemented in Rust. It serves the same HTTP and WebSocket APIs that the official Bitwarden server does, which means the official iOS app, Android app, browser extensions, desktop apps, and CLI all talk to it without modification. From the client's perspective, Vaultwarden is Bitwarden.

It was originally released in 2018 under the name bitwarden_rs, then renamed to Vaultwarden in 2021 at Bitwarden Inc.'s request. It is not affiliated with Bitwarden and is maintained independently. The code is licensed AGPL-3.0, the source lives on GitHub under dani-garcia/vaultwarden, and the latest stable release at the time of writing is 1.36.0.

Architecture

The server is a single Rust binary built on the Rocket web framework. It listens on port 80 by default inside the container. State lives in SQLite by default, in a single db.sqlite3 file inside the data directory; the same data directory holds attachments, sends, icons, and the WebSocket session store. MariaDB and PostgreSQL are supported through the Diesel ORM if you outgrow SQLite, but for a home-scale or small-team vault, SQLite is the right answer and stays the right answer for a long time.

A Vaultwarden install is, mechanically:

  • One binary (or one container).
  • One directory of state on disk.
  • A reverse proxy in front of it terminating HTTPS.

That's the whole picture. There is no message broker, no separate identity service, no microservice mesh. The simplicity is the point.

How big does the data get

The vault itself is tiny. A few thousand encrypted entries weigh in well under 100 MB. The data directory grows mostly when users start uploading attachments to entries (passport scans, recovery codes as PDFs, license keys), and even then it's bounded by the configurable ATTACHMENTS_FOLDER size limit. A 128 GB NVMe — what the smallest VPS ships with — is enough vault for a lifetime.

Why people self-host it

Three reasons, in roughly this order:

  1. Cost — a family or small team paying per-seat for a hosted plan crosses the break-even point against a 6 €/month VPS very quickly.
  2. Control — your encrypted vault lives in a jurisdiction and on a machine you chose. The cipher is the same E2E encryption Bitwarden uses, but the blob is on your disk.
  3. Features — Vaultwarden quietly enables features (organisations, attachments, custom fields, emergency access) that the upstream offering reserves for paid plans. Same clients, more switches flipped.

How to use Vaultwarden

Core concepts

Vaultwarden inherits the Bitwarden vocabulary one-to-one. The four nouns that matter:

  • Vault — the per-user, end-to-end encrypted bag of items. Everything in it is encrypted on the client with a key derived from the master password before it ever reaches the server.
  • Item — a login, secure note, card, or identity. Items have name, username, password, URI list, custom fields, and optional file attachments.
  • Organisation — a shared vault. The household, the team, the project. Items live in folders ("collections") and access is granted per user.
  • Send — a one-shot encrypted share. Useful for handing a credential to someone who is not in your org without inviting them.

The admin panel is a separate concept. It is disabled by default and turned on by setting ADMIN_TOKEN in the environment. Once enabled, it lives at /admin on your domain and is where you toggle signups, manage users, browse the running config, and trigger diagnostics. Treat the admin token like a root password and never set it to a value you can remember.

Day-to-day workflow

For users, day-to-day looks like Bitwarden — because it is. The browser extension fills credentials, the mobile app syncs, the desktop client unlocks with biometrics. The only place users notice they're on Vaultwarden is the URL of the web vault and, occasionally, a feature that's been quietly enabled for free that they expected to be paywalled.

For the operator, day-to-day is mostly nothing. The server runs, the logs say 200 OK, the SQLite file grows by a few kilobytes a week. The two operational events that actually happen:

  • Version upgrades. The container's latest tag moves forward roughly monthly. docker compose pull && docker compose up -d is the upgrade.
  • Backups. SQLite's db.sqlite3 is the whole vault. Snapshot it, encrypt it, ship it off the box. More on this below.

Integrations and extensibility

Vaultwarden exposes the Bitwarden API, so anything written against Bitwarden works: the rbw CLI, scripts using the Bitwarden CLI (bw), the password-store-style integrations, and the assorted browser-extension forks. The directory-sync and SCIM features in upstream Bitwarden are the main things Vaultwarden does not implement — if you need automated user provisioning from an IdP for a 200-person company, this is not the right tool. For everyone else, the missing piece is invisible.

WebSocket notifications (so clients see vault changes near-instantly) work natively when the reverse proxy is configured to upgrade /notifications/hub. Caddy handles this with one line; the section below shows it.

tip
Disable open signups (SIGNUPS_ALLOWED=false) the moment your own account is created. The default-on behaviour is convenient for the first five minutes and a liability forever after. Use the admin panel to invite anyone else by email.

Backup and operational reality

The only file that matters is data/db.sqlite3. Everything else (attachments/, sends/, rsa_key.*) matters too, but those are append-only-ish and recoverable; the database is the vault. A safe backup loop is sqlite3 db.sqlite3 ".backup /tmp/db.bak" followed by encrypting and shipping /tmp/db.bak somewhere off-box. The .backup command takes a consistent snapshot even while the server is writing.

The two failure modes worth rehearsing: losing the database (restore from your encrypted off-box backup, point the new instance at it), and forgetting the master password (game over for that vault — Vaultwarden cannot recover what it cannot decrypt; this is the entire security model). Recovery codes printed on paper, or an emergency-access contact, are how the second mode is mitigated, and both are worth setting up before you load the vault with real secrets.

Quick Start Guide

1. Provision the box

Sign up for the VPS 500 G12 at netcup.com and apply coupon 36nc17718015548 for 5 € off — which makes the first month essentially free at 5.91 €. Drop in your SSH public key on creation, choose Debian 12 minimal as the OS, then SSH in and lock the box down:

# /etc/ssh/sshd_config.d/00-hardening.conf
PasswordAuthentication no
PermitRootLogin prohibit-password
KbdInteractiveAuthentication no
systemctl reload ssh
apt update && apt full-upgrade -y
apt install -y ufw
ufw default deny incoming
ufw allow ssh
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable

UFW with three open ports is enough. Vaultwarden itself binds to localhost and gets reached only through the reverse proxy.

2. Install Docker

Vaultwarden ships an official container, and that's the path with the least surprises. The native binary works too but you'd be reinventing the systemd unit and the runtime upgrades.

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

Verify with docker run --rm hello-world. If that prints the welcome message, Docker is working.

3. Point DNS at the box

Create an A record for the subdomain you'll use — vault.example.com — pointing at the VPS's IPv4. Add an AAAA for the IPv6 if you have one configured. Wait for propagation; dig vault.example.com from your laptop should answer the right address before you continue.

4. Write the Compose file

mkdir -p /opt/vaultwarden && cd /opt/vaultwarden
# /opt/vaultwarden/docker-compose.yml
services:
  vaultwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden
    restart: unless-stopped
    environment:
      DOMAIN: "https://vault.example.com"
      SIGNUPS_ALLOWED: "false"
      INVITATIONS_ALLOWED: "true"
      ADMIN_TOKEN: "argon2id-hash-here"
    volumes:
      - ./data:/data
    ports:
      - "127.0.0.1:8000:80"

Generate the admin token with docker run --rm -it vaultwarden/server /vaultwarden hash, paste the resulting Argon2id hash into ADMIN_TOKEN. Plain-text tokens are deprecated and shouted about in the logs.

docker compose up -d
docker compose logs -f vaultwarden

You should see Rocket binding to 0.0.0.0:80 inside the container. Hit curl http://127.0.0.1:8000/alive from the host and expect a timestamp.

5. Reverse proxy with Caddy

Caddy is the house pick. It's one binary, one config file, and it handles Let's Encrypt with no certbot, no cron, no expiry surprises.

apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' \
  | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' \
  | tee /etc/apt/sources.list.d/caddy-stable.list
apt update && apt install -y caddy
# /etc/caddy/Caddyfile
vault.example.com {
    reverse_proxy 127.0.0.1:8000
}
systemctl reload caddy

Caddy will fetch a Let's Encrypt cert the first time it sees a request for vault.example.com. WebSocket upgrades for /notifications/hub are handled automatically — reverse_proxy proxies WebSockets transparently in modern Caddy.

6. Create the first account, then close the door

In a browser, visit https://vault.example.com, register your account, then SSH back to the box and edit the Compose file:

SIGNUPS_ALLOWED: "false"
docker compose up -d

From this point on, new users only enter through the admin panel's invite flow. Sign in to /admin with the token, click "Users → Invite User", and email a registration link.

7. Back the vault up

Add a daily cron that snapshots the SQLite file, encrypts it with age against a key you keep off the box, and ships it to S3-compatible storage (Hetzner Object Storage, Backblaze B2, Wasabi, Storj — pick one).

# /etc/cron.daily/vaultwarden-backup
#!/bin/sh
set -eu
cd /opt/vaultwarden
docker compose exec -T vaultwarden sqlite3 /data/db.sqlite3 ".backup /data/db.bak"
age -r age1examplerecipientkeyhere... data/db.bak \
  | rclone rcat remote:vaultwarden-backups/db-$(date -I).bak.age
rm data/db.bak

Test the restore once. A backup you've never restored is a wish, not a backup.

Choosing the Right Netcup Server for cheap Vaultwarden hosting

Vaultwarden's resource profile (~30 MB idle, ~100 MB under load, a database that grows kilobytes per week) means almost any hosting decision is fine. The interesting question is what else lives on the box. The tiers below bracket the realistic answers, from "Vaultwarden alone, cheapest possible" to "Vaultwarden plus my whole household stack on dedicated cores".

VPS 500 G12 — recommended for almost every Vaultwarden deployment

Specs: 2 vCPU, 4 GB RAM, 128 GB NVMe, traffic included. Around 5.91 €/month (verify on netcup.com).

Why it works for Vaultwarden: the server idles at less than 1% of this tier's RAM. The NVMe handles the SQLite write pattern (a few small writes per minute, even with active users) effortlessly. The two vCPUs are shared, but Vaultwarden does not care about CPU contention — Argon2id key-derivation runs on the client, not the server. There is no scenario where Vaultwarden alone outgrows this tier.

The only reason to pick something larger is if you're co-hosting other services. A typical "household services" box on a 500 G12 might run Vaultwarden, Pi-hole, a Wireguard endpoint, Uptime Kuma, and a small static site, and still idle below 1.5 GB of RAM total.

Coupons (each pops a different code at build time):

  • 36nc17718015542
  • 36nc17718015546
  • 36nc17718015547

The general_5 coupon takes 5 € off any order, including the VPS 500 G12. There is no dedicated VPS 500 coupon category.

VPS 1000 G12 — buffer pick if you'll add more services

Specs: 4 vCPU, 8 GB RAM, 256 GB NVMe. Around 10.37 €/month.

The right pick if you already know you'll layer Nextcloud, a Mastodon instance, an Immich preview, or a Forgejo on top of the same box. Vaultwarden remains a footnote on this tier. You're paying for the room your other workloads will need, not for Vaultwarden's headroom.

Coupons:

  • 5799nc17718015261
  • 5799nc17800061381
  • 5799nc17774618550

VPS 2000 G12 — multi-org, multi-tenant team setups

Specs: 8 vCPU, 16 GB RAM, 512 GB NVMe. Around 19.25 €/month.

Overkill for Vaultwarden in isolation. The tier earns its keep if you're running Vaultwarden alongside a real database (PostgreSQL for several apps), a CI runner, or a heavy app like Penpot or Mastodon on the same host. If your "team Vaultwarden" is for a software company that also wants its Forgejo and matrix-synapse on Netcup, this is the tier that absorbs all of it.

Coupons:

  • 5800nc17718015230
  • 5800nc17804382710
  • 5800nc17802654090

RS 1000 G12 — production for paying customers or strict SLAs

Specs: 4 dedicated AMD EPYC 9645 cores, 8 GB DDR5 ECC, 256 GB NVMe. Around 12.79 €/month.

The Root Server line gives you dedicated cores with no oversubscription, which matters when you're hosting Vaultwarden for paying customers or a company that has put it in scope for a compliance audit. The same RAM as VPS 1000 G12, but the CPU is yours, the memory is ECC, and the noisy-neighbour problem is gone. If "the password manager went down" would be a P1 incident at your job, this is the floor tier.

Coupons:

  • 5159nc17718015443
  • 5159nc17718015441
  • 5997nc17755880771

Comparison

Offer vCPU / cores RAM NVMe Approx. price
VPS 500 G12 2 vCPU 4 GB 128 GB 5.91 €/mo
VPS 1000 G12 4 vCPU 8 GB 256 GB 10.37 €/mo
VPS 2000 G12 8 vCPU 16 GB 512 GB 19.25 €/mo
RS 1000 G12 4 dedicated 8 GB ECC 256 GB 12.79 €/mo

Which one to pick: if you're trying Vaultwarden for the first time and just want a vault for yourself and a few family members, take the VPS 500 G12 and don't overthink it. If you already know the box will end up hosting half a dozen other small services, go straight to VPS 1000 G12 so you don't have to migrate later. If you're running Vaultwarden for paying customers or under a compliance regime, RS 1000 G12 removes the shared-CPU variable from your incident reviews.

Conclusion

After working through this guide you have a hardened Debian VPS, a Vaultwarden instance behind Caddy with a real Let's Encrypt cert, signups closed, the admin panel locked behind an Argon2id token, and a daily encrypted backup landing in off-box storage. Your browser extension and your phone are pointed at your domain instead of bitwarden.com, and the monthly bill is one line, in euros, for a piece of hardware in the EU.

The math is hard to argue with. VPS 500 G12 at 5.91 €/month, minus a 5 € first-order coupon, lands the first month at well under a euro. After that it's 71 €/year for a vault that hosts the whole family, and there's room on the box for a dozen other small services if you ever want them. As a final nudge for whatever order you place: 36nc17718015541 takes 5 € off any Netcup order, so it stacks against the smallest tier or any of the larger ones.

Two things to keep an eye on once you're up: the daily backup actually completing (set up a healthcheck that pings you when it stops landing), and version upgrades on the vaultwarden/server:latest image — read the release notes before pulling, especially across point releases that touch the SQLite schema. Everything else is the kind of boring that good infrastructure is supposed to be.