Reference example · Python API + sidecar

Python API with Nginx sidecar.

A Python API with an Nginx sidecar and a named Service target port.

values.yaml

replicaCount: 2
image: ghcr.io/example-org/python-api
imageTag: "1.0.0"
imagePullPolicy: IfNotPresent

service:
  port: 8080
  targetPort: nginx

securityContext:
  runAsNonRoot: true
  runAsUser: 10001
  runAsGroup: 10001
  allowPrivilegeEscalation: false
  readOnlyRootFilesystem: true
  capabilities:
    drop: ["ALL"]
podSecurityContext:
  seccompProfile:
    type: RuntimeDefault

env:
  - name: APP_ENV
    value: production
envFrom:
  - configMapRef:
      name: python-config
configMaps:
  - name: python-config
    data:
      LOG_LEVEL: info
      WORKERS: "2"
  - name: nginx-config
    data:
      nginx.conf: |
        pid /tmp/nginx.pid;
        events {}
        http {
          access_log off;
          server {
            listen 8081;
            location / {
              proxy_pass http://127.0.0.1:8080;
              proxy_buffering off;
              proxy_set_header Host $host;
              proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            }
          }
        }

volumes:
  - name: nginx-config
    configMap:
      name: nginx-config
  - name: nginx-tmp
    emptyDir: {}

extraContainers:
  enabled: true
  containers:
    - name: nginx
      image: nginxinc/nginx-unprivileged
      imageTag: "1.27-alpine"
      imagePullPolicy: IfNotPresent
      command: ["nginx", "-g", "daemon off;"]
      ports:
        - name: nginx
          containerPort: 8081
          protocol: TCP
      securityContext:
        runAsNonRoot: true
        runAsUser: 101
        runAsGroup: 101
        allowPrivilegeEscalation: false
        readOnlyRootFilesystem: true
        capabilities:
          drop: ["ALL"]
      volumeMounts:
        - name: nginx-config
          mountPath: /etc/nginx/nginx.conf
          subPath: nginx.conf
          readOnly: true
        - name: nginx-tmp
          mountPath: /tmp
      readinessProbe:
        httpGet: {path: /health, port: nginx}
      livenessProbe:
        httpGet: {path: /health, port: nginx}
      resources:
        requests: {cpu: 25m, memory: 32Mi}
        limits: {cpu: 100m, memory: 128Mi}

resources:
  requests: {cpu: 50m, memory: 64Mi}
  limits: {cpu: 250m, memory: 256Mi}
readinessProbe:
  httpGet: {path: /health, port: http}
livenessProbe:
  httpGet: {path: /health, port: http}
route:
  enabled: true
  gateway: external
  gatewayNamespace: gateway-system
  sectionName: https
  hostname: python.example.com

Deploy

helm upgrade --install python-api universal/application \
  --namespace apps --create-namespace \
  --values values.yaml

Result

kubectl get pods -l app.kubernetes.io/instance=python-api
NAME                           READY   STATUS
python-api-7b86c9d7f5-abcde    2/2     Running

curl -fsS https://python.example.com/health
{"status":"ok"}

Package

Artifact Hub →