apiVersion: v1 data: init.sql: | -- Create keycloak database and user CREATE DATABASE keycloak; CREATE USER keycloak WITH PASSWORD 'keycloakpass'; GRANT ALL PRIVILEGES ON DATABASE keycloak TO keycloak; -- Keycloak database permissions \c keycloak GRANT ALL PRIVILEGES ON SCHEMA public TO keycloak; ALTER SCHEMA public OWNER TO keycloak; -- Application database permissions \c workclub GRANT ALL PRIVILEGES ON SCHEMA public TO app; ALTER SCHEMA public OWNER TO app; kind: ConfigMap metadata: labels: app: workclub-postgres environment: development name: postgres-init namespace: workclub-dev --- apiVersion: v1 data: api-base-url: http://workclub-api cors-origins: http://localhost:3000 database-host: workclub-postgres database-name: workclub database-port: "5432" keycloak-realm: workclub keycloak-url: http://workclub-keycloak log-level: Information kind: ConfigMap metadata: labels: app: workclub environment: development name: workclub-config namespace: workclub-dev --- apiVersion: v1 kind: Service metadata: labels: app: workclub-api component: backend environment: development name: workclub-api namespace: workclub-dev spec: ports: - name: http port: 80 protocol: TCP targetPort: 8080 selector: app: workclub-api environment: development type: ClusterIP --- apiVersion: v1 kind: Service metadata: labels: app: workclub-frontend component: frontend environment: development name: workclub-frontend namespace: workclub-dev spec: ports: - name: http port: 80 protocol: TCP targetPort: 3000 selector: app: workclub-frontend environment: development type: ClusterIP --- apiVersion: v1 kind: Service metadata: labels: app: workclub-keycloak component: auth environment: development name: workclub-keycloak namespace: workclub-dev spec: ports: - name: http port: 80 protocol: TCP targetPort: 8080 selector: app: workclub-keycloak environment: development type: ClusterIP --- apiVersion: v1 kind: Service metadata: labels: app: workclub-postgres component: database environment: development name: workclub-postgres namespace: workclub-dev spec: ports: - name: postgresql port: 5432 protocol: TCP targetPort: 5432 selector: app: workclub-postgres environment: development type: ClusterIP --- apiVersion: v1 kind: Service metadata: labels: app: workclub-postgres component: database environment: development name: workclub-postgres-headless namespace: workclub-dev spec: clusterIP: None ports: - name: postgresql port: 5432 protocol: TCP targetPort: 5432 publishNotReadyAddresses: true selector: app: workclub-postgres environment: development type: ClusterIP --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: workclub-api component: backend environment: development name: workclub-api namespace: workclub-dev spec: replicas: 1 selector: matchLabels: app: workclub-api environment: development template: metadata: labels: app: workclub-api component: backend environment: development spec: containers: - env: - name: ASPNETCORE_ENVIRONMENT value: Development - name: ASPNETCORE_URLS value: http://+:8080 - name: ConnectionStrings__DefaultConnection valueFrom: secretKeyRef: key: database-connection-string name: workclub-secrets - name: Keycloak__Url valueFrom: configMapKeyRef: key: keycloak-url name: workclub-config image: workclub-api:dev imagePullPolicy: IfNotPresent livenessProbe: failureThreshold: 3 httpGet: path: /health/live port: http initialDelaySeconds: 10 periodSeconds: 15 timeoutSeconds: 5 name: api ports: - containerPort: 8080 name: http protocol: TCP readinessProbe: failureThreshold: 2 httpGet: path: /health/ready port: http initialDelaySeconds: 5 periodSeconds: 10 timeoutSeconds: 5 resources: limits: cpu: 200m memory: 256Mi requests: cpu: 50m memory: 128Mi startupProbe: failureThreshold: 30 httpGet: path: /health/startup port: http initialDelaySeconds: 5 periodSeconds: 10 timeoutSeconds: 5 --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: workclub-frontend component: frontend environment: development name: workclub-frontend namespace: workclub-dev spec: replicas: 1 selector: matchLabels: app: workclub-frontend environment: development template: metadata: labels: app: workclub-frontend component: frontend environment: development spec: containers: - env: - name: NODE_ENV value: production - name: NEXT_PUBLIC_API_URL valueFrom: configMapKeyRef: key: api-base-url name: workclub-config - name: NEXT_PUBLIC_KEYCLOAK_URL valueFrom: configMapKeyRef: key: keycloak-url name: workclub-config image: workclub-frontend:dev imagePullPolicy: IfNotPresent livenessProbe: failureThreshold: 3 httpGet: path: /api/health port: http initialDelaySeconds: 10 periodSeconds: 15 timeoutSeconds: 5 name: frontend ports: - containerPort: 3000 name: http protocol: TCP readinessProbe: failureThreshold: 2 httpGet: path: /api/health port: http initialDelaySeconds: 5 periodSeconds: 10 timeoutSeconds: 5 resources: limits: cpu: 200m memory: 256Mi requests: cpu: 50m memory: 128Mi --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: workclub-keycloak component: auth environment: development name: workclub-keycloak namespace: workclub-dev spec: replicas: 1 selector: matchLabels: app: workclub-keycloak environment: development template: metadata: labels: app: workclub-keycloak component: auth environment: development spec: containers: - command: - start env: - name: KC_DB value: postgres - name: KC_DB_URL_HOST value: workclub-postgres - name: KC_DB_URL_PORT value: "5432" - name: KC_DB_URL_DATABASE value: keycloak - name: KC_DB_USERNAME value: keycloak - name: KC_DB_PASSWORD valueFrom: secretKeyRef: key: keycloak-db-password name: workclub-secrets - name: KEYCLOAK_ADMIN value: admin - name: KEYCLOAK_ADMIN_PASSWORD valueFrom: secretKeyRef: key: keycloak-admin-password name: workclub-secrets - name: KC_HOSTNAME_STRICT value: "false" - name: KC_PROXY value: edge - name: KC_HTTP_ENABLED value: "true" image: quay.io/keycloak/keycloak:26.1 imagePullPolicy: IfNotPresent livenessProbe: failureThreshold: 3 httpGet: path: /health/live port: http initialDelaySeconds: 20 periodSeconds: 15 timeoutSeconds: 5 name: keycloak ports: - containerPort: 8080 name: http protocol: TCP readinessProbe: failureThreshold: 2 httpGet: path: /health/ready port: http initialDelaySeconds: 10 periodSeconds: 10 timeoutSeconds: 5 resources: limits: cpu: 500m memory: 512Mi requests: cpu: 100m memory: 256Mi --- apiVersion: apps/v1 kind: StatefulSet metadata: labels: app: workclub-postgres component: database environment: development name: workclub-postgres namespace: workclub-dev spec: replicas: 1 selector: matchLabels: app: workclub-postgres environment: development serviceName: workclub-postgres-headless template: metadata: labels: app: workclub-postgres component: database environment: development spec: containers: - env: - name: POSTGRES_DB value: workclub - name: POSTGRES_USER value: app - name: POSTGRES_PASSWORD valueFrom: secretKeyRef: key: postgres-password name: workclub-secrets image: postgres:16-alpine imagePullPolicy: IfNotPresent livenessProbe: exec: command: - /bin/sh - -c - pg_isready -U app -d workclub failureThreshold: 3 initialDelaySeconds: 10 periodSeconds: 15 timeoutSeconds: 5 name: postgres ports: - containerPort: 5432 name: postgresql protocol: TCP readinessProbe: exec: command: - /bin/sh - -c - pg_isready -U app -d workclub failureThreshold: 2 initialDelaySeconds: 5 periodSeconds: 10 timeoutSeconds: 5 resources: limits: cpu: 500m memory: 512Mi requests: cpu: 100m memory: 256Mi volumeMounts: - mountPath: /var/lib/postgresql/data name: postgres-data subPath: postgres - mountPath: /docker-entrypoint-initdb.d name: postgres-init volumes: - configMap: items: - key: init.sql path: init.sql name: postgres-init name: postgres-init volumeClaimTemplates: - metadata: labels: environment: development name: postgres-data spec: accessModes: - ReadWriteOnce resources: requests: storage: 10Gi storageClassName: standard --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: labels: app: workclub environment: development name: workclub-ingress namespace: workclub-dev spec: rules: - host: localhost http: paths: - backend: service: name: workclub-frontend port: number: 80 path: / pathType: Prefix - backend: service: name: workclub-api port: number: 80 path: /api pathType: Prefix