Non-Privileged Named Volumes for Shared PHP-FPM and Nginx Sockets on Docker Alpine

Barney Hanlon and his Medium story Setting up nginx and PHP-FPM in Docker with Unix Sockets were the inspiration that led to today’s story. If you find this story was relevant or helpful to you, please go and follow or thank Barney for his story!

Photo by Gabriel González on Unsplash

PHP FPM Pool Config and Dockerfile

.

Original: LEFT; New: RIGHT

Nginx Virtual Host Config

.

location ~ '\.php$|^\/update.php' {  # Talk to Docker Compose Service "php-fpm" on port "9010":
fastcgi_pass php-fpm:9010;
}
location ~ '\.php$|^\/update.php' {
fastcgi_pass unix:/sock/docker.sock;
}
Thanks Barney Hanlon!

Launch It!

.

connect() to unix:/sock/docker.sock failed (2: No such file or directory)
When root owns your socket

Yes! I Love Writing About Solving Problems!

.

And just like that, for as brief moment my morning became more exciting.
We’re using named volumes for the FPM socket, and having perms issues, this is relevant.
Github issue #3270 for Docker Compose, shows how to initialize named volume permissions.
FPM Dockerfile with NEW volume, VOLUME is initialized before being declared
FPM’s Pool configuration hardcoded to /sock/docker.sock with nobody user
Run my rebuild script for all Docker images
Destroy all previous volumes to be safe
ALL SERVICES ARE UP
docker compose logs php-fpm show startup is nominal, no errors
Directory /sock on php-fpm container has correct nobody permissions
Splendid! Would you like some tea?
Test FPM container’s perms using compose exec, not run
The new socket works!
volumes:  
drawer:
php-fpm:
volumes:
- drawer:/sock
nginx:
volumes:
- drawer:/sock
environment:
PHP_FPM_LISTEN: /sock/docker.sock
My reaction when my sockets work. Image may be subject to copyright.

Recap and Breakdown

  • Before I was using TCP for communication between PHP-FPM and Nginx.
  • I switched from TCP to Unix Socket on both PHP-FPM and Nginx containers.
  • Using Unix Sockets instead of TCP is more performant because it avoids using the networking overhead associated with TCP communications.
  • Both my FPM and Nginx containers run their respective processes as the non-privileged user nobody.
  • I use Alpine Linux on both my FPM and Nginx containers.
  • I choose to use the non-privileged user nobody because it is endemic to Alpine Linux — that is it ships with the Alpine base image, which is used in both my containers. That way I don’t need to create an additional, custom user.
  • When sharing a named volume between containers for use by non-privileged users, there’s additional considerations to take in mind — such as that by default named volumes are created by the Docker engine as root .
  • To overcome this limitation, in your Dockerfile you can initialize the named volume by creating it and calling chmod on it for the desired non-privileged user before declaring it with the VOLUME ["/NAMEDVOLUME"] instruction.
  • I provided the documentation trail for how to overcome non-privileged named volume limitations.

Organic, fair-sourced DevOps and Full-Stack things. This is a BYOB Establishment — Bring Your Own hipster Beard.

Get the Medium app