# ====================================================== # WGER - PRODUCTION ARCHITECTURE # Traefik → nginx → wger → postgres # ====================================================== # ------------------------- # STORAGE CLASS # ------------------------- --- apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: wger-local-storage provisioner: kubernetes.io/no-provisioner volumeBindingMode: WaitForFirstConsumer # ====================================================== # PERSISTENT VOLUMES # ====================================================== # ------------------------- # POSTGRES PV # ------------------------- --- apiVersion: v1 kind: PersistentVolume metadata: name: wger-postgres-pv spec: capacity: storage: 2Gi accessModes: [ReadWriteOnce] storageClassName: wger-local-storage persistentVolumeReclaimPolicy: Retain local: path: /home/kimjunte/k8s_storage/wger/postgres nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: [mist] --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: wger-postgres-pvc spec: accessModes: [ReadWriteOnce] storageClassName: wger-local-storage resources: requests: storage: 2Gi # ------------------------- # STATIC PV # ------------------------- --- apiVersion: v1 kind: PersistentVolume metadata: name: wger-static-pv spec: capacity: storage: 2Gi accessModes: [ReadWriteOnce] storageClassName: wger-local-storage persistentVolumeReclaimPolicy: Retain local: path: /home/kimjunte/k8s_storage/wger/static nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: [mist] --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: wger-static-pvc spec: accessModes: [ReadWriteOnce] storageClassName: wger-local-storage resources: requests: storage: 2Gi # ------------------------- # MEDIA PV # ------------------------- --- apiVersion: v1 kind: PersistentVolume metadata: name: wger-media-pv spec: capacity: storage: 5Gi accessModes: [ReadWriteOnce] storageClassName: wger-local-storage persistentVolumeReclaimPolicy: Retain local: path: /home/kimjunte/k8s_storage/wger/media nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: [mist] --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: wger-media-pvc spec: accessModes: [ReadWriteOnce] storageClassName: wger-local-storage resources: requests: storage: 5Gi # ====================================================== # POSTGRES # ====================================================== --- apiVersion: apps/v1 kind: Deployment metadata: name: wger-postgres spec: replicas: 1 selector: matchLabels: app: wger-postgres template: metadata: labels: app: wger-postgres spec: nodeSelector: kubernetes.io/hostname: mist containers: - name: postgres image: postgres:15-alpine env: - name: POSTGRES_USER value: wger - name: POSTGRES_PASSWORD value: wgerpassword - name: POSTGRES_DB value: wger volumeMounts: - mountPath: /var/lib/postgresql/data name: postgres-storage volumes: - name: postgres-storage persistentVolumeClaim: claimName: wger-postgres-pvc --- apiVersion: v1 kind: Service metadata: name: wger-postgres spec: selector: app: wger-postgres ports: - port: 5432 # ====================================================== # REDIS # ====================================================== --- apiVersion: apps/v1 kind: Deployment metadata: name: wger-redis spec: replicas: 1 selector: matchLabels: app: wger-redis template: metadata: labels: app: wger-redis spec: nodeSelector: kubernetes.io/hostname: mist containers: - name: redis image: redis:7-alpine --- apiVersion: v1 kind: Service metadata: name: wger-redis spec: selector: app: wger-redis ports: - port: 6379 # ====================================================== # WGER APP # ====================================================== --- apiVersion: apps/v1 kind: Deployment metadata: name: wger spec: replicas: 1 selector: matchLabels: app: wger template: metadata: labels: app: wger spec: nodeSelector: kubernetes.io/hostname: mist containers: - name: wger image: wger/server:latest env: - name: DATABASE_URL value: postgres://wger:wgerpassword@wger-postgres:5432/wger - name: CACHE_URL value: redis://wger-redis:6379/1 - name: DJANGO_SECRET_KEY value: replace-with-long-random-string - name: ALLOWED_HOSTS value: "*" - name: CSRF_TRUSTED_ORIGINS value: https://exercise.juntekim.com ports: - containerPort: 8000 volumeMounts: - name: static-storage mountPath: /home/wger/static - name: media-storage mountPath: /home/wger/media volumes: - name: static-storage persistentVolumeClaim: claimName: wger-static-pvc - name: media-storage persistentVolumeClaim: claimName: wger-media-pvc --- apiVersion: v1 kind: Service metadata: name: wger spec: selector: app: wger ports: - port: 8000 targetPort: 8000 # ====================================================== # NGINX (STATIC + PROXY) # ====================================================== --- apiVersion: v1 kind: ConfigMap metadata: name: wger-nginx-config data: default.conf: | server { listen 80; location /static/ { alias /home/wger/static/; } location /media/ { alias /home/wger/media/; } location / { proxy_pass http://wger:8000; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } --- apiVersion: apps/v1 kind: Deployment metadata: name: wger-nginx spec: replicas: 1 selector: matchLabels: app: wger-nginx template: metadata: labels: app: wger-nginx spec: nodeSelector: kubernetes.io/hostname: mist containers: - name: nginx image: nginx:alpine ports: - containerPort: 80 volumeMounts: - name: static-storage mountPath: /home/wger/static - name: media-storage mountPath: /home/wger/media - name: nginx-config mountPath: /etc/nginx/conf.d volumes: - name: static-storage persistentVolumeClaim: claimName: wger-static-pvc - name: media-storage persistentVolumeClaim: claimName: wger-media-pvc - name: nginx-config configMap: name: wger-nginx-config --- apiVersion: v1 kind: Service metadata: name: wger-nginx spec: selector: app: wger-nginx ports: - port: 80 targetPort: 80 # ====================================================== # TRAEFIK INGRESS # ====================================================== --- apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: wger-ingress spec: entryPoints: - websecure routes: - match: Host(`exercise.juntekim.com`) kind: Rule services: - name: wger-nginx port: 80 tls: certResolver: myresolver