When trying to share a Unix socket between PHP-FPM and Nginx containers via Docker volumes, the permission denied error (error 13) is a common roadblock. The fundamental issue stems from user/group mismatches between containers despite correct file permissions.
The error occurs because:
- PHP-FPM creates the socket with specific user/group (often www-data in Ubuntu)
- Nginx runs as a different user (also typically www-data, but in separate container contexts)
- Docker volume mounts preserve ownership from the host system
The most reliable approach is ensuring consistent UID/GID across containers:
# Modified PHP-FPM Dockerfile
FROM ubuntu:13.10
RUN groupadd -g 33 www-data && \
useradd -u 33 -g www-data www-data
RUN apt-get update && apt-get install -y php5-fpm
RUN sed -i 's/user = www-data/user = 33/' /etc/php5/fpm/pool.d/www.conf
RUN sed -i 's/group = www-data/group = 33/' /etc/php5/fpm/pool.d/www.conf
CMD ["php5-fpm"]
# Modified Nginx Dockerfile
FROM ubuntu:13.10
RUN groupadd -g 33 www-data && \
useradd -u 33 -g www-data www-data
RUN apt-get update && apt-get install -y nginx
CMD ["nginx", "-g", "daemon off;"]
When running containers, explicitly set the shared volume:
docker run -d --name php-fpm \
-v /path/to/socket:/var/run/php5-fpm.sock \
custom-php-fpm
docker run -d --name nginx \
-v /path/to/socket:/var/run/php5-fpm.sock \
-p 80:80 \
custom-nginx
For more modern setups, consider using Docker's built-in networking:
# Create shared network
docker network create app-network
# Run services on same network
docker run -d --network app-network --name php-fpm custom-php-fpm
docker run -d --network app-network -p 80:80 --name nginx custom-nginx
Then configure Nginx to connect via TCP:
fastcgi_pass php-fpm:9000;
When attempting to connect PHP-FPM and Nginx containers through a shared Unix socket, permission issues are among the most common roadblocks. The core problem manifests as Nginx being unable to access the socket file created by PHP-FPM in the shared volume.
The permission system involves three key components:
1. File permissions (777 won't always solve the problem)
2. Process ownership (www-data in both containers)
3. Volume mount options (critical for cross-container communication)
First, ensure both containers use compatible user/group IDs. The standard approach is to:
# In your PHP-FPM Dockerfile
RUN usermod -u 1000 www-data
RUN groupmod -g 1000 www-data
# In your Nginx Dockerfile
RUN usermod -u 1000 www-data
RUN groupmod -g 1000 www-data
For the shared socket directory, use these Docker run commands:
# For PHP-FPM container
docker run -v /host/socket/path:/container/fpm/run -e SOCKET_DIR=/container/fpm/run php-fpm-container
# For Nginx container
docker run -v /host/socket/path:/container/fpm/run nginx-container
Modify your www.conf to ensure proper socket permissions:
[www]
user = www-data
group = www-data
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
listen = /container/fpm/run/php5-fpm.sock
For better permission handling, consider using Docker named volumes:
docker volume create socket_volume
docker run -v socket_volume:/container/fpm/run php-fpm-container
docker run -v socket_volume:/container/fpm/run nginx-container
If issues persist, verify these aspects:
1. Check actual permissions inside containers:
docker exec -it php-fpm-container ls -la /container/fpm/run
2. Verify process ownership:
docker exec -it php-fpm-container ps aux
3. Test socket communication manually:
docker exec -it nginx-container nc -U /container/fpm/run/php5-fpm.sock
Here's a functional docker-compose.yml implementation:
version: '3'
services:
php-fpm:
build:
context: .
dockerfile: Dockerfile.fpm
volumes:
- socket_volume:/container/fpm/run
environment:
- SOCKET_DIR=/container/fpm/run
nginx:
build:
context: .
dockerfile: Dockerfile.nginx
volumes:
- socket_volume:/container/fpm/run
ports:
- "8080:80"
depends_on:
- php-fpm
volumes:
socket_volume: