Multi-process Docker Service

Kubernetes has Pods; standard Docker Services do not. This poses a problem when multiple processes should have access to the same resources, particularly volumes. While the solution below doesn’t solve all problems Pods do, it does make it possible for two processes to access the same volume.

Here Supervisor is used to control multiple processes within the same container, and while doing so we are going to set it up in a way to ensure a few things:

  • the output for all processes go to stout
  • when a program dies, it is restarted

Install requirements

By default Supervisor writes logs to files. It doesn’t support logging to stdout by default. The package supervisor-stdout fixes this shortcoming by listening to log events and writing them to stdout.

Install both these packages with the command:

pip install supervisor supervisor-stdout

Base configuration

Since we want this to run within a Docker container, Supervisor should not fork into the background. Start the file /etc/supervisor/supervisord.conf with:

[supervisord]
nodaemon=true

Next, setup the event listener. The following block will listen for PROCESS_LOG events:

[eventlistener:stdout]
priority = 1
command = supervisor_stdout
buffer_size = 100
events = PROCESS_LOG
result_handler = supervisor_stdout:event_handler

Finally, add your program blocks. Here, we’ll verify that stdout and stderr are redirected properly with two separate programs:

[program:test_stderr]
priority=10
command=/bin/bash -c 'while [ 1 ]; do date 1>&2; sleep 10; done;'
startsecs=10
exitcodes=0
stdout_events_enabled = true
stderr_events_enabled = true


[program:test_stdout]
priority=10
command=/bin/bash -c 'while [ 1 ]; do date; sleep 10; done;'
startsecs=10
exitcodes=0
stdout_events_enabled = true
stderr_events_enabled = true

Copy one of those blocks and change the command to run for your particular application.

Output will look something like this:

root@24b74c2e5f51:/# supervisord -c /etc/supervisor/supervisord.conf
2017-11-06 14:02:28,996 CRIT Supervisor running as root (no user in config file)
2017-11-06 14:02:28,999 INFO supervisord started with pid 207
2017-11-06 14:02:30,003 INFO spawned: 'stdout' with pid 210
2017-11-06 14:02:30,006 INFO spawned: 'test_stdout' with pid 211
2017-11-06 14:02:30,011 INFO spawned: 'test_stderr' with pid 213
2017-11-06 14:02:31,093 INFO success: stdout entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
test_stderr stderr | Mon Nov  6 14:02:30 UTC 2017
test_stdout stdout | Mon Nov  6 14:02:30 UTC 2017
2017-11-06 14:02:40,021 INFO success: test_stdout entered RUNNING state, process has stayed up for > than 10 seconds (startsecs)
2017-11-06 14:02:40,021 INFO success: test_stderr entered RUNNING state, process has stayed up for > than 10 seconds (startsecs)
test_stderr stderr | Mon Nov  6 14:02:40 UTC 2017
test_stdout stdout | Mon Nov  6 14:02:40 UTC 2017

Docker CMD

Instead of calling your app in CMD, launch Supervisor:

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