Yes, I know…. containers are not meant to be used like this, running two processes within a single container. Ideally, one container runs only one process.
But, what if we want to have php-fpm + nginx on the same container? since we do need both processes running for serving our website, we may say that there is no benefit in having them in two separate containers, and in case one fails, the other is useless and the whole container should be restarted.
So, we decide to have them both in the same container. How to do it properly?? with supervisord
It is a process management daemon that will allow us to monitor and control processes on Linux.
It is quite extensive but we are not going to use all of it. we just need to run two freaking processes.
How to do it?
FROM debian:stretch # make sure you install supervisord RUN apt-get -qq update > /dev/null && apt-get -qq upgrade -y > /dev/null; \ apt-get -qq install -y ... supervisor > /dev/null; # do your stuff, install php, nginx, whatever do you need. # . # . # after you did everything, set up supervisord COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf CMD ["/usr/bin/supervisord"]
The changes in the Dockerfile are straight forward, just:
- install supervisord
- copy the config file
- make docker CMD run supervisord
[supervisord] nodaemon=true [program:nginx] command=nginx -g "daemon off;" autostart=true autorestart=true stdout_logfile=/dev/stdout stdout_logfile_maxbytes=0 stderr_logfile=/dev/stderr stderr_logfile_maxbytes=0 [program:php-fpm] command=/bin/bash -c "mkdir -p /var/run/php && php-fpm7.1 --nodaemonize --fpm-config /etc/php/7.1/fpm/php-fpm.conf" autostart=true autorestart=true stdout_logfile=/dev/stdout stdout_logfile_maxbytes=0 stderr_logfile=/dev/stderr stderr_logfile_maxbytes=0
Now things are interesting….. let’s break them up:
nodaemon=truewe tell supervisord to run as a foreground process.
program:nginxwe run nginx with the “daemon off” directive, we set it to auto-restart in case it fails and most importantly, we redirect logs to stdout and stderr so that docker can pick them up.
program:php-fpmwe first create the /var/run/php folder, so php doesn’t fail to start, then we run php-fpm as a foreground process too. We do the same thing we did for nginx, redirecting the logs to stdout and stderr
And…. that is all! you now have php-fpm and nginx running on the same container, in the proper manner, with supervisord supervising them!