Scenario #
An application using Nginx and PHP-FPM failed to serve pages. The resources involved:
- Pod:
nginx-phpfpm - ConfigMap:
nginx-config
Your task is to find and fix the issue, then copy /home/thor/index.php from the jump host into the Nginx document root inside the nginx-container so the site becomes accessible.
Diagnosis #
You provided the recent pod events and logs — both containers started successfully, so this is not a startup or image-pull failure. Here are the events observed:
Normal Scheduled 6m52s default-scheduler Successfully assigned default/nginx-phpfpm to kodekloud-control-plane
Normal Pulling 6m51s kubelet Pulling image "php:7.2-fpm-alpine"
Normal Pulled 6m49s kubelet Successfully pulled image "php:7.2-fpm-alpine"
Normal Created 6m49s kubelet Created container php-fpm-container
Normal Started 6m48s kubelet Started container php-fpm-container
Normal Pulling 6m48s kubelet Pulling image "nginx:latest"
Normal Pulled 6m43s kubelet Successfully pulled image "nginx:latest"
Normal Created 6m43s kubelet Created container nginx-container
Normal Started 6m42s kubelet Started container nginx-containerNginx logs show the container initialized and is ready to start:
/docker-entrypoint.sh: Configuration complete; ready for start upPHP-FPM logs show the PHP process is running and ready to handle connections:
[12-Jan-2026 19:48:39] NOTICE: fpm is running, pid 1
[12-Jan-2026 19:48:39] NOTICE: ready to handle connectionsBecause both containers are Running and Ready (see kubectl describe pod), and the nginx-config is mounted into /etc/nginx/nginx.conf, we can draw specific conclusions from the provided outputs.
Observed from kubectl describe pod nginx-phpfpm:
Containers:
php-fpm-container: Ready: True
nginx-container: Ready: True
Mounts:
/var/www/html from shared-files (rw)
/etc/nginx/nginx.conf from nginx-config-volume (rw,path="nginx.conf")ConfigMap nginx-config contents show Nginx is listening on port 8099 and serving from /var/www/html with index including index.php. The fastcgi_pass is configured as 127.0.0.1:9000:
server {
listen 8099 default_server;
root /var/www/html;
index index.html index.htm index.php;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass 127.0.0.1:9000;
}
}Root cause analysis:
- Nginx and PHP-FPM are up and running and the ConfigMap is mounted.
- The
ConfigMapconfig setsroot /var/www/html;(so Nginx expects files under/var/www/html). - The
shared-filesEmptyDir is mounted at different paths in the two containers:- In
php-fpm-containerit is mounted at/var/www/html. - In
nginx-containerit is mounted at/usr/share/nginx/html.
- In
- Because Nginx’s configured
root(/var/www/html) does not exist inside thenginx-container(its shared volume is at/usr/share/nginx/html), requests return404even though the file may exist in thephp-fpm-containerpath.
Therefore the immkubectl delete pod nginx-phpfpm
wait for new pod to be Ready before proceeding #
kubectl get pods -wkubectl delete pod nginx-phpfpm
wait for new pod to be Ready before proceeding #
kubectl get pods -wkubectl delete pod nginx-phpfpm
wait for new pod to be Ready before proceeding #
kubectl get pods -wediate fix is to make Nginx use the path it actually has mounted, or change the mount path in the pod spec. The simpler, safe approach is to update the nginx-config ConfigMap so root points to /usr/share/nginx/html (the path present in the nginx-container). After that, recreate the pod so Nginx picks up the updated config and then copy the index.php into /usr/share/nginx/html inside the nginx-container.
Fix summary: change root /var/www/html; to root /usr/share/nginx/html; in the nginx-config ConfigMap, restart the pod, then copy /home/thor/index.php into /usr/share/nginx/html/index.php in nginx-container.
Likely Root Cause #
In many kata-style exercises the common issue is a configuration typo in nginx-config that points Nginx to the wrong PHP-FPM socket (e.g. fastcgi_pass unix:/var/run/php-fpm.sock; when the PHP-FPM container listens on 127.0.0.1:9000 or vice-versa), or an invalid include/syntax causing the Nginx process to not start.
For this scenario, inspect the nginx-config contents and look for fastcgi_pass pointing to a non-existent socket or mismatched upstream.
Fix #
Edit the ConfigMap in-place and correct the fastcgi_pass setting (or other syntax errors):
kubectl edit configmap nginx-config- If
fastcgi_passis set to127.0.0.1:9000, ensure PHP-FPM listens on TCP socket at that address. - If it uses a unix socket path, ensure PHP-FPM creates that socket and the volume mount points match.
After saving the corrected ConfigMap, restart the pod to pick up the new configuration:
kubectl delete pod nginx-phpfpm
# pod will be recreated by its controller (Deployment/ReplicaSet) if presentIf the pod is a standalone Pod (not managed), re-create it using the corrected manifest.
Copy index.php into container #
Once the pod is running and Nginx is serving, copy /home/thor/index.php from the jump host into the container’s document root (commonly /usr/share/nginx/html or /var/www/html depending on your image). First, confirm the document root used by your Nginx configuration.
Assuming document root is /usr/share/nginx/html and the container name is nginx-container:
kubectl cp /home/thor/index.php nginx-phpfpm:/usr/share/nginx/html/index.php -c nginx-containerIf the pod uses a Deployment and new pods are created, copy the file into the running pod’s container after it’s ready.
Verification #
- Check pod status:
kubectl get pods
kubectl describe pod nginx-phpfpm- Tail Nginx logs:
kubectl logs -f nginx-phpfpm -c nginx-container- After copying
index.php, open the Website button in the top bar (or curl the NodePort/ingress URL) to verify the PHP page is rendered:
curl -sS http://<node-ip>:<nodeport>/ | head -n 30Useful commands to inspect and fix nginx-config
#
# View current configmap contents
kubectl get configmap nginx-config -o yaml
# Edit the configmap in-place
kubectl edit configmap nginx-config
# After editing, restart the pod to pick up changes
kubectl delete pod nginx-phpfpmIf you get 502 Bad Gateway after copying the file, check these logs for clues:
kubectl logs nginx-phpfpm -c nginx-container --tail=200
kubectl logs nginx-phpfpm -c php-fpm-container --tail=200If you want, I can craft the exact fastcgi_pass fix if you paste the nginx-config content here. Otherwise run the kubectl get configmap nginx-config -o yaml command and look for the fastcgi_pass line — it should point to the address/socket where PHP-FPM is listening (for example 127.0.0.1:9000 or the unix socket path /var/run/php/php7.2-fpm.sock).
Exact commands to run now (from the jump host) #
- Confirm
index.phpis missing inside the container:
kubectl exec -it nginx-phpfpm -c nginx-container -- ls -la /var/www/html || true- Copy the file from the jump host into the running container:
kubectl edit configmap nginx-config
# In the editor, change the `root` line from `/var/www/html` to `/usr/share/nginx/html` and save.
# Recreate the pod so the nginx container picks up the new config
kubectl delete pod nginx-phpfpm
# Wait for the pod to become Ready, then copy the file into the nginx container's mount path
kubectl cp /home/thor/index.php nginx-phpfpm:/usr/share/nginx/html/index.php -c nginx-container- Confirm the file is present and readable by both containers:
kubectl exec -it nginx-phpfpm -c nginx-container -- ls -la /var/www/html/index.php
kubectl exec -it nginx-phpfpm -c php-fpm-container -- ls -la /var/www/html/index.php- Check logs if you still see issues:
kubectl logs nginx-phpfpm -c nginx-container --tail=200
kubectl logs nginx-phpfpm -c php-fpm-container --tail=200- Verify via curl (replace
<node-ip>and<nodeport>with your cluster/node details):
curl -sS http://<node-ip>:<nodeport>/ | head -n 50If the page still returns 404, paste the output of step (1) and the kubectl get configmap nginx-config -o yaml here and I’ll provide the exact next diagnosis. Otherwise, after step (2) the Website button should work and serve the PHP page.
Expected result: the PHP page is served and contains whatever test output is in /home/thor/index.php.
Notes #
- If you continue to see
502 Bad Gateway, it’s typically a PHP-FPM connection issue—verifyfastcgi_passand ensure PHP-FPM is listening on the configured address/socket. - If
kubectl cpfails due to permissions, ensure you run it from the jump host location with the source file accessible.