Resolving Docker Volume Permission Denied Error for Unix Socket Sharing Between PHP-FPM and Nginx Containers


4 views

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: