We encountered an issue with our Nginx and PHP-FPM setup on the Kubernetes cluster this morning, which halted its functionality. Investigate and rectify the issue:
The pod name is nginx-phpfpm and configmap name is nginx-config. Identify and fix the problem.
Once resolved, copy /home/thor/index.php file from the jump host to the nginx-container within the nginx document root. After this, you should be able to access the website using Website button on the top bar.
Introduction
Welcome to Day 53 of my 100 Days of DevOps journey! Today, we're diving deep into one of the most common Kubernetes challenges: VolumeMounts issues.
The Scenario
We had a Kubernetes Pod with two containers:
- PHP-FPM – For processing PHP code
- Nginx – For serving web content
Both containers needed to share the same files, but they were mounted to different directories – causing the application to fail!
┌─────────────────────────────────────────────────────────────────────────────┐
│ The Problem │
│ │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ Pod: nginx-phpfpm │ │
│ │ │ │
│ │ ┌──────────────────────┐ ┌──────────────────────┐ │ │
│ │ │ PHP-FPM Container │ │ Nginx Container │ │ │
│ │ │ │ │ │ │ │
│ │ │ Mount: │ │ Mount: │ │ │
│ │ │ /usr/share/nginx/ │ │ /var/www/html/ │ │ │
│ │ │ html │ │ │ │ │
│ │ └──────────────────────┘ └──────────────────────┘ │ │
│ │ ❌ ❌ │ │
│ │ They are NOT sharing the same directory! │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │
│ Result: PHP files were not accessible to Nginx │
└─────────────────────────────────────────────────────────────────────────────┘
📋 What We'll Do Today
Our Task:
-
Pod Name:
nginx-phpfpm -
ConfigMap:
nginx-config - Issue: VolumeMounts misalignment
- Goal: Fix the mount paths and deploy a PHP info page
📖 Understanding VolumeMounts
What are VolumeMounts?
In Kubernetes, VolumeMounts are like shared folders between containers and pods. Think of it like a shared drive on a network:
| Concept | Analogy |
|---|---|
| Volume | A physical hard drive |
| Mount | Connecting the drive to a computer |
| MountPath | The folder where the drive appears |
| Containers | Different computers on the same network |
Why Do Both Containers Need the Same Mount?
┌─────────────────────────────────────────────────────────────────────────────┐
│ Shared Volume Architecture │
│ │
│ ┌──────────────────────────────────────────────────────────────────────┐ │
│ │ Shared Volume (EmptyDir) │ │
│ │ /var/www/html (shared directory) │ │
│ │ │ │
│ │ ┌──────────────────────────────────────────────────────────────────┐ │ │
│ │ │ PHP-FPM writes files │ Nginx reads files │ │ │
│ │ │ (index.php, app files) │ (serves to users) │ │ │
│ │ └──────────────────────────────────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────────────────────────────────┘ │
│ │
│ Both containers must mount to the SAME directory for files to be shared! │
└─────────────────────────────────────────────────────────────────────────────┘
🔍 Diagnosing the Issue
Step 1: Check Pod Status
kubectl get pods
Output:
NAME READY STATUS RESTARTS AGE
nginx-phpfpm 2/2 Running 0 2m44s
The pod is running, but the application isn't working.
Step 2: Inspect VolumeMounts
kubectl describe pod nginx-phpfpm
Key Findings:
Containers:
php-fpm-container:
Mounts:
/usr/share/nginx/html from shared-files (rw) ← PHP mounts here
nginx-container:
Mounts:
/var/www/html from shared-files (rw) ← Nginx mounts here
The Issue: Both containers mount to different paths on the same shared volume!
Step 3: Check ConfigMap
kubectl get configmap nginx-config -o yaml
Nginx Configuration:
root /var/www/html; ← Nginx serves from /var/www/html
PHP-FPM writes to /usr/share/nginx/html, but Nginx reads from /var/www/html. They are not seeing the same files!
🔧 The Solution
Step 1: Delete the Current Pod
kubectl delete pod nginx-phpfpm
Output:
pod "nginx-phpfpm" deleted
Step 2: Create Fixed YAML
vi nginx-phpfpm-fixed.yaml
Fixed YAML Content:
apiVersion: v1
kind: Pod
metadata:
name: nginx-phpfpm
labels:
app: php-app
spec:
containers:
- name: php-fpm-container
image: php:7.2-fpm-alpine
volumeMounts:
- name: shared-files
mountPath: /var/www/html # ← Changed to match nginx!
- name: nginx-container
image: nginx:latest
volumeMounts:
- name: shared-files
mountPath: /var/www/html # ← This is correct
- name: nginx-config-volume
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
volumes:
- name: shared-files
emptyDir: {}
- name: nginx-config-volume
configMap:
name: nginx-config
What Changed?
| Component | Before | After |
|---|---|---|
| PHP-FPM Mount | /usr/share/nginx/html |
/var/www/html |
| Nginx Mount | /var/www/html |
/var/www/html |
| Result | ❌ Different paths | ✅ Same path! |
Step 3: Apply the Fixed Pod
kubectl apply -f nginx-phpfpm-fixed.yaml
Output:
pod/nginx-phpfpm created
Step 4: Verify Pod is Running
kubectl get pods
Output:
NAME READY STATUS RESTARTS AGE
nginx-phpfpm 2/2 Running 0 12s
Step 5: Copy PHP File to Container
# Copy index.php to the nginx container
kubectl cp /home/thor/index.php nginx-phpfpm:/var/www/html/index.php -c nginx-container
Step 6: Verify Everything Works
# Check if file is copied
kubectl exec -it nginx-phpfpm -c nginx-container -- ls -la /var/www/html/
Output:
total 12
drwxrwxrwx 2 root root 4096 Aug 16 14:30 .
drwxr-xr-x 3 root root 4096 Aug 16 14:29 ..
-rw-r--r-- 1 1000 1000 19 Aug 16 14:30 index.php
# Check PHP info file content
kubectl exec -it nginx-phpfpm -c nginx-container -- cat /var/www/html/index.php
Output:
<?php
phpinfo();
?>
# Check pod status
kubectl get pods
Output:
NAME READY STATUS RESTARTS AGE
nginx-phpfpm 2/2 Running 0 28s
📝 Complete Commands Summary
# 1. Delete the current pod
kubectl delete pod nginx-phpfpm
# 2. Create fixed YAML
cat > nginx-phpfpm-fixed.yaml << 'EOF'
apiVersion: v1
kind: Pod
metadata:
name: nginx-phpfpm
labels:
app: php-app
spec:
containers:
- name: php-fpm-container
image: php:7.2-fpm-alpine
volumeMounts:
- name: shared-files
mountPath: /var/www/html
- name: nginx-container
image: nginx:latest
volumeMounts:
- name: shared-files
mountPath: /var/www/html
- name: nginx-config-volume
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
volumes:
- name: shared-files
emptyDir: {}
- name: nginx-config-volume
configMap:
name: nginx-config
EOF
# 3. Apply the fixed pod
kubectl apply -f nginx-phpfpm-fixed.yaml
# 4. Copy index.php
kubectl cp /home/thor/index.php nginx-phpfpm:/var/www/html/index.php -c nginx-container
# 5. Verify
kubectl exec -it nginx-phpfpm -c nginx-container -- ls -la /var/www/html/
kubectl exec -it nginx-phpfpm -c nginx-container -- cat /var/www/html/index.php
📊 Before and After Comparison
| Aspect | Before | After |
|---|---|---|
| PHP-FPM Mount | /usr/share/nginx/html |
/var/www/html |
| Nginx Mount | /var/www/html |
/var/www/html |
| Shared Directory | ❌ Different | ✅ Same |
| File Accessibility | ❌ Not accessible | ✅ Accessible |
| Pod Status | Running | Running |
| Application | ❌ Not working | ✅ Working |
📋 YAML Breakdown
Fixed VolumeMounts Section
volumeMounts:
- name: shared-files
mountPath: /var/www/html # ← Both containers mount here!
What Changed?
# PHP-FPM Container
- mountPath: /usr/share/nginx/html
+ mountPath: /var/www/html
# Nginx Container (unchanged)
mountPath: /var/www/html
Why This Works
- ✅ Both containers mount the same volume at the same path
- ✅ PHP-FPM writes files to
/var/www/html - ✅ Nginx reads files from
/var/www/html - ✅ They share the same files!
🔍 Verification Commands
# Check pod status
kubectl get pods
# Check detailed pod info
kubectl describe pod nginx-phpfpm
# Check volume mounts
kubectl describe pod nginx-phpfpm | grep -A 5 "Mounts:"
# Check ConfigMap
kubectl get configmap nginx-config -o yaml
# Check if file exists
kubectl exec -it nginx-phpfpm -c nginx-container -- ls -la /var/www/html/
# Check PHP info
kubectl exec -it nginx-phpfpm -c nginx-container -- cat /var/www/html/index.php
🎯 Key Learnings
1. VolumeMount Paths Must Match
Both containers must mount the shared volume at the same path for files to be accessible.
2. Check Configuration Alignment
The Nginx config (root /var/www/html) must match the mount path.
3. Use kubectl describe for Debugging
Always check kubectl describe pod to see mount details.
4. EmptyDir Volumes
EmptyDir volumes are temporary and share data between containers in the same pod.
5. ConfigMap Mounts
ConfigMaps can be mounted as files or directories.
🛠️ Common VolumeMount Issues
| Issue | Symptom | Solution |
|---|---|---|
| Wrong mount path | Files not accessible | Align mount paths between containers |
| Missing subPath | Directory mounted instead of file | Use subPath for individual files |
| Permission issues | Can't write files | Set security context or fsGroup |
| ConfigMap not found | Pod fails to start | Check ConfigMap name and namespace |
| Mount conflict | Files overwritten | Use different mount paths for different purposes |
📚 Quick Reference
VolumeMount Commands
| Command | Purpose |
|---|---|
kubectl describe pod <name> |
See volume mount details |
kubectl exec -it <pod> -- ls -la <mountPath> |
Check files in mounted volume |
kubectl cp <file> <pod>:<path> -c <container> |
Copy files to container |
kubectl get configmap <name> -o yaml |
View ConfigMap content |
Common Mount Paths for Nginx + PHP
| Container | Mount Path |
|---|---|
| PHP-FPM | /var/www/html |
| Nginx | /var/www/html |
| Shared Volume | /var/www/html |
🎉 You Did It!
You've successfully resolved a VolumeMounts issue in Kubernetes! This is a critical skill for:
- ✅ Multi-container pods – Sharing files between containers
- ✅ Web applications – PHP-FPM + Nginx setups
- ✅ Stateful applications – Persistent storage
- ✅ Troubleshooting – Identifying mount issues
Top comments (0)