titan-iac/services/planka/deployment.yaml

154 lines
5.1 KiB
YAML

# services/planka/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: planka
namespace: planka
labels:
app: planka
spec:
replicas: 1
selector:
matchLabels:
app: planka
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 0
maxUnavailable: 1
template:
metadata:
labels:
app: planka
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: "planka"
vault.hashicorp.com/agent-inject-secret-planka-env.sh: "kv/data/atlas/planka/planka-db"
vault.hashicorp.com/agent-inject-template-planka-env.sh: |
{{ with secret "kv/data/atlas/planka/planka-db" }}
export DATABASE_URL="{{ .Data.data.DATABASE_URL }}"
{{ end }}
{{ with secret "kv/data/atlas/planka/planka-secrets" }}
export SECRET_KEY="{{ .Data.data.SECRET_KEY }}"
{{ end }}
{{ with secret "kv/data/atlas/planka/planka-oidc" }}
export OIDC_CLIENT_ID="{{ .Data.data.OIDC_CLIENT_ID }}"
export OIDC_CLIENT_SECRET="{{ .Data.data.OIDC_CLIENT_SECRET }}"
export OIDC_ENFORCED="{{ .Data.data.OIDC_ENFORCED }}"
export OIDC_IGNORE_ROLES="{{ .Data.data.OIDC_IGNORE_ROLES }}"
export OIDC_ISSUER="{{ .Data.data.OIDC_ISSUER }}"
export OIDC_SCOPES="{{ .Data.data.OIDC_SCOPES }}"
export OIDC_USE_OAUTH_CALLBACK="{{ .Data.data.OIDC_USE_OAUTH_CALLBACK }}"
{{ end }}
{{ with secret "kv/data/atlas/planka/planka-smtp" }}
export SMTP_FROM="{{ .Data.data.SMTP_FROM }}"
export SMTP_HOST="{{ .Data.data.SMTP_HOST }}"
export SMTP_PORT="{{ .Data.data.SMTP_PORT }}"
export SMTP_SECURE="{{ .Data.data.SMTP_SECURE }}"
export SMTP_TLS_REJECT_UNAUTHORIZED="{{ .Data.data.SMTP_TLS_REJECT_UNAUTHORIZED }}"
{{ end }}
{{ with secret "kv/data/atlas/shared/postmark-relay" }}
export SMTP_USER="{{ index .Data.data "relay-username" }}"
export SMTP_PASSWORD="{{ index .Data.data "relay-password" }}"
{{ end }}
spec:
serviceAccountName: planka-vault
nodeSelector:
node-role.kubernetes.io/worker: "true"
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: hardware
operator: In
values: ["rpi4", "rpi5"]
securityContext:
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
fsGroupChangePolicy: OnRootMismatch
initContainers:
- name: init-user-data
image: docker.io/alpine:3.20
securityContext:
runAsUser: 0
runAsGroup: 0
command: ["/bin/sh", "-c"]
args:
- |
set -e
mkdir -p /data/public/user-avatars \
/data/public/background-images \
/data/private/attachments
chown -R 1000:1000 /data /tmp-data
volumeMounts:
- name: user-data
mountPath: /data
- name: app-data
mountPath: /tmp-data
containers:
- name: planka
image: ghcr.io/plankanban/planka:2.0.0-rc.4
command:
- /bin/sh
- -c
args:
- . /vault/secrets/planka-env.sh && exec node app.js --prod
ports:
- name: http
containerPort: 1337
env:
- name: BASE_URL
value: https://tasks.bstein.dev
- name: TRUST_PROXY
value: "true"
- name: OIDC_ADMIN_ROLES
value: admin
- name: OIDC_PROJECT_OWNER_ROLES
value: planka-users
- name: OIDC_ROLES_ATTRIBUTE
value: groups
volumeMounts:
- name: user-data
mountPath: /app/public/user-avatars
subPath: public/user-avatars
- name: user-data
mountPath: /app/public/background-images
subPath: public/background-images
- name: user-data
mountPath: /app/private/attachments
subPath: private/attachments
- name: app-data
mountPath: /app/.tmp
readinessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 3
failureThreshold: 6
livenessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 30
periodSeconds: 20
timeoutSeconds: 3
failureThreshold: 6
resources:
requests:
cpu: 200m
memory: 512Mi
limits:
cpu: "1"
memory: 2Gi
volumes:
- name: user-data
persistentVolumeClaim:
claimName: planka-user-data
- name: app-data
persistentVolumeClaim:
claimName: planka-app-data