Add complete Directus configuration and update to v12.1.1

Moved Directus deployment configuration from k8s cluster to Git repository:
- Main Directus deployment updated to v12.1.1
- PostgreSQL deployment (postgres:16-alpine)
- Services for both Directus and PostgreSQL
- Ingress with TLS/cert-manager
- Backup CronJob (daily at 2 AM)
- PVCs for database and uploads

This enables GitOps management via Argo CD.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
CTO Agent 2026-07-25 13:45:47 +00:00
parent 8c66f6c955
commit a309c6873c
8 changed files with 397 additions and 0 deletions

View file

@ -0,0 +1,87 @@
apiVersion: batch/v1
kind: CronJob
metadata:
name: directus-backup
namespace: directus
labels:
app: directus
component: backup
spec:
schedule: "0 2 * * *"
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 3
jobTemplate:
spec:
template:
metadata:
labels:
app: directus
component: backup
spec:
restartPolicy: OnFailure
containers:
- name: backup
image: postgres:16-alpine
command:
- /bin/sh
- -c
- |
set -e
BACKUP_DIR="/backups/directus"
BACKUP_FILE="${BACKUP_DIR}/directus-backup-$(date +%Y%m%d-%H%M%S).sql.gz"
echo "Starting Directus database backup to $BACKUP_FILE"
# Create backup directory if it doesn't exist
mkdir -p "$BACKUP_DIR"
# Perform PostgreSQL dump and compress
PGPASSWORD="$POSTGRES_PASSWORD" pg_dump \
-h directus-postgres \
-U directus \
-d directus \
--clean \
--if-exists \
--no-owner \
--no-privileges \
| gzip > "$BACKUP_FILE"
# Verify backup was created
if [ -f "$BACKUP_FILE" ]; then
SIZE=$(du -h "$BACKUP_FILE" | cut -f1)
echo "Backup completed successfully: $BACKUP_FILE ($SIZE)"
ls -lh "$BACKUP_FILE"
else
echo "ERROR: Backup file was not created"
exit 1
fi
# Clean up backups older than 30 days
echo "Cleaning up backups older than 30 days..."
find "$BACKUP_DIR" -name "directus-backup-*.sql.gz" -type f -mtime +30 -delete
# Show remaining backups
echo "Current backups:"
ls -lh "$BACKUP_DIR" | grep "directus-backup-" || echo "No backups found"
echo "Backup job completed"
env:
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: directus-db-credentials
key: postgres-password
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
volumeMounts:
- name: backup-storage
mountPath: /backups
volumes:
- name: backup-storage
hostPath:
path: /var/backups
type: DirectoryOrCreate

View file

@ -0,0 +1,15 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: directus-db
namespace: directus
labels:
app: directus
component: database
spec:
accessModes:
- ReadWriteOnce
storageClassName: hcloud-volumes-encrypted
resources:
requests:
storage: 20Gi

View file

