# services/finance/actual-budget-deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: actual-budget namespace: finance labels: app: actual-budget spec: replicas: 1 selector: matchLabels: app: actual-budget strategy: type: RollingUpdate rollingUpdate: maxSurge: 0 maxUnavailable: 1 template: metadata: labels: app: actual-budget annotations: vault.hashicorp.com/agent-inject: "true" vault.hashicorp.com/agent-pre-populate-only: "true" vault.hashicorp.com/agent-init-first: "true" vault.hashicorp.com/role: "finance" vault.hashicorp.com/agent-inject-secret-actual-env.sh: "kv/data/atlas/finance/actual-oidc" vault.hashicorp.com/agent-inject-template-actual-env.sh: | {{ with secret "kv/data/atlas/finance/actual-oidc" }} export ACTUAL_OPENID_CLIENT_ID="{{ .Data.data.ACTUAL_OPENID_CLIENT_ID }}" export ACTUAL_OPENID_CLIENT_SECRET="{{ .Data.data.ACTUAL_OPENID_CLIENT_SECRET }}" {{ end }} actual.bstein.dev/bootstrap-rev: "2" spec: serviceAccountName: finance-vault nodeSelector: kubernetes.io/arch: arm64 node-role.kubernetes.io/worker: "true" affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 preference: matchExpressions: - key: hardware operator: In values: ["rpi5"] - weight: 70 preference: matchExpressions: - key: hardware operator: In values: ["rpi4"] securityContext: runAsUser: 1000 runAsGroup: 1000 fsGroup: 1000 fsGroupChangePolicy: OnRootMismatch initContainers: - name: init-data-permissions image: docker.io/alpine:3.20 command: ["/bin/sh", "-c"] args: - | set -e mkdir -p /data /data/server-files /data/user-files chown -R 1000:1000 /data securityContext: runAsUser: 0 runAsGroup: 0 volumeMounts: - name: actual-data mountPath: /data - name: init-openid image: actualbudget/actual-server:26.1.0-alpine@sha256:34aae5813fdfee12af2a50c4d0667df68029f1d61b90f45f282473273eb70d0d command: ["/bin/sh", "-c"] args: - | set -eu . /vault/secrets/actual-env.sh node /app/src/scripts/run-migrations.js node /scripts/actual_openid_bootstrap.mjs env: - name: ACTUAL_DATA_DIR value: /data - name: ACTUAL_LOGIN_METHOD value: openid - name: ACTUAL_ALLOWED_LOGIN_METHODS value: openid - name: ACTUAL_MULTIUSER value: "true" - name: ACTUAL_OPENID_DISCOVERY_URL value: https://sso.bstein.dev/realms/atlas - name: ACTUAL_OPENID_AUTHORIZATION_ENDPOINT value: https://sso.bstein.dev/realms/atlas/protocol/openid-connect/auth - name: ACTUAL_OPENID_TOKEN_ENDPOINT value: https://sso.bstein.dev/realms/atlas/protocol/openid-connect/token - name: ACTUAL_OPENID_USERINFO_ENDPOINT value: https://sso.bstein.dev/realms/atlas/protocol/openid-connect/userinfo - name: ACTUAL_OPENID_PROVIDER_NAME value: Atlas SSO - name: ACTUAL_OPENID_SERVER_HOSTNAME value: https://budget.bstein.dev volumeMounts: - name: actual-data mountPath: /data - name: actual-openid-bootstrap-script mountPath: /scripts readOnly: true containers: - name: actual-budget image: actualbudget/actual-server:26.1.0-alpine@sha256:34aae5813fdfee12af2a50c4d0667df68029f1d61b90f45f282473273eb70d0d command: ["/bin/sh", "-c"] args: - | . /vault/secrets/actual-env.sh exec node app ports: - name: http containerPort: 5006 env: - name: ACTUAL_DATA_DIR value: /data - name: ACTUAL_LOGIN_METHOD value: openid - name: ACTUAL_ALLOWED_LOGIN_METHODS value: openid - name: ACTUAL_MULTIUSER value: "true" - name: ACTUAL_OPENID_DISCOVERY_URL value: https://sso.bstein.dev/realms/atlas - name: ACTUAL_OPENID_AUTHORIZATION_ENDPOINT value: https://sso.bstein.dev/realms/atlas/protocol/openid-connect/auth - name: ACTUAL_OPENID_TOKEN_ENDPOINT value: https://sso.bstein.dev/realms/atlas/protocol/openid-connect/token - name: ACTUAL_OPENID_USERINFO_ENDPOINT value: https://sso.bstein.dev/realms/atlas/protocol/openid-connect/userinfo - name: ACTUAL_OPENID_PROVIDER_NAME value: Atlas SSO - name: ACTUAL_OPENID_SERVER_HOSTNAME value: https://budget.bstein.dev volumeMounts: - name: actual-data mountPath: /data readinessProbe: httpGet: path: /health port: http initialDelaySeconds: 10 periodSeconds: 10 timeoutSeconds: 3 failureThreshold: 6 livenessProbe: httpGet: path: /health port: http initialDelaySeconds: 30 periodSeconds: 20 timeoutSeconds: 3 failureThreshold: 6 resources: requests: cpu: 200m memory: 512Mi limits: cpu: "1" memory: 1Gi volumes: - name: actual-data persistentVolumeClaim: claimName: actual-budget-data-encrypted - name: actual-openid-bootstrap-script configMap: name: actual-openid-bootstrap-script defaultMode: 0555