From 94be854bd7354afb7d7085fe6a08452e34d7cb2b Mon Sep 17 00:00:00 2001 From: "Dustin C. Hatch" Date: Fri, 10 Jan 2025 19:50:05 -0600 Subject: [PATCH] vaultwarden: Deploy, migrate Vaultwarden Vaultwarden requires basically no configuration anymore. Older versions needed some environment variables for configuring the WebSocket server, but as of 1.31, WebSockets are handled by the same server as HTTP, so even that is not necessary now. The only other option that could potentially be useful is `ADMIN_TOKEN`, but it's optional. For added security, we can leave it unset, which disables the administration console; we can set it later if/when we actually need that feature. Migrating data from the old server was pretty simple. The database is pretty small, and even the attachments and site icons don't take up much space. All-in-all, there was only about 20 MB to move, so the copy only took a few seconds. Aside from moving the Vaultwarden server itself, we will also need to adjust the HAProxy configuration to proxy requests to the Kubernetes ingress controller. --- argocd/applications/vaultwarden.yaml | 16 +++++ updatebot/config.yml | 10 +++ vaultwarden/README.md | 15 +++++ vaultwarden/ingress.yaml | 20 ++++++ vaultwarden/kustomization.yaml | 30 +++++++++ vaultwarden/migrate.yaml | 34 ++++++++++ vaultwarden/namespace.yaml | 4 ++ vaultwarden/vaultwarden.env | 1 + vaultwarden/vaultwarden.yaml | 95 ++++++++++++++++++++++++++++ 9 files changed, 225 insertions(+) create mode 100644 argocd/applications/vaultwarden.yaml create mode 100644 vaultwarden/README.md create mode 100644 vaultwarden/ingress.yaml create mode 100644 vaultwarden/kustomization.yaml create mode 100644 vaultwarden/migrate.yaml create mode 100644 vaultwarden/namespace.yaml create mode 100644 vaultwarden/vaultwarden.env create mode 100644 vaultwarden/vaultwarden.yaml diff --git a/argocd/applications/vaultwarden.yaml b/argocd/applications/vaultwarden.yaml new file mode 100644 index 0000000..aa07a6a --- /dev/null +++ b/argocd/applications/vaultwarden.yaml @@ -0,0 +1,16 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: vaultwarden + namespace: argocd +spec: + destination: + server: https://kubernetes.default.svc + project: default + source: + path: vaultwarden + repoURL: https://git.pyrocufflink.blue/infra/kubernetes.git + targetRevision: master + syncPolicy: + automated: + prune: true diff --git a/updatebot/config.yml b/updatebot/config.yml index 6d8e02e..f956eb7 100644 --- a/updatebot/config.yml +++ b/updatebot/config.yml @@ -96,3 +96,13 @@ projects: kind: github organization: authelia repo: authelia + +- name: vaultwarden + kind: kustomize + images: + - name: authelia + image: ghcr.io/dani-garcia/vaultwarden + source: + kind: github + organization: dani-garcia + repo: vaultwarden diff --git a/vaultwarden/README.md b/vaultwarden/README.md new file mode 100644 index 0000000..d081cdd --- /dev/null +++ b/vaultwarden/README.md @@ -0,0 +1,15 @@ +# Vaultwarden (Bitwarden-rs) + +## Migration + +```sh +kubectl scale statefulset -n vaultwarden vaultwarden --replicas 0 +kubectl create -f vaultwarden/migrate.yaml +kubectl exec -n vaultwarden vaultwarden-migration -- find /data -mindepth 1 -delete +ssh bw0 sudo systemctl stop vaultwarden +ssh bw0 sudo tar -C /var/lib/vaultwarden/data -c . \ + | pv \ + | kubectl exec -n vaultwarden -i vaultwarden-migration -- tar -C /data -x +kubectl delete pod -n vaultwarden vaultwarden-migration +kubectl scale statefulset -n vaultwarden vaultwarden --replicas 1 +``` diff --git a/vaultwarden/ingress.yaml b/vaultwarden/ingress.yaml new file mode 100644 index 0000000..b719b32 --- /dev/null +++ b/vaultwarden/ingress.yaml @@ -0,0 +1,20 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: vaultwarden + labels: + app.kubernetes.io/name: vaultwarden + app.kubernetes.io/component: vaultwarden +spec: + ingressClassName: nginx + rules: + - host: bitwarden.pyrocufflink.net + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: vaultwarden + port: + name: http diff --git a/vaultwarden/kustomization.yaml b/vaultwarden/kustomization.yaml new file mode 100644 index 0000000..f514407 --- /dev/null +++ b/vaultwarden/kustomization.yaml @@ -0,0 +1,30 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +namespace: vaultwarden + +labels: +- pairs: + app.kubernetes.io/instance: vaultwarden + includeSelectors: true +- pairs: + app.kubernetes.io/part-of: vaultwarden + includeTemplates: true + +resources: +- namespace.yaml +- vaultwarden.yaml +- ingress.yaml + +configMapGenerator: +- name: vaultwarden + envs: + - vaultwarden.env + options: + labels: + app.kubernetes.io/name: vaultwarden + app.kubernetes.io/component: vaultwarden + +images: +- name: ghcr.io/dani-garcia/vaultwarden + newTag: 1.32.7-alpine diff --git a/vaultwarden/migrate.yaml b/vaultwarden/migrate.yaml new file mode 100644 index 0000000..b27c00e --- /dev/null +++ b/vaultwarden/migrate.yaml @@ -0,0 +1,34 @@ +apiVersion: v1 +kind: Pod +metadata: + name: vaultwarden-migration + namespace: vaultwarden + labels: &labels + app.kubernetes.io/name: vaultwarden + app.kubernetes.io/component: migration +spec: + containers: + - name: migration + image: busybox + command: + - sh + - -c + - | + trap 'kill $!' TERM + sleep 99999 & + wait + securityContext: + readOnlyRootFilesystem: true + volumeMounts: + - mountPath: /data + name: data + subPath: data + securityContext: + runAsUser: 266 + runAsGroup: 266 + fsGroup: 266 + fsGroupChangePolicy: OnRootMismatch + volumes: + - name: data + persistentVolumeClaim: + claimName: vaultwarden diff --git a/vaultwarden/namespace.yaml b/vaultwarden/namespace.yaml new file mode 100644 index 0000000..6fc17a5 --- /dev/null +++ b/vaultwarden/namespace.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: vaultwarden diff --git a/vaultwarden/vaultwarden.env b/vaultwarden/vaultwarden.env new file mode 100644 index 0000000..f092b8e --- /dev/null +++ b/vaultwarden/vaultwarden.env @@ -0,0 +1 @@ +DOMAIN=https://bitwarden.pyrocufflink.net diff --git a/vaultwarden/vaultwarden.yaml b/vaultwarden/vaultwarden.yaml new file mode 100644 index 0000000..06d52ac --- /dev/null +++ b/vaultwarden/vaultwarden.yaml @@ -0,0 +1,95 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: vaultwarden + labels: + app.kubernetes.io/name: vaultwarden + app.kubernetes.io/component: vaultwarden +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 4Gi + +--- +apiVersion: v1 +kind: Service +metadata: + name: vaultwarden + labels: &labels + app.kubernetes.io/name: vaultwarden + app.kubernetes.io/component: vaultwarden +spec: + selector: *labels + ports: + - port: 8080 + targetPort: http + name: http + +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: vaultwarden + labels: &labels + app.kubernetes.io/name: vaultwarden + app.kubernetes.io/component: vaultwarden +spec: + serviceName: vaultwarden + selector: + matchLabels: *labels + template: + metadata: + labels: *labels + spec: + containers: + - name: vaultwarden + image: ghcr.io/dani-garcia/vaultwarden + env: + - name: ROCKET_PORT + value: '8080' + envFrom: + - configMapRef: + name: vaultwarden + optional: true + - secretRef: + name: vaultwarden + optional: true + ports: + - name: http + containerPort: 8080 + readinessProbe: &probe + httpGet: + port: http + path: /alive + failureThreshold: 1 + periodSeconds: 60 + timeoutSeconds: 5 + startupProbe: + <<: *probe + failureThreshold: 60 + initialDelaySeconds: 2 + periodSeconds: 1 + timeoutSeconds: 1 + securityContext: + readOnlyRootFilesystem: true + volumeMounts: + - mountPath: /data + name: data + subPath: data + - mountPath: /tmp + name: tmp + subPath: tmp + securityContext: + runAsUser: 266 + runAsGroup: 266 + fsGroup: 266 + fsGroupChangePolicy: OnRootMismatch + volumes: + - name: data + persistentVolumeClaim: + claimName: vaultwarden + - name: tmp + emptyDir: + medium: Memory