@ -0,0 +1,150 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: directus
namespace: directus
labels:
app: directus
component: app
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: directus
component: app
template:
metadata:
labels:
app: directus
component: app
spec:
initContainers:
- name: wait-for-postgres
image: postgres:16-alpine
command:
- sh
- -c
- |
until pg_isready -h directus-postgres -U directus; do
echo "Waiting for PostgreSQL..."
sleep 2
done
securityContext:
fsGroup: 1000
containers:
- name: directus
image: directus/directus:12.1.1
ports:
- name: http
containerPort: 8055
env:
- name: DB_CLIENT
value: pg
- name: DB_HOST
value: directus-postgres
- name: DB_PORT
value: "5432"
- name: DB_DATABASE
value: directus
- name: DB_USER
value: directus
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: directus-db-credentials
key: postgres-password
- name: KEY
valueFrom:
secretKeyRef:
name: directus-app-secrets
key: key
- name: SECRET
valueFrom:
secretKeyRef:
name: directus-app-secrets
key: secret
- name: ADMIN_EMAIL
valueFrom:
secretKeyRef:
name: directus-admin-credentials
key: admin-email
- name: ADMIN_PASSWORD
valueFrom:
secretKeyRef:
name: directus-admin-credentials
key: admin-password
- name: PUBLIC_URL
value: https://directus.basicstack.de
- name: AUTH_PROVIDERS
value: openid
- name: AUTH_OPENID_DRIVER
value: openid
- name: AUTH_OPENID_CLIENT_ID
valueFrom:
secretKeyRef:
name: directus-oidc-secret
key: client-id
- name: AUTH_OPENID_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: directus-oidc-secret
key: client-secret
- name: AUTH_OPENID_ISSUER_URL
valueFrom:
secretKeyRef:
name: directus-oidc-secret
key: issuer-url
- name: AUTH_OPENID_IDENTIFIER_KEY
value: email
- name: AUTH_OPENID_ALLOW_PUBLIC_REGISTRATION
value: "true"
- name: AUTH_OPENID_DEFAULT_ROLE_ID
value: ""
- name: AUTH_OPENID_ICON
value: account_circle
- name: AUTH_OPENID_LABEL
value: SSO Login
- name: AUTH_OPENID_SCOPE
value: openid email profile
- name: CORS_ENABLED
value: "true"
- name: CORS_ORIGIN
value: "true"
- name: CACHE_ENABLED
value: "false"
- name: RATE_LIMITER_ENABLED
value: "true"
- name: RATE_LIMITER_POINTS
value: "50"
- name: RATE_LIMITER_DURATION
value: "1"
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: "1"
memory: 2Gi
livenessProbe:
httpGet:
path: /server/health
port: 8055
initialDelaySeconds: 60
periodSeconds: 10
timeoutSeconds: 5
readinessProbe:
httpGet:
path: /server/health
port: 8055
initialDelaySeconds: 30
periodSeconds: 5
timeoutSeconds: 3
volumeMounts:
- name: uploads
mountPath: /directus/uploads
volumes:
- name: uploads
persistentVolumeClaim:
claimName: directus-uploads

View file

@ -0,0 +1,26 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: directus
namespace: directus
labels:
app: directus
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
ingressClassName: traefik
tls:
- hosts:
- directus.basicstack.de
secretName: directus-tls
rules:
- host: directus.basicstack.de
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: directus
port:
number: 80

View file

@ -0,0 +1,70 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: directus-postgres
namespace: directus
labels:
app: directus
component: database
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: directus
component: database
template:
metadata:
labels:
app: directus
component: database
spec:
containers:
- name: postgres
image: postgres:16-alpine
ports:
- name: postgres
containerPort: 5432
env:
- name: POSTGRES_DB
value: directus
- name: POSTGRES_USER
value: directus
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: directus-db-credentials
key: postgres-password
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: "1"
memory: 1Gi
livenessProbe:
exec:
command:
- pg_isready
- -U
- directus
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
exec:
command:
- pg_isready
- -U
- directus
initialDelaySeconds: 5
periodSeconds: 5
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
volumes:
- name: data
persistentVolumeClaim:
claimName: directus-db

View file

@ -0,0 +1,17 @@
apiVersion: v1
kind: Service
metadata:
name: directus-postgres
namespace: directus
labels:
app: directus
component: database
spec:
type: ClusterIP
selector:
app: directus
component: database
ports:
- name: postgres
port: 5432
targetPort: 5432

View file

@ -0,0 +1,17 @@
apiVersion: v1
kind: Service
metadata:
name: directus
namespace: directus
labels:
app: directus
component: app
spec:
type: ClusterIP
selector:
app: directus
component: app
ports:
- name: http
port: 80
targetPort: 8055

View file

@ -0,0 +1,15 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: directus-uploads
namespace: directus
labels:
app: directus
component: data
spec:
accessModes:
- ReadWriteOnce
storageClassName: hcloud-volumes-encrypted
resources:
requests:
storage: 10Gi