In this example we are going to run PHP-FPM as the main process in our container and control it with supervisor so if the PHP process ever goes down, supervisor will bring it up again.


Structure


superman$ tree -a
.
├── config
│ └── supervisor
│ └── hello.conf
├── docker
│ └── php
│ ├── Dockerfile
│ └── supervisord.conf
├── docker-compose.yml
└── hello.php

Files


config/supervisor/hello.conf


[program:hello]
command=php hello.php -DFOREGROUND
directory=/superman
autostart=true
autorestart=true
startretries=5
startsecs=0
user=root
numprocs=1
process_name=%(program_name)s_%(process_num)02d
stderr_logfile=/var/log/supervisor/%(program_name)s_stderr.log
stderr_logfile_maxbytes=10MB
stdout_logfile=/var/log/supervisor/%(program_name)s_stdout.log
stdout_logfile_maxbytes=10MB

docker/php/Dockerfile


FROM php:7.2-fpm

RUN apt-get update \
&& apt-get install -y --no-install-recommends \
supervisor

COPY ./docker/php/supervisord.conf /etc/supervisor
COPY ./config/supervisor/* /etc/supervisor/conf.d

CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/supervisord.conf"]

docker/php/supervisord.conf


[unix_http_server]
file=/var/run/supervisor.sock
chmod=0770
chown=nobody:nogroup

[supervisord]
logfile=/var/log/supervisor/supervisord.log
pidfile=/var/run/supervisord.pid
nodaemon=true

[rpcinterface:supervisor]
supervisor.rpcinterface_factory=supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]
serverurl=unix:///var/run/supervisor.sock

[inet_http_server]
port = 9001
username = root
password = root

[program:php]
command=docker-php-entrypoint php-fpm # This is our main process so let us put it here

[include]
files=/etc/supervisor/conf.d/*.conf

docker-compose.yml


version: '3'

services:
php:
build:
context: ../superman
dockerfile: ./docker/php/Dockerfile
ports:
- 9001:9001 # Access GUI with http://localhost:9001/
volumes:
- .:/superman:cached

hello.php


This will write a new line to log file every 3 seconds.


<?php

$i = 1;

while (true) {
file_put_contents('message.log', 'Hello '.++$i.PHP_EOL, FILE_APPEND);

sleep(3);
}

Build


$ docker-compose up --build
Creating network "superman_default" with the default driver
Building php
Step 1/6 : FROM php:7.2-fpm
---> 0a757334c1f6
Step 2/6 : RUN apt-get update && apt-get install -y --no-install-recommends supervisor
---> Using cache
---> 380e5920f7cf
Step 3/6 : COPY ./docker/php/supervisord.conf /etc/supervisor
---> 73b5be38a5b3
Step 4/6 : COPY ./config/supervisor/* /etc/supervisor/conf.d
---> 8612c82bcc77
Removing intermediate container 1124a20b9c3a
---> 56aa767a0eac
Step 5/6 : CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/supervisord.conf"]
---> Running in 412ba596026e
Removing intermediate container 412ba596026e
---> db2ccf96cbb9
Successfully built db2ccf96cbb9
Successfully tagged superman_php:latest
Creating superman_php_1 ... done
Attaching to superman_php_1
php_1 | 2018-06-05 21:08:08,673 CRIT Supervisor running as root (no user in config file)
php_1 | 2018-06-05 21:08:08,673 INFO Included extra file "/etc/supervisor/conf.d/hello.conf" during parsing
php_1 | 2018-06-05 21:08:08,680 INFO RPC interface 'supervisor' initialized
php_1 | 2018-06-05 21:08:08,681 INFO RPC interface 'supervisor' initialized
php_1 | 2018-06-05 21:08:08,681 CRIT Server 'unix_http_server' running without any HTTP authentication checking
php_1 | 2018-06-05 21:08:08,681 INFO supervisord started with pid 1
php_1 | 2018-06-05 21:08:09,687 INFO spawned: 'php' with pid 9
php_1 | 2018-06-05 21:08:09,691 INFO spawned: 'hello_00' with pid 10
php_1 | 2018-06-05 21:08:09,710 INFO success: hello_00 entered RUNNING state, process has stayed up for > than 0 seconds (startsecs)
php_1 | 2018-06-05 21:08:10,725 INFO success: php entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)

As you can see above the process id of "php" is 9 and the process id of "hello_00" is 10. Let's see the content of log file.


$ tail -f message.log
...
Hello 251
Hello 252
Hello 253
...

Let's kill the process 10 see what happens.


$ docker exec -it superman_php_1 bash
# kill -9 10

Let's see what happened afterwards.


php_1  | 2018-06-05 21:09:16,488 INFO exited: hello_00 (terminated by SIGKILL; not expected)
php_1 | 2018-06-05 21:09:17,492 INFO spawned: 'hello_00' with pid 35
php_1 | 2018-06-05 21:09:18,494 INFO success: hello_00 entered RUNNING state, process has stayed up for > than 0 seconds (startsecs)

$ tail -f message.log
...
Hello 1
Hello 2
Hello 3
...