Docker Nginx 502 Bad Gateway

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.

Jasper Frumau

Jasper has been working with web frameworks and applications such as Laravel, Magento and his favorite CMS WordPress including Roots Trellis and Sage for more than a decade. He helps customers with web design and online marketing. Services provided are web design, ecommerce, SEO, content marketing. When Jasper is not coding, marketing a website, reading about the web or dreaming the internet of things he plays with his son, travels or run a few blocks.