A password vault is the one self-hosted app where "mostly working" is not good enough. Vaultwarden is small, fast on a fraction of a gigabyte, and every serious client refuses to talk to it without a real certificate — which is the part that actually takes the twenty minutes.Ein Passwort-Tresor ist die eine selbst gehostete App, bei der „meistens funktioniert“ nicht gut genug ist. Vaultwarden ist klein, läuft flott mit einem Bruchteil eines Gigabytes, und jeder ernstzunehmende Client weigert sich, ohne ein echtes Zertifikat mit ihm zu sprechen — und genau das ist der Teil, der die zwanzig Minuten wirklich kostet.
Vaultwarden is a from-scratch server implementation of the Bitwarden sync API, written in Rust, distributed as a single small Docker image. It is not Bitwarden's own server software (that project is the much heavier bitwarden/server stack) and it is not affiliated with Bitwarden the company — it is a community project that happens to speak the same protocol, so the official Bitwarden apps and browser extensions work against it once you point them at your own server URL. That compatibility is the entire pitch: your phone, laptop and browser extension do not know or care that the server on the other end is Vaultwarden.Vaultwarden ist eine von Grund auf neu geschriebene Serverimplementierung der Bitwarden-Sync-API, in Rust geschrieben und als einzelnes kleines Docker-Image verteilt. Es ist nicht Bitwardens eigene Serversoftware (dieses Projekt ist der deutlich schwerere bitwarden/server-Stack), und es steht in keiner Verbindung zum Unternehmen Bitwarden — es ist ein Community-Projekt, das zufällig dasselbe Protokoll spricht, sodass die offiziellen Bitwarden-Apps und Browser-Erweiterungen damit funktionieren, sobald du sie auf deine eigene Server-URL zeigen lässt. Genau diese Kompatibilität ist das ganze Versprechen: Dein Handy, dein Laptop und deine Browser-Erweiterung wissen nicht und interessiert es nicht, dass der Server auf der anderen Seite Vaultwarden ist.
Every other app in this series can limp along on plain HTTP for testing. Vaultwarden cannot, and the reason is not policy, it is the client software. The web vault runs inside your browser, and once that page is loaded over HTTPS, mixed-content rules block it from talking to a plain http:// server — the browser refuses the request before it leaves the page. The mobile app and browser extension add their own validation on top and reject a non-HTTPS, non-localhost server URL outright, regardless of what the browser would allow. Try to add a plain-http:// server URL anywhere but localhost and it gets refused before it ever reaches your container. There is no setting that turns this off, because it is not Vaultwarden's rule to relax.Jede andere App in dieser Serie kommt zum Testen mehr schlecht als recht auch mit reinem HTTP zurecht. Vaultwarden nicht, und der Grund ist keine Vorgabe, sondern die Client-Software. Der Web-Tresor läuft in deinem Browser, und sobald diese Seite über HTTPS geladen wurde, verhindern die Mixed-Content-Regeln, dass sie mit einem reinen http://-Server spricht — der Browser verweigert die Anfrage, bevor sie die Seite überhaupt verlässt. Die mobile App und die Browser-Erweiterung setzen ihre eigene Prüfung obendrauf und lehnen eine Server-URL ohne HTTPS und ohne localhost rundweg ab, unabhängig davon, was der Browser erlauben würde. Versuchst du, irgendwo außer localhost eine reine http://-Server-URL einzutragen, wird sie abgelehnt, bevor sie je deinen Container erreicht. Es gibt keine Einstellung, die das abschaltet, weil es nicht Vaultwardens Regel ist, die sich lockern lässt.
Practically this means: get a real hostname and a real certificate before you try to log in from a client, not after. A self-signed certificate does not fix it either — the clients want something a normal trust store accepts, so a real domain behind Let's Encrypt (or equivalent) is the actual requirement, not an optional nicety.Praktisch bedeutet das: Besorge dir einen echten Hostnamen und ein echtes Zertifikat, bevor du versuchst, dich von einem Client aus anzumelden, nicht danach. Auch ein selbstsigniertes Zertifikat behebt das nicht — die Clients wollen etwas, das ein normaler Trust-Store akzeptiert, also ist eine echte Domain hinter Let's Encrypt (oder einer gleichwertigen Lösung) die tatsächliche Voraussetzung, keine optionale Nettigkeit.
Cheap VPS plans very often hand you NAT IPv4 — one shared public address with a short list of forwarded ports — rather than an address that is entirely yours. That is fine for outbound traffic and for SSH on a non-standard port, but it changes how you expose HTTPS.Günstige VPS-Pläne geben dir sehr häufig NAT-IPv4 — eine gemeinsam genutzte öffentliche Adresse mit einer kurzen Liste weitergeleiteter Ports — statt einer Adresse, die ganz dir allein gehört. Das ist für ausgehenden Traffic und für SSH auf einem nicht standardmäßigen Port kein Problem, ändert aber, wie du HTTPS nach außen anbietest.
https://vault.example.com:8443, say. Every Bitwarden client accepts a port in the server URL field; it is one extra field at setup, not a limitation of the protocol. This only works if port 80 is also forwarded to you: Caddy serves the site itself on 8443, but still needs 80 free to complete the HTTP-01 challenge that gets the certificate from Let's Encrypt in the first place. If 80 is not forwarded either, automatic HTTPS on a non-standard port needs a DNS-01 challenge instead — a Caddy build with your DNS provider's plugin, which the stock image does not ship, plus API credentials — so ask about the dedicated IPv4 below if that is on the table.Ist das nicht der Fall, kannst du den Standard-HTTPS-Port nicht binden, also besteht die ehrliche Lösung darin, Caddy auf dem Port laufen zu lassen, den du bekommen hast, und diesen Port in die Server-URL des Clients einzutragen — etwa https://vault.example.com:8443. Jeder Bitwarden-Client akzeptiert einen Port im Feld für die Server-URL; das ist bei der Einrichtung ein zusätzliches Feld, keine Einschränkung des Protokolls. Das funktioniert nur, wenn Port 80 ebenfalls zu dir weitergeleitet wird: Caddy stellt die Seite selbst auf 8443 bereit, braucht aber weiterhin Port 80 frei, um die HTTP-01-Challenge abzuschließen, die das Zertifikat von Let's Encrypt überhaupt erst besorgt. Ist auch 80 nicht weitergeleitet, braucht automatisches HTTPS auf einem nicht standardmäßigen Port stattdessen eine DNS-01-Challenge — einen Caddy-Build mit dem Plugin deines DNS-Anbieters, das das Standard-Image nicht mitbringt, plus API-Zugangsdaten — frag also nach der dedizierten IPv4 weiter unten, falls das infrage kommt.Worth reading first: NAT IPv4 vs a dedicated IP and NAT IPv4, ports and forwarding.Lesenswert vorab: NAT-IPv4 vs. dedizierte IP und NAT-IPv4, Ports und Weiterleitung.
Pin the image tag. Vaultwarden ships new releases regularly and some of them change the database schema, so latest on a vault you actually rely on is a bad trade for saving one line of maintenance. Check the current release at the project's GitHub releases page before copying the tag below — this guide will drift out of date, and running whatever is current matters more than this exact number.Pinne den Image-Tag. Vaultwarden bringt regelmäßig neue Releases heraus, und manche davon ändern das Datenbankschema, also ist latest bei einem Tresor, auf den du dich wirklich verlässt, ein schlechter Tausch für eine gesparte Zeile Wartungsaufwand. Prüfe das aktuelle Release auf der GitHub-Releases-Seite des Projekts, bevor du den Tag unten übernimmst — diese Anleitung wird mit der Zeit veralten, und wichtiger als diese genaue Zahl ist, dass du das jeweils Aktuelle einsetzt.
services:
vaultwarden:
image: vaultwarden/server:1.32.7
restart: unless-stopped
environment:
- DOMAIN=https://vault.example.com
- SIGNUPS_ALLOWED=false
- ADMIN_TOKEN=${ADMIN_TOKEN}
- WEBSOCKET_ENABLED=true
volumes:
- vw-data:/data
ports:
- "127.0.0.1:8080:80"
volumes:
vw-data:
The port is bound to 127.0.0.1 on purpose: nothing but the reverse proxy on the same host can reach Vaultwarden directly, so a stray scanner hitting the VPS's public address on port 8080 finds nothing.Der Port ist absichtlich an 127.0.0.1 gebunden: Nichts außer dem Reverse-Proxy auf demselben Host kann Vaultwarden direkt erreichen, sodass ein zufälliger Scanner, der die öffentliche Adresse des VPS auf Port 8080 trifft, nichts findet.
Generate the admin token before first boot, not after, then hash it rather than storing it raw:Erzeuge den Admin-Token vor dem ersten Start, nicht danach, und hashe ihn, statt ihn roh zu speichern:
docker run --rm -it vaultwarden/server:1.32.7 /vaultwarden hash
That prompts for a password — paste the output of openssl rand -base64 48 into it — and prints an Argon2 PHC string. Put that string, not the raw random value, into .env, wrapped in single quotes — an Argon2 string is full of $ signs, and Docker Compose would otherwise try to expand them as variables and hand Vaultwarden a mangled token:Das fragt nach einem Passwort — füge dort die Ausgabe von openssl rand -base64 48 ein — und gibt einen Argon2-PHC-String aus. Trag diesen String, nicht den rohen Zufallswert, in .env ein, in einfache Anführungszeichen gesetzt — ein Argon2-String steckt voller $-Zeichen, und Docker Compose würde sie sonst als Variablen expandieren und Vaultwarden ein verstümmeltes Token übergeben:
printf "ADMIN_TOKEN='%s'\n" 'paste-the-argon2-phc-string-here' > .env
chmod 600 .env
Vaultwarden accepts a plain token too, but the hashed form is the one its own documentation recommends — it is not vulnerable to timing-attack recovery from the /admin login the way a raw comparison is.Vaultwarden akzeptiert auch einen Token im Klartext, aber die gehashte Form ist die, die seine eigene Dokumentation empfiehlt — sie ist nicht anfällig für eine Wiederherstellung per Timing-Angriff über das /admin-Login, wie es bei einem rohen Vergleich der Fall ist.
SIGNUPS_ALLOWED=false matters more here than the equivalent setting does on most self-hosted apps, because a vault is the one place a stranger creating their own account is a genuinely bad outcome, not just clutter. Leave signups closed and create your own accounts through the /admin page instead, using the token above. If you do want a second household member in, invite them from an existing account rather than reopening signups — invitations work with SIGNUPS_ALLOWED=false set.SIGNUPS_ALLOWED=false spielt hier eine größere Rolle als die entsprechende Einstellung bei den meisten selbst gehosteten Apps, denn ein Tresor ist genau der eine Ort, an dem ein Fremder, der sich selbst ein Konto anlegt, ein wirklich schlechtes Ergebnis ist, nicht nur unnötiger Ballast. Lass Signups geschlossen und lege deine eigenen Konten stattdessen über die /admin-Seite an, mit dem Token von oben. Willst du ein zweites Haushaltsmitglied hinzufügen, lade es von einem bestehenden Konto aus ein, statt die Signups wieder zu öffnen — Einladungen funktionieren auch, wenn SIGNUPS_ALLOWED=false gesetzt ist.
The /admin page itself is worth locking down further once you are done using it day to day: it accepts the same token forever unless you rotate it, so treat that token like a root password, not like an application setting.Die /admin-Seite selbst lohnt es sich, noch weiter abzusichern, sobald du sie nicht mehr täglich brauchst: Sie akzeptiert für immer denselben Token, solange du ihn nicht rotierst, also behandle diesen Token wie ein Root-Passwort und nicht wie eine Anwendungseinstellung.
vault.example.com {
reverse_proxy 127.0.0.1:8080
}
That is the whole file — Caddy requests and renews the certificate on its own the first time it sees a request for that hostname, provided DNS already points at the machine. Point the A record first and let it settle; point your domain at your service covers that if you have not done it before. If you are on the forwarded-port path from the NAT section above, change the site block to vault.example.com:8443, open that port, and make sure 80 is forwarded too — Caddy serves the site on 8443 but still needs 80 open to fetch and renew the certificate itself.Das ist die ganze Datei — Caddy fordert das Zertifikat beim ersten gesehenen Request für diesen Hostnamen von selbst an und erneuert es auch selbst, vorausgesetzt der DNS zeigt bereits auf die Maschine. Richte zuerst den A-Eintrag ein und lass ihn sich setzen; deine Domain auf deinen Dienst zeigen lassen beschreibt das, falls du es noch nicht gemacht hast. Bist du auf dem Weg über den weitergeleiteten Port aus dem NAT-Abschnitt oben, ändere den Site-Block zu vault.example.com:8443, öffne diesen Port, und stelle sicher, dass auch 80 weitergeleitet ist — Caddy stellt die Seite auf 8443 bereit, braucht aber weiterhin Port 80 offen, um das Zertifikat selbst zu beziehen und zu erneuern.
WebSockets need to pass through cleanly for live sync between devices to work — Caddy's reverse_proxy handles the Upgrade/Connection headers automatically, which is one less thing to get wrong compared with a manually written nginx config.WebSockets müssen sauber durchgereicht werden, damit die Live-Synchronisation zwischen Geräten funktioniert — Caddys reverse_proxy kümmert sich automatisch um die Upgrade-/Connection-Header, was eine Fehlerquelle weniger ist im Vergleich zu einer von Hand geschriebenen nginx-Konfiguration.
Vaultwarden is a single Rust binary and a SQLite file holding encrypted blobs — there is no PHP runtime, no Node process, no in-memory cache to budget for. 1 GiB of RAM is plenty, including room for Caddy and the OS itself, even with a handful of accounts and a few hundred items each. Disk is dominated by attachments, if you use them, and those are also usually small. This is the rare self-hosted app where the constraint is not sizing at all — it is getting HTTPS right.Vaultwarden ist eine einzelne Rust-Binary und eine SQLite-Datei mit verschlüsselten Blobs — es gibt keine PHP-Laufzeitumgebung, keinen Node-Prozess, keinen In-Memory-Cache, den man einplanen müsste. 1 GiB RAM reicht locker, inklusive Platz für Caddy und das Betriebssystem selbst, sogar bei einer Handvoll Konten mit je ein paar Hundert Einträgen. Der Speicherplatz wird von Anhängen dominiert, falls du sie nutzt, und auch die sind meist klein. Das ist die seltene selbst gehostete App, bei der die Dimensionierung überhaupt nicht der begrenzende Faktor ist — sondern HTTPS richtig hinzubekommen.
The data volume holds more than a database, and all of it needs to leave the machine together.Das Datenvolume enthält mehr als nur eine Datenbank, und all das muss gemeinsam die Maschine verlassen.
db.sqlite3) — accounts, encrypted vault items, organizations;die SQLite-Datenbank (db.sqlite3) — Konten, verschlüsselte Tresor-Einträge, Organisationen;rsa_key.pem, rsa_key.pub.pem) that Vaultwarden generates on first boot and uses to sign authentication tokens — lose it and every existing client session invalidates, forcing a re-login everywhere, though the vault data itself is still readable.das RSA-Schlüsselpaar (rsa_key.pem, rsa_key.pub.pem), das Vaultwarden beim ersten Start erzeugt und mit dem es Authentifizierungs-Token signiert — verlierst du es, werden alle bestehenden Client-Sitzungen ungültig und erzwingen überall eine erneute Anmeldung, wobei die Tresordaten selbst weiterhin lesbar bleiben.All three live under /data inside the container, so a volume-level copy catches everything in one pass — but stop the container first. db.sqlite3 is a live database while Vaultwarden runs, and a raw copy taken mid-write can land on a torn, inconsistent snapshot; a few seconds of downtime is cheap insurance against a backup that turns out useless the day you need it.Alle drei liegen im Container unter /data, sodass eine Kopie auf Volume-Ebene alles in einem Durchgang erfasst — aber stoppe zuerst den Container. db.sqlite3 ist eine laufende Datenbank, solange Vaultwarden läuft, und eine rohe Kopie mitten im Schreibvorgang kann auf einem zerrissenen, inkonsistenten Stand landen; ein paar Sekunden Ausfallzeit sind eine günstige Versicherung gegen ein Backup, das sich genau an dem Tag als nutzlos erweist, an dem du es brauchst.
docker compose stop vaultwarden
docker run --rm \
-v vw-data:/data:ro \
-v "$PWD":/backup \
alpine:3.20 tar czf /backup/vaultwarden-$(date +%F).tar.gz -C /data .
docker compose start vaultwarden
Run it on a schedule and copy the result off the VPS entirely — a tarball sitting next to the volume it came from does not survive the disk it is on failing. back up your VPS is our own write-up of what off-machine backup actually means in practice, on any provider.Führe das nach Zeitplan aus und kopiere das Ergebnis vollständig vom VPS herunter — ein Tarball, der neben dem Volume liegt, aus dem er stammt, übersteht den Ausfall der Festplatte nicht, auf der er liegt. Backup deines VPS ist unser eigener Leitfaden dazu, was Backup abseits der Maschine in der Praxis tatsächlich bedeutet, bei jedem Anbieter.
docker compose pull
docker compose up -d
Bump the pinned tag deliberately rather than tracking latest, and skim the release notes first — Vaultwarden documents schema migrations and any breaking environment-variable changes per release, and they run automatically against your SQLite file on the next start. Take the backup above immediately before an update on a vault you cannot afford to lose; a failed migration is rare, but a vault is exactly the file you do not want to find that out about the hard way.Hebe den gepinnten Tag bewusst an, statt latest zu verfolgen, und überflieg vorher die Release Notes — Vaultwarden dokumentiert Schemamigrationen und alle rückwärtsinkompatiblen Änderungen an Umgebungsvariablen pro Release, und sie laufen beim nächsten Start automatisch gegen deine SQLite-Datei. Erstelle unmittelbar vor einem Update das Backup von oben, wenn du es dir nicht leisten kannst, einen Tresor zu verlieren; eine fehlgeschlagene Migration ist selten, aber ein Tresor ist genau die Datei, bei der du das nicht auf die harte Tour herausfinden willst.
Full disclosure: this is what we sell. If you want the app without the sysadmin, the managed Vaultwarden container comes with its own hostname and certificate — you get the app and a URL, not a root shell.Zur vollen Transparenz: Das ist, was wir verkaufen. Willst du die App ohne die Systemadministration, kommt der gemanagte Vaultwarden-Container mit eigenem Hostnamen und Zertifikat — du bekommst die App und eine URL, keine Root-Shell.
One-click apps — EUR 4 to EUR 12 a month, hosted in Germany (EU). Eight apps: n8n, Uptime Kuma, Vaultwarden, Gitea, Nextcloud, Ghost, Managed WordPress, Private AI Chat. Each customer gets an isolated Docker network and volume, plus a hostname under apps.overnight.host on a real wildcard certificate. Memory and CPU are capped per plan by the container runtime.One-Click-Apps — 4 bis 12 EUR im Monat, gehostet in Deutschland (EU). Acht Apps: n8n, Uptime Kuma, Vaultwarden, Gitea, Nextcloud, Ghost, Managed WordPress, Private AI Chat. Jeder Kunde bekommt ein isoliertes Docker-Netzwerk und -Volume sowie einen Hostnamen unter apps.overnight.host mit einem echten Wildcard-Zertifikat. Arbeitsspeicher und CPU sind je Plan durch die Container-Runtime gedeckelt.
You order in the shop, pay by card (Stripe) or SEPA bank transfer, and your login details are e-mailed to you once the service is set up. Support is e-mail, run by one person, with no guaranteed response time. All prices are final totals under the German small-business rule (§19 UStG); no VAT is added or shown.Du bestellst im Shop, zahlst per Karte (Stripe) oder SEPA-Überweisung, und deine Zugangsdaten werden dir per E-Mail zugeschickt, sobald der Dienst eingerichtet ist. Support läuft per E-Mail, von einer einzelnen Person betrieben, ohne garantierte Reaktionszeit. Alle Preise sind Endpreise. Gemäß § 19 UStG wird keine Umsatzsteuer ausgewiesen.
Order one-click-vaultwarden → · One-click apps overviewOne-Click-Vaultwarden bestellen → · Übersicht One-Click-Apps
Written by the person who runs overnight.host: a small, honest hosting company on dedicated bare metal — Linux VPS, game servers, web hosting. Live status at up.overnight.host.Geschrieben von der Person, die overnight.host betreibt: ein kleines, ehrliches Hosting-Unternehmen auf dedizierter Bare-Metal-Hardware — Linux-VPS, Gameserver, Webhosting. Live-Status unter up.overnight.host.
Only from localhost, because that is the one address every Bitwarden client also treats as trusted. Anything reached over a network — your phone, a different machine, even another device on your own LAN — needs real HTTPS before the clients will accept the server URL: the web vault is blocked by its own browser's mixed-content rules, and the mobile app and extension refuse a non-HTTPS, non-localhost URL by their own validation regardless of what the browser would allow.Nur von localhost aus, denn das ist die eine Adresse, die jeder Bitwarden-Client ebenfalls als vertrauenswürdig behandelt. Alles, was über ein Netzwerk erreicht wird — dein Handy, eine andere Maschine, sogar ein anderes Gerät in deinem eigenen LAN — braucht echtes HTTPS, bevor die Clients die Server-URL akzeptieren: Der Web-Tresor wird durch die Mixed-Content-Regeln seines eigenen Browsers blockiert, und die mobile App und die Erweiterung lehnen eine URL ohne HTTPS und ohne localhost durch ihre eigene Prüfung ab, unabhängig davon, was der Browser erlauben würde.
No. A forwarded port for 443 works fine, and if you were not given one, running HTTPS on a non-standard port and putting that port in the client's server URL works exactly as well. A dedicated IPv4 is only for when you want the standard port without any of that, and on our plans it is arranged by e-mail rather than self-service.Nein. Ein weitergeleiteter Port für 443 funktioniert einwandfrei, und wenn dir keiner zugeteilt wurde, funktioniert es genauso gut, HTTPS auf einem nicht standardmäßigen Port laufen zu lassen und diesen Port in die Server-URL des Clients einzutragen. Eine dedizierte IPv4 lohnt sich nur, wenn du den Standard-Port ohne all das willst, und bei unseren Plänen wird das per E-Mail statt per Self-Service arrangiert.
It implements the same client-side encryption model — your vault is encrypted and decrypted on your device, and the server only ever stores ciphertext — so a compromise of the server does not hand over readable vault contents either way. What differs is who wrote and maintains the server code: Vaultwarden is an independent, community-maintained reimplementation, not Bitwarden's own software.Es setzt dasselbe clientseitige Verschlüsselungsmodell um — dein Tresor wird auf deinem Gerät ver- und entschlüsselt, und der Server speichert immer nur Chiffretext — sodass eine kompromittierte Serverinstanz in beiden Fällen keine lesbaren Tresorinhalte preisgibt. Der Unterschied liegt darin, wer den Servercode schreibt und pflegt: Vaultwarden ist eine unabhängige, von der Community gepflegte Neuimplementierung, nicht Bitwardens eigene Software.
Every client gets logged out and has to re-authenticate, because the tokens they were holding were signed with a key that no longer exists. Your vault data is unaffected — it is encrypted with your own master password, not with that key pair — but it is still a bad afternoon, which is why the key pair is one of the three things backed up above, not an afterthought.Jeder Client wird abgemeldet und muss sich neu authentifizieren, weil die Token, die er hatte, mit einem Schlüssel signiert wurden, den es nicht mehr gibt. Deine Tresordaten sind davon nicht betroffen — sie sind mit deinem eigenen Master-Passwort verschlüsselt, nicht mit diesem Schlüsselpaar —, aber es ist trotzdem ein unangenehmer Nachmittag, weshalb das Schlüsselpaar eines der drei oben gesicherten Dinge ist und kein Nachgedanke.
You do not need to. Existing accounts can send invitations while SIGNUPS_ALLOWED stays false, so a new household member gets in without the vault being open to anyone who finds the URL in between.Das musst du nicht. Bestehende Konten können Einladungen verschicken, während SIGNUPS_ALLOWED auf false bleibt, sodass ein neues Haushaltsmitglied Zugang bekommt, ohne dass der Tresor zwischenzeitlich für jeden offen wäre, der die URL findet.
Prices are final totals; no VAT is shown (§19 UStG). Need something the shop does not list? Email us for a written offer.Alle Preise sind Endpreise ohne ausgewiesene USt. (§19 UStG). Du brauchst etwas, das nicht im Shop steht? Schreib uns für ein schriftliches Angebot.
Order now →Jetzt bestellen → Request a custom configIndividuelle Konfiguration anfragen