--- # Pangolin Data PersistentVolumeClaim (retained for pangolin runtime files at /app/config) apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pangolin-data namespace: pangolin annotations: argocd.argoproj.io/sync-options: Delete=false spec: accessModes: - ReadWriteOnce storageClassName: hcloud-volumes-encrypted resources: requests: storage: 10Gi --- # Pangolin Deployment apiVersion: apps/v1 kind: Deployment metadata: name: pangolin namespace: pangolin spec: replicas: 1 strategy: type: Recreate selector: matchLabels: app: pangolin template: metadata: labels: app: pangolin spec: initContainers: - name: wait-for-postgres image: postgres:17.5 command: - /bin/sh - -c - | set -e until pg_isready -h pangolin-postgres.pangolin.svc.cluster.local -p 5432 -U "$POSTGRES_USER" -d "$POSTGRES_DB"; do echo "waiting for postgres..." sleep 2 done echo "postgres is ready" env: - name: POSTGRES_USER valueFrom: secretKeyRef: name: pangolin-postgres-secrets key: postgres-user - name: POSTGRES_DB valueFrom: secretKeyRef: name: pangolin-postgres-secrets key: postgres-db containers: - name: pangolin image: fosrl/pangolin:postgresql-1.21.1 ports: - containerPort: 3000 name: api - containerPort: 3002 name: http env: - name: PANGOLIN_URL value: "https://pangolin.basicstack.de" # PostgreSQL database URL (Pangolin PostgreSQL variant reads this at startup) - name: DATABASE_URL valueFrom: secretKeyRef: name: pangolin-postgres-secrets key: connection-string # OIDC Configuration - name: OIDC_ENABLED value: "true" - name: OIDC_ISSUER value: "https://auth.basicstack.de" - name: OIDC_CLIENT_ID valueFrom: secretKeyRef: name: pangolin-secrets key: oidc-client-id - name: OIDC_CLIENT_SECRET valueFrom: secretKeyRef: name: pangolin-secrets key: oidc-client-secret - name: OIDC_CALLBACK_URL value: "https://pangolin.basicstack.de/auth/callback" - name: OIDC_SCOPES value: "openid profile email groups" # Admin Credentials - name: ADMIN_PASSWORD valueFrom: secretKeyRef: name: pangolin-secrets key: admin-password volumeMounts: - name: pangolin-data mountPath: /app/config - name: config mountPath: /app/config/config.yml subPath: config.yml resources: requests: memory: "256Mi" cpu: "100m" limits: memory: "1Gi" cpu: "500m" livenessProbe: httpGet: path: / port: 3002 initialDelaySeconds: 60 periodSeconds: 10 timeoutSeconds: 5 failureThreshold: 6 readinessProbe: httpGet: path: / port: 3002 initialDelaySeconds: 30 periodSeconds: 5 timeoutSeconds: 3 failureThreshold: 3 volumes: - name: pangolin-data persistentVolumeClaim: claimName: pangolin-data - name: config configMap: name: pangolin-config --- # Pangolin Service apiVersion: v1 kind: Service metadata: name: pangolin namespace: pangolin spec: type: ClusterIP selector: app: pangolin ports: - name: api port: 3000 targetPort: 3000 protocol: TCP - name: http port: 3002 targetPort: 3002 protocol: TCP --- # Pangolin Ingress apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: pangolin namespace: pangolin annotations: cert-manager.io/cluster-issuer: "letsencrypt-http01" traefik.ingress.kubernetes.io/router.entrypoints: web,websecure spec: ingressClassName: traefik tls: - hosts: - pangolin.basicstack.de secretName: pangolin-tls rules: - host: pangolin.basicstack.de http: paths: - path: /api pathType: Prefix backend: service: name: pangolin port: number: 3000 - path: / pathType: Prefix backend: service: name: pangolin port: number: 3002