From 055491681853b001d80517432e0e5e583d18b867 Mon Sep 17 00:00:00 2001 From: Paul Payne Date: Fri, 19 Jun 2026 21:33:30 +0000 Subject: [PATCH] Adds vaultwarden app. --- vaultwarden/app.yaml | 5 ++ vaultwarden/versions/1/README.md | 42 ++++++++++ vaultwarden/versions/1/db-init-job.yaml | 59 ++++++++++++++ vaultwarden/versions/1/deployment.yaml | 96 +++++++++++++++++++++++ vaultwarden/versions/1/ingress.yaml | 26 ++++++ vaultwarden/versions/1/kustomization.yaml | 16 ++++ vaultwarden/versions/1/manifest.yaml | 30 +++++++ vaultwarden/versions/1/namespace.yaml | 4 + vaultwarden/versions/1/pvc.yaml | 11 +++ vaultwarden/versions/1/service.yaml | 13 +++ 10 files changed, 302 insertions(+) create mode 100644 vaultwarden/app.yaml create mode 100644 vaultwarden/versions/1/README.md create mode 100644 vaultwarden/versions/1/db-init-job.yaml create mode 100644 vaultwarden/versions/1/deployment.yaml create mode 100644 vaultwarden/versions/1/ingress.yaml create mode 100644 vaultwarden/versions/1/kustomization.yaml create mode 100644 vaultwarden/versions/1/manifest.yaml create mode 100644 vaultwarden/versions/1/namespace.yaml create mode 100644 vaultwarden/versions/1/pvc.yaml create mode 100644 vaultwarden/versions/1/service.yaml diff --git a/vaultwarden/app.yaml b/vaultwarden/app.yaml new file mode 100644 index 0000000..97b141e --- /dev/null +++ b/vaultwarden/app.yaml @@ -0,0 +1,5 @@ +name: vaultwarden +is: vaultwarden +description: Vaultwarden is a lightweight, self-hosted Bitwarden-compatible password manager server written in Rust. +icon: https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/vaultwarden.svg +latest: "1" diff --git a/vaultwarden/versions/1/README.md b/vaultwarden/versions/1/README.md new file mode 100644 index 0000000..a74cecd --- /dev/null +++ b/vaultwarden/versions/1/README.md @@ -0,0 +1,42 @@ +# Vaultwarden + +Vaultwarden is a lightweight, self-hosted Bitwarden-compatible password manager server. It's compatible with all official Bitwarden clients (browser extensions, desktop apps, mobile apps). + +## Dependencies + +- **PostgreSQL** - Database for storing vault data +- **SMTP** - For sending verification emails and emergency access notifications + +## Configuration + +Key settings in `config.yaml`: + +- **domain** - Where Vaultwarden will be accessible (required for client connections) +- **signupsAllowed** - Whether new users can self-register (`"true"` or `"false"`) +- **storage** - Persistent volume size for attachments and icons (default: `1Gi`) +- **smtp** - Email settings inherited from your Wild Cloud SMTP service + +## First-Time Setup + +1. Add and deploy the app: + ```bash + wild app add vaultwarden + wild app deploy vaultwarden + ``` + +2. Register your admin account by visiting the app URL and clicking **Create Account**. + +3. Log in to the **admin panel** at `/admin` using the `adminToken` from your `secrets.yaml`. From here you can: + - Disable signups so no other users can self-register + - Invite specific users by email + - View server diagnostics + +4. Install the **Bitwarden client** (browser extension, desktop app, or mobile app), then set the server URL to your Vaultwarden domain before logging in. + +## Notes + +- Vaultwarden is fully compatible with the official Bitwarden clients — set your server URL in the client settings before creating an account +- The `adminToken` secret is the password for the `/admin` panel — treat it like a root password +- Set `signupsAllowed: "false"` in your config after creating your account to prevent others from registering +- Attachments and icons are stored on the persistent volume; back it up along with your PostgreSQL database +- TOTP (authenticator app) two-factor authentication works out of the box; email-based 2FA requires SMTP diff --git a/vaultwarden/versions/1/db-init-job.yaml b/vaultwarden/versions/1/db-init-job.yaml new file mode 100644 index 0000000..17d5416 --- /dev/null +++ b/vaultwarden/versions/1/db-init-job.yaml @@ -0,0 +1,59 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: vaultwarden-db-init + labels: + component: db-init +spec: + template: + metadata: + labels: + component: db-init + spec: + restartPolicy: OnFailure + securityContext: + runAsNonRoot: true + runAsUser: 999 + runAsGroup: 999 + seccompProfile: + type: RuntimeDefault + containers: + - name: postgres-init + image: postgres:15 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: false + env: + - name: PGHOST + value: {{ .db.host }} + - name: PGUSER + value: postgres + - name: PGPASSWORD + valueFrom: + secretKeyRef: + name: vaultwarden-secrets + key: postgres.password + - name: DB_NAME + value: {{ .db.name }} + - name: DB_USER + value: {{ .db.user }} + - name: DB_PASSWORD + valueFrom: + secretKeyRef: + name: vaultwarden-secrets + key: dbPassword + command: + - /bin/bash + - -c + - | + set -e + until pg_isready; do sleep 2; done + psql -c "CREATE DATABASE ${DB_NAME};" || echo "Database already exists" + psql -c "CREATE USER ${DB_USER} WITH PASSWORD '${DB_PASSWORD}';" || echo "User already exists" + psql -c "ALTER USER ${DB_USER} WITH PASSWORD '${DB_PASSWORD}';" + psql -c "GRANT ALL PRIVILEGES ON DATABASE ${DB_NAME} TO ${DB_USER};" + psql -d ${DB_NAME} -c "GRANT ALL ON SCHEMA public TO ${DB_USER};" + echo "Done" diff --git a/vaultwarden/versions/1/deployment.yaml b/vaultwarden/versions/1/deployment.yaml new file mode 100644 index 0000000..94a1001 --- /dev/null +++ b/vaultwarden/versions/1/deployment.yaml @@ -0,0 +1,96 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: vaultwarden + namespace: {{ .namespace }} +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + component: web + template: + metadata: + labels: + component: web + spec: + securityContext: + runAsNonRoot: false + runAsUser: 0 + seccompProfile: + type: RuntimeDefault + containers: + - name: vaultwarden + image: vaultwarden/server:1.36.0 + ports: + - name: http + containerPort: 80 + protocol: TCP + env: + - name: DATABASE_URL + valueFrom: + secretKeyRef: + name: vaultwarden-secrets + key: dbUrl + - name: DOMAIN + value: "https://{{ .domain }}" + - name: ADMIN_TOKEN + valueFrom: + secretKeyRef: + name: vaultwarden-secrets + key: adminToken + - name: SIGNUPS_ALLOWED + value: "{{ .signupsAllowed }}" + - name: SMTP_HOST + value: "{{ .smtp.host }}" + - name: SMTP_PORT + value: "{{ .smtp.port }}" + - name: SMTP_FROM + value: "{{ .smtp.from }}" + - name: SMTP_USERNAME + value: "{{ .smtp.user }}" + - name: SMTP_PASSWORD + valueFrom: + secretKeyRef: + name: vaultwarden-secrets + key: smtp.password + - name: SMTP_SECURITY + value: "{{ .smtp.security }}" + - name: ROCKET_PORT + value: "80" + resources: + limits: + cpu: 500m + ephemeral-storage: 1Gi + memory: 256Mi + requests: + cpu: 25m + ephemeral-storage: 50Mi + memory: 64Mi + volumeMounts: + - name: vaultwarden-data + mountPath: /data + livenessProbe: + httpGet: + path: /alive + port: 80 + initialDelaySeconds: 30 + timeoutSeconds: 5 + periodSeconds: 30 + failureThreshold: 6 + readinessProbe: + httpGet: + path: /alive + port: 80 + initialDelaySeconds: 10 + timeoutSeconds: 3 + periodSeconds: 10 + failureThreshold: 3 + securityContext: + readOnlyRootFilesystem: false + volumes: + - name: vaultwarden-data + persistentVolumeClaim: + claimName: vaultwarden-data + restartPolicy: Always diff --git a/vaultwarden/versions/1/ingress.yaml b/vaultwarden/versions/1/ingress.yaml new file mode 100644 index 0000000..927944b --- /dev/null +++ b/vaultwarden/versions/1/ingress.yaml @@ -0,0 +1,26 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: vaultwarden + namespace: {{ .namespace }} + annotations: + external-dns.alpha.kubernetes.io/target: {{ .externalDnsDomain }} + external-dns.alpha.kubernetes.io/cloudflare-proxied: "false" + external-dns.alpha.kubernetes.io/ttl: "60" +spec: + ingressClassName: traefik + rules: + - host: {{ .domain }} + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: vaultwarden + port: + number: 80 + tls: + - hosts: + - {{ .domain }} + secretName: {{ .tlsSecretName }} diff --git a/vaultwarden/versions/1/kustomization.yaml b/vaultwarden/versions/1/kustomization.yaml new file mode 100644 index 0000000..eaf2eb8 --- /dev/null +++ b/vaultwarden/versions/1/kustomization.yaml @@ -0,0 +1,16 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: {{ .namespace }} +labels: + - includeSelectors: true + pairs: + app: vaultwarden + managedBy: kustomize + partOf: wild-cloud +resources: + - namespace.yaml + - db-init-job.yaml + - deployment.yaml + - service.yaml + - ingress.yaml + - pvc.yaml diff --git a/vaultwarden/versions/1/manifest.yaml b/vaultwarden/versions/1/manifest.yaml new file mode 100644 index 0000000..22b226c --- /dev/null +++ b/vaultwarden/versions/1/manifest.yaml @@ -0,0 +1,30 @@ +version: 1.36.0 +requires: + - name: postgres + - name: smtp +defaultConfig: + namespace: vaultwarden + externalDnsDomain: '{{ .cloud.domain }}' + domain: vaultwarden.{{ .cloud.domain }} + tlsSecretName: wildcard-wild-cloud-tls + storage: 1Gi + signupsAllowed: "true" + db: + host: '{{ .apps.postgres.host }}' + port: '{{ .apps.postgres.port }}' + name: vaultwarden + user: vaultwarden + smtp: + host: '{{ .apps.smtp.host }}' + port: '{{ .apps.smtp.port }}' + from: '{{ .apps.smtp.from }}' + user: '{{ .apps.smtp.user }}' + security: starttls +defaultSecrets: + - key: dbPassword + - key: dbUrl + default: "postgresql://{{ .app.db.user }}:{{ .secrets.dbPassword }}@{{ .app.db.host }}:{{ .app.db.port }}/{{ .app.db.name }}?sslmode=disable" + - key: adminToken +requiredSecrets: + - postgres.password + - smtp.password diff --git a/vaultwarden/versions/1/namespace.yaml b/vaultwarden/versions/1/namespace.yaml new file mode 100644 index 0000000..054927e --- /dev/null +++ b/vaultwarden/versions/1/namespace.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: {{ .namespace }} diff --git a/vaultwarden/versions/1/pvc.yaml b/vaultwarden/versions/1/pvc.yaml new file mode 100644 index 0000000..de81e53 --- /dev/null +++ b/vaultwarden/versions/1/pvc.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: vaultwarden-data + namespace: {{ .namespace }} +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .storage }} diff --git a/vaultwarden/versions/1/service.yaml b/vaultwarden/versions/1/service.yaml new file mode 100644 index 0000000..48f9124 --- /dev/null +++ b/vaultwarden/versions/1/service.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Service +metadata: + name: vaultwarden + namespace: {{ .namespace }} +spec: + selector: + component: web + ports: + - name: http + port: 80 + targetPort: 80 + protocol: TCP