Next.js with Nginx on Kubernetes

11/5/2019

I am learning Kubernetes. I am trying to run Next.js with Nginx on Kubernetes, but I got "504 Gateway Time-out"


nginx.yml

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-conf
data:
  nginx.conf: |
    worker_processes 5;

    events {
    }

    http {
      # Cache zone
      proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=STATIC:10m inactive=7d use_temp_path=off;

      upstream nextjs_upstream {
        server next;
      }

      server {
        listen 80 default_server;

        server_name _;

        server_tokens off;

        gzip on;
        gzip_proxied any;
        gzip_comp_level 4;
        gzip_types text/css application/javascript image/svg+xml;

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;

        # BUILT ASSETS (E.G. JS BUNDLES)
        # Browser cache - max cache headers from Next.js as build id in url
        # Server cache - valid forever (cleared after cache "inactive" period)
        location /_next/static {
          proxy_cache STATIC;
          proxy_pass http://nextjs_upstream;

          # For testing cache - remove before deploying to production
          add_header X-Cache-Status $upstream_cache_status;
        }

        # STATIC ASSETS (E.G. IMAGES)
        # Browser cache - "no-cache" headers from Next.js as no build id in url
        # Server cache - refresh regularly in case of changes
        location /static {
          proxy_cache STATIC;
          proxy_ignore_headers Cache-Control;
          proxy_cache_valid 60m;
          proxy_pass http://nextjs_upstream;

          # For testing cache - remove before deploying to production
          add_header X-Cache-Status $upstream_cache_status;
        }

        # DYNAMIC ASSETS - NO CACHE
        location / {
          proxy_pass http://nextjs_upstream;
        }
      }
    }
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx
          ports:
            - containerPort: 80
          volumeMounts:
            - mountPath: /etc/nginx
              readOnly: true
              name: nginx-conf
            - mountPath: /var/log/nginx
              name: log
          imagePullPolicy: Always
      volumes:
        - name: nginx-conf
          configMap:
            name: nginx-conf
            items:
              - key: nginx.conf
                path: nginx.conf
        - name: log
          emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  selector:
    app: nginx
  ports:
    - port: 80
      targetPort: 80
  type: LoadBalancer

next.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: next
spec:
  replicas: 1
  selector:
    matchLabels:
      app: next
  template:
    metadata:
      labels:
        app: next
    spec:
      containers:
        - name: next
          image: my/next-tw:0.0.1
          ports:
            - containerPort: 3000
          imagePullPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
  name: next
spec:
  selector:
    app: next
  ports:
    - port: 3000
      targetPort: 3000

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Docker built containers are tested on local and running fine with docker-compose.yml

Please enlighten me, what I am doing wrong?

-- Rario
docker
kubernetes
next.js
nginx
reactjs

1 Answer

11/15/2019

You need to:

  • Install ingress-controller.
  • setup LoadBalancer service
  • map domain name to Loadbalancer IP.
  • run deployment
  • create Kubernetes Ingress Object

All steps are described here: setup-ingress-controller.

There is an option to use annotations during defining Ingress Object. You need to define a timeout for reading a response from the proxied server. The timeout is set only between two successive read operations, not for the transmission of the whole response. If the proxied server does not transmit anything within this time, the connection is closed.

Try to set a timeout using the annotation nginx.ingress.kubernetes.io/proxy-read-timeout nginx-timeout.

-- MaggieO
Source: StackOverflow