Docker

Running php-fpm and nginx processes in the same container with supervisord

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

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?

Dockerfile:

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.conf:

[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=true we tell supervisord to run as a foreground process.
  • program:nginx we 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-fpm we 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!