Skip to content

Updates to multi-process container topic #3026

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 24, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions _data/toc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,8 @@ guides:
title: Using Chef
- path: /engine/admin/puppet/
title: Using Puppet
- path: /engine/admin/using_supervisord/
title: Using Supervisor with Docker
- path: /engine/admin/multi-service_containers/
title: Run multiple services in a container
- path: /engine/admin/runmetrics/
title: Runtime metrics
- path: /engine/admin/ambassador_pattern_linking/
Expand Down
97 changes: 97 additions & 0 deletions engine/admin/multi-service_container.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
---
description: How to run more than one process in a container
keywords: docker, supervisor, process management
redirect_from:
- /engine/articles/using_supervisord/
- /engine/admin/using_supervisord/
title: Run multiple services in a container
---

A container's main running process is the `ENTRYPOINT` and/or `CMD` at the
end of the `Dockerfile`. It is generally recommended that you separate areas of
concern by using one service per container. That service may fork into multiple
processes (for example, Apache web server starts multiple worker processes).
It's ok to have multiple processes, but to get the most benefit out of Docker,
avoid one container being responsible for multiple aspects of your overall
application. You can connect multiple containers using user-defined networks and
shared volumes.

The container's main process is responsible for managing all processes that it
starts. In some cases, the main process isn't well-designed, and doesn't handle
"reaping" (stopping) child processes gracefully when the container exists. If
your process falls into this category, you can use the `--init` option when you
run the container. The `--init` flag inserts a tiny init-process into the
container as the main process, and handles reaping of all processes when the
container exits. Handling such processes this way is superior to using a
full-fledged init process such as `sysvinit`, `upstart`, or `systemd` to handle
process lifecycle within your container.

If you need to run more than one service within a container, you can accomplish
this in a few different ways.

- Put all of your commands in a wrapper script, complete with testing and
debugging information. Run the wrapper script as your `CMD`. This is a very
naive example. First, the wrapper script:

```bash
#!/bin/bash

# Start the first process
./my_first_process -D
status=$?
if [ $status -ne 0 ]; then
echo "Failed to start my_first_process: $status"
exit $status
fi

# Start the second process
./my_second_process -D
status=$?
if [ $status -ne 0 ]; then
echo "Failed to start my_second_process: $status"
exit $status
fi

# Naive check runs checks once a minute to see if either of the processes exited.
# This illustrates part of the heavy lifting you need to do if you want to run
# more than one service in a container. The container will exit with an error
# if it detects that either of the processes has exited.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is awesome 😍

while /bin/true; do
PROCESS_1_STATUS=$(ps aux |grep -q my_first_process)
PROCESS_2_STATUS=$(ps aux |grep -q my_second_process)
if [ $PROCESS_!_STATUS || $PROCESS_2_STATUS ]; then
echo "One of the processes has already exited."
exit -1
fi
sleep 60
done
```

Next, the Dockerfile:

```conf
FROM ubuntu:latest
COPY my_first_process my_first_process
COPY my_second_process my_second_process
COPY my_wrapper_script.sh my_wrapper_script.sh
CMD ./my_wrapper_script.sh
```

- Use a process manager like `supervisord`. This is a moderately heavy-weight
approach that requires you to package `supervisord` and its configuration in
your image (or base your image on one that includes `supervisord`), along with
the different applications it will manage. Then you start `supervisord`, which
manages your processes for you. Here is an example Dockerfile using this
approach, that assumes the pre-written `supervisord.conf`, `my_first_process`,
and `my_second_process` files all exist in the same directory as your
Dockerfile.

```conf
FROM ubuntu:latest
RUN apt-get update && apt-get install -y supervisor
RUN mkdir -p /var/log/supervisor
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY my_first_process my_first_process
COPY my_second_process my_second_process
CMD ["/usr/bin/supervisord"]
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely a fan of how lightweight this example is -- basically, if you want to run multiple processes, that's fine, here's an example of one application that can do so, but getting a "good" configuration for it is Up To You (Docker's not going to help you figure that out because it's Bad). 👍 ❤️

148 changes: 0 additions & 148 deletions engine/admin/using_supervisord.md

This file was deleted.

12 changes: 5 additions & 7 deletions engine/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Server 2016, or Windows 10.

### How do containers compare to virtual machines?

Containers and virtual machines (VMs) are complementary. VMs excel at providing extreme isolation (for example with hostile tenant applications where you need the ultimate break out prevention). Containers operate at the process level, which makes them very lightweight and perfect as a unit of software delivery. While VMs take minutes to boot, containers can often be started in less than a second.
Containers and virtual machines (VMs) are complementary. VMs excel at providing extreme isolation (for example with hostile tenant applications where you need the ultimate break out prevention). Containers operate at the process level, which makes them very lightweight and perfect as a unit of software delivery. While VMs take minutes to boot, containers can often be started in less than a second.

### What does Docker technology add to just plain LXC?

Expand Down Expand Up @@ -139,12 +139,10 @@ pattern](admin/ambassador_pattern_linking.md).

### How do I run more than one process in a Docker container?

Any capable process supervisor such as [http://supervisord.org/](
http://supervisord.org/), runit, s6, or daemontools can do the trick. Docker
will start up the process management daemon which will then fork to run
additional processes. As long as the processor manager daemon continues to run,
the container will continue to as well. You can see a more substantial example
[that uses supervisord here](admin/using_supervisord.md).
This approach is discouraged for most use cases. For maximum efficiency and
isolation, each container should address one specific area of concern. However,
if you need to run multiple services within a single container, see
[Run multiple services in a container](admin/multi-service_container.md).

### What platforms does Docker run on?

Expand Down