Skip to content

Docker Nginx 502 Bad Gateway

By Jasper Frumau

Been dealing with a 502 Bad Gateway error on my Laravel Minikube setup. I started using one web deployment using PHP FPM and Nginx, with a custom image for Laravel / FPM.

I initially thought there were perhaps memory issues or timeout issues, but I soon found out I needed to change the two services to one and tweak the PHP Container setup.

Errors Displayed

When I check the Nginx container logs inside the web deployment I got:

kubectl logs web-699566497c-rpp2z nginx
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: error: /etc/nginx/conf.d/default.conf is not a file or does not exist
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2021/01/11 01:22:24 [error] 20#20: *1 connect() failed (110: Connection timed out) while connecting to upstream, client: 172.17.0.3, server: smart48k8.local, request: "HEAD / HTTP/1.1", upstream: "fastcgi://10.110.166.216:9000", host: "smart48k8.local"
172.17.0.3 - - [11/Jan/2021:01:22:24 +0000] "HEAD / HTTP/1.1" 502 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36" "192.168.64.1"

I had nothing in Laravel logs and no useful Ingress Nginx logs either.

Larger timeout

I did change the timeout for Nginx fastcgi

#  let Nginx wait for 600s on its backend.
fastcgi_read_timeout 600s;

(solid tips by Ma.ttias.be) but still got no good feedback. Then I did some more digging. I changed from a separate deployment for Nginx and PHP FPM to one deployment for both called web.

Real Issue

In the end I realized I needed and a single service called web-service to point to port 80

apiVersion: v1
kind: Service
metadata:
  name: web-service
  namespace: smt-local
  labels:
    tier: backend
spec:
  selector:
    app: web
    tier: backend
  ports:
  - protocol: TCP
    port: 80

and I needed the PHP container to listen to port 80 as well:

- name: php
  envFrom:
    - configMapRef:
        name: laravel-config
  image: smart48/smt-laravel:2.1.2
  imagePullPolicy: IfNotPresent
  ports:
    # https://stackoverflow.com/questions/52132193/kubernetes-nginx-php-deployment
    - containerPort: 80
  resources:
    requests:
      cpu: 250m
    limits:
      cpu: 500m
  volumeMounts:
  - name: code-storage
    mountPath: /code

But I also needed to adjust the fastcgi_pass: in the nginx_configMap:

# fastcgi_pass php-service:9000;
# https://stackoverflow.com/questions/52132193/kubernetes-nginx-php-deployment
fastcgi_pass 127.0.0.1:9000;

As I was no longer using a separate pod for PHP I needed to use the local loopback address.

Once I had adjusted all that I deleted the web deployment and added it anew

kubectl delete deployments.apps web
kubectl apply -f deployments/web.yml

As soon as that was taken care of I started seeing familiar Laravel app errors again and could continue with one deployment for PHP FPM and Nginx and therefore do all the replicating / autoscaling with way more ease.