Running your own password manager allows you to control the security of your passwords. Here is how I set up Vaultwarden (a Bitwarden-compatible server) on K3s, using just a budget VPS with 1 vCPU and 2GB RAM. Everything works smoothly, and the cost is about $2 a month.
Why Vaultwarden and K3s?
Vaultwarden is what Bitwarden could be if it were built for simplicity and efficiency. It is written in Rust, fully compatible with Bitwarden clients, and skips all the complexity of the official Bitwarden setup. You do not need Docker Compose with ten containers or a ton of memory. Vaultwarden runs as a single binary with barely any dependencies.
K3s, Rancher’s lightweight Kubernetes, fits right in for this kind of deployment. My whole stack runs comfortably on a low-end VPS with Ubuntu 24.04.
The Stack
Here is the main lineup:
- Vaultwarden: Handles all vault operations.
- K3s: The Kubernetes platform, light enough for a single VPS.
- NeonDB: Free managed PostgreSQL in the cloud. (SQLite also works, but Postgres allows you to scale in the future + backups are easier)
- Cloudflare Tunnel: No public IP required. You get DDoS protection and CDN performance at zero cost.
All requests go through Cloudflare, then a secure tunnel, land on your VPS, and finally hit Vaultwarden. Passwords are stored on your VPS disk, and all other metadata sits in NeonDB.
flowchart TD A[Internet] --> B[Cloudflare Tunnel] B --> C[VPS NodePort] C --> D[K3s Service] D --> E[Vaultwarden Pod] E --> F["hostPath Storage<br/>/opt/vaultwarden-data"] E --> G["External Database<br/>(NeonDB PostgreSQL)"]
Storage
For single-node setups, simple is best. I use hostPath volumes so Vaultwarden writes directly to a local folder on the VPS. Backups are as easy as copying that folder. The only tradeoff is that the pod is tied to this node, but in a single-node cluster this is exactly what you want.
Networking
I use a NodePort service. No need for an Ingress controller since Cloudflare handles SSL and all public access. Cloudflare Tunnel means nothing is exposed publicly, and your server’s IP stays private.
The Kubernetes YAML You’ll Use
PersistentVolume
apiVersion: v1
kind: PersistentVolume
metadata:
name: vaultwarden-pv
spec:
capacity:
storage: 2Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
hostPath:
path: /opt/vaultwarden-data
type: DirectoryOrCreate
PersistentVolumeClaim
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: vaultwarden-data
namespace: vaultwarden
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi
storageClassName: ""
selector:
matchLabels:
app: vaultwarden
Secrets
apiVersion: v1
kind: Secret
metadata:
name: vaultwarden-secrets
namespace: vaultwarden
type: Opaque
stringData:
DATABASE_URL: "postgresql://user:[email protected]/vaultwarden?sslmode=require"
DOMAIN: "https://vault.yourdomain.tld"
Deployment
Keep replicas: 1
and use Recreate
as the strategy. Make sure the folder on your VPS is owned by user 1000 and group 1000, which matches Vaultwarden’s container defaults.
Step-by-Step Setup
Prepare the VPS:
sudo mkdir -p /opt/vaultwarden-data sudo chown 1000:1000 /opt/vaultwarden-data sudo chmod 755 /opt/vaultwarden-data
Apply manifests in order:
kubectl apply -f namespace.yaml kubectl apply -f pv.yaml kubectl apply -f pvc.yaml kubectl apply -f secret.yaml kubectl apply -f deployment.yaml kubectl apply -f service.yaml
Check that it’s running:
kubectl get pods -n vaultwarden -w kubectl logs -n vaultwarden deployment/vaultwarden
Maintenance
Update Vaultwarden:
kubectl set image deployment/vaultwarden vaultwarden=vaultwarden/server:1.XX.X -n vaultwarden kubectl rollout status deployment/vaultwarden -n vaultwarden
Monitor:
kubectl get pods -n vaultwarden kubectl top pods -n vaultwarden kubectl logs -n vaultwarden deployment/vaultwarden --tail=50
What Does It Cost?
Item | Monthly Cost |
---|---|
VPS (1vCPU, 2GB) | $1 |
Domain | $1 |
NeonDB | $0 (free tier) |
Cloudflare | $0 |
You get a Bitwarden-compatible setup for about $2 per month.
Final Thoughts
Self-hosting Vaultwarden with K3s is a straightforward project that pays off. You have full control, hardly spend anything, and keep all your passwords in your hands. If you enjoy tech projects and want to own your credentials, this is a fun and practical weekend build.
Comment below if you tried it out!