Deploy Vaultwarden on Thalassa Cloud Kubernetes
Vaultwarden is a lightweight, self-hosted alternative to Bitwarden that provides secure password management with end-to-end encryption. By deploying Vaultwarden on Thalassa Cloud Kubernetes, a European cloud platform, you can run a production-ready password manager with full data sovereignty, ensuring your sensitive credentials remain under your control, hosted within the European Union, and comply with EU privacy regulations like GDPR.
This guide walks you through deploying Vaultwarden using Kubernetes manifests, configuring persistent storage, and setting up ingress with TLS certificates.
Prerequisites
Before deploying Vaultwarden, ensure you have a few things in place. First, you need a running Kubernetes cluster in Thalassa Cloud. If you’re new to Thalassa Cloud Kubernetes, see the Getting Started guide for cluster creation and basic setup.
- You’ll also need cluster access configured using
kubectl. Usetcloud kubernetes connectto configure access, or set up kubeconfig manually. You’ll need cluster administrator permissions to create namespaces and deploy resources. - For TLS certificates, you’ll need Cert Manager installed with Let’s Encrypt configured. See the Cert Manager and Let’s Encrypt guide for installation and configuration instructions.
- Finally, ensure your cluster has sufficient resources. Vaultwarden is lightweight but requires persistent storage for the database. Plan for at least one node with adequate resources. For information about storage options, see the Storage documentation and Persistent Volumes documentation.
Understanding Vaultwarden on Kubernetes
Vaultwarden is a Rust implementation of the Bitwarden server API that is compatible with all Bitwarden clients (desktop, mobile, browser extensions). It uses SQLite by default, making it simple to deploy without requiring a separate database. On Kubernetes, Vaultwarden benefits from persistent storage, automatic restarts, and easy scaling.
Vaultwarden stores all data encrypted at rest and in transit. The encryption keys are managed by the Bitwarden clients, ensuring that even if the server is compromised, your passwords remain encrypted. This makes it ideal for organisations requiring data sovereignty and compliance with privacy regulations.
Deploying Vaultwarden
Step 1: Create Namespace
Create a namespace for Vaultwarden resources with pod security labels:
apiVersion: v1
kind: Namespace
metadata:
name: vaultwarden
labels:
pod-security.kubernetes.io/enforce: baseline
pod-security.kubernetes.io/warn: restrictedApply the namespace:
kubectl apply -f namespace.yamlStep 2: Create PersistentVolumeClaim
Vaultwarden requires persistent storage for its SQLite database. Create a PersistentVolumeClaim:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: vaultwarden-data
namespace: vaultwarden
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: tc-blockApply the PersistentVolumeClaim:
kubectl apply -f pvc.yamlStep 3: Create Configuration Secret
Create a Kubernetes Secret for Vaultwarden configuration. Generate a strong admin token:
openssl rand -base64 32Create the secret:
apiVersion: v1
kind: Secret
metadata:
name: vaultwarden-config
namespace: vaultwarden
type: Opaque
stringData:
ADMIN_TOKEN: "your-generated-admin-token-here"
SIGNUPS_ALLOWED: "true"
DOMAIN: "https://vaultwarden.yourdomain.com"Security Configuration
- Use a strong, randomly generated admin token
- Set
SIGNUPS_ALLOWEDtofalsein production after creating your account - Configure
DOMAINwith your actual domain for proper client configuration
Apply the secret:
kubectl apply -f secret.yamlStep 4: Deploy Vaultwarden
Create a Deployment for Vaultwarden:
apiVersion: apps/v1
kind: Deployment
metadata:
name: vaultwarden
namespace: vaultwarden
labels:
app: vaultwarden
spec:
replicas: 1
selector:
matchLabels:
app: vaultwarden
template:
metadata:
labels:
app: vaultwarden
spec:
containers:
- name: vaultwarden
image: vaultwarden/server:latest
ports:
- containerPort: 80
name: http
env:
- name: ADMIN_TOKEN
valueFrom:
secretKeyRef:
name: vaultwarden-config
key: ADMIN_TOKEN
- name: SIGNUPS_ALLOWED
valueFrom:
secretKeyRef:
name: vaultwarden-config
key: SIGNUPS_ALLOWED
- name: DOMAIN
valueFrom:
secretKeyRef:
name: vaultwarden-config
key: DOMAIN
- name: ROCKET_PORT
value: "80"
- name: DATA_FOLDER
value: "/data"
volumeMounts:
- name: data
mountPath: /data
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 10
periodSeconds: 5
volumes:
- name: data
persistentVolumeClaim:
claimName: vaultwarden-dataApply the Deployment:
kubectl apply -f deployment.yamlStep 5: Create Service
Create a Service to expose Vaultwarden:
apiVersion: v1
kind: Service
metadata:
name: vaultwarden
namespace: vaultwarden
spec:
selector:
app: vaultwarden
ports:
- port: 80
targetPort: 80
protocol: TCP
name: http
type: ClusterIPApply the Service:
kubectl apply -f service.yamlStep 6: Configure Ingress with TLS
Create an Ingress resource with TLS configuration. This assumes Cert Manager is installed and configured:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: vaultwarden
namespace: vaultwarden
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/proxy-body-size: "128m"
spec:
ingressClassName: nginx
tls:
- hosts:
- vaultwarden.yourdomain.com
secretName: vaultwarden-tls
rules:
- host: vaultwarden.yourdomain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: vaultwarden
port:
number: 80Ingress Controller
This example uses NGINX ingress controller. Adjust the ingressClassName and annotations based on your ingress controller configuration.
Apply the Ingress:
kubectl apply -f ingress.yamlAccessing Vaultwarden
After deployment, access Vaultwarden through your configured domain. The admin panel is available at /admin using the admin token you configured.
Initial Setup
- Access Vaultwarden at
https://vaultwarden.yourdomain.com - Create your first account (if
SIGNUPS_ALLOWEDistrue) - After creating your account, set
SIGNUPS_ALLOWEDtofalsein the secret and restart the deployment - Access the admin panel at
https://vaultwarden.yourdomain.com/adminusing your admin token
Client Configuration
Vaultwarden is compatible with all Bitwarden clients. Configure clients to use your self-hosted instance:
- Desktop/Mobile Apps: In settings, change the server URL to
https://vaultwarden.yourdomain.com - Browser Extensions: In extension settings, set the server URL to your domain
Backup and Recovery
Vaultwarden stores all data in a SQLite database. To back up:
# Create a backup
kubectl exec -n vaultwarden deployment/vaultwarden -- \
sqlite3 /data/db.sqlite3 ".backup /data/backup-$(date +%Y%m%d).db"
# Copy backup from pod
kubectl cp vaultwarden/vaultwarden-<pod-name>:/data/backup-20240115.db ./backup.dbFor automated backups, consider using a CronJob or integrating with Thalassa Cloud’s snapshot capabilities for the persistent volume.
References
- Vaultwarden GitHub Repository — Official Vaultwarden documentation
- Bitwarden Client Documentation — Client configuration guides
- Persistent Volumes Documentation — Storage configuration
- Cert Manager Guide — TLS certificate management