Skip to content
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

Updates to multi-process container topic #3026

Merged
merged 2 commits into from
Apr 24, 2017
Merged

Updates to multi-process container topic #3026

merged 2 commits into from
Apr 24, 2017

Conversation

mdlinville
Copy link

Proposed changes

We should more strongly recommend against running multiple processes in a container

We should not specifically advocate for supervisord either.

Fixes #758.

Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

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

left some thoughts


A container's running process is usually the `ENTRYPOINT` and/or `CMD` at the
end of the `Dockerfile`. It is generally recommended that you separate areas of
concern by using one container per process, and connect those containers using
Copy link
Member

Choose a reason for hiding this comment

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

We may want to tweak a bit w.r.t. "one process per container"; it may be a bit more nuanced; it's a single "service" per container. That service may fork into multiple processes (for example, Apache starts multiple worker processes). It's ok to have multiple processes, but the concept of Docker is to not have a container be responsible for multiple services / tasks.

Slightly orthogonal:

The container's main process is responsible for managing all processes that it started. In some cases, the main process isn't well-designed, and doesn't handle "reaping" of child processes well when the container exists. If you're dealing with such a process, you can use the --init option, which inserts a tiny init-process in the container as the main process, and handles "reaping" of all processes when the container exits. There's no reason to use a full-fledged init process (Sysvinit, upstart, systemd) for that.

FROM ubuntu:latest
COPY my_first_process my_first_process
COPY my_second_process my_second_process
CMD ./my_first_process && ./my_second_process
Copy link
Member

Choose a reason for hiding this comment

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

This probably won't work, because it runs the second process after the first one exits; you probably have to daemonize the first one (./foobar &) to keep it running in the background.

I'm actually not sure we should recommend this, as this is a DYI init process, without reaping, and without any management of (e.g.) logging, startup ordering, keeping processes up, etc.

I'd prefer to keep the supervisord page as a possible option to run multiple processes, for those that need it, as long as we reiterate that generally running a single service in a container is the way to go.

Probably we can come up with some examples how to split those services over multiple containers (e.g. have a sshd service container that allows you to rsync files in a volume that's used by another container)

@mdlinville
Copy link
Author

I added your supplementary info, removed the example you didn't like, tweaked the topic name.

@thaJeztah
Copy link
Member

Thanks! The introduction looks better; Let me call in @tianon for help as well, he may have good suggestions for describing this ❤️

Copy link
Contributor

@tianon tianon left a comment

Choose a reason for hiding this comment

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

Overall seems sane to me, just a few questions/clarifications. 👍 ❤️

# Naive check to see if either of them exited immediately
PROCESS_!_STATUS=$(ps aux |grep -q my_first_process)
PROCESS_2_STATUS=$(ps aux |grep -q my_second_process)
if [ $PROCESS_!_STATUS || $PROCESS_2_STATUS ];
Copy link
Contributor

Choose a reason for hiding this comment

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

I think these PROCESS_!_STATUS instances were intended to be PROCESS_1_STATUS. 😄

echo "One of the processes has already exited."
exit -1
fi
```
Copy link
Contributor

Choose a reason for hiding this comment

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

This script, as written, will exit immediately and thus PID 1 will exit and the two services started will be killed. Is that the intention for this example? The hacky way I usually see folks solve this is by putting this ps logic into a loop or using something silly like tail -f to just keep the container alive (tail -f /dev/null is the cheekiest example of "keep this container from dying" that I've seen to date 😄).

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). 👍 ❤️

@mdlinville
Copy link
Author

Thanks @tianon I have updated the instructions and made the process check live in a loop, and also left some comments about how painful and hacky that is. ;)

Copy link
Contributor

@tianon tianon left a comment

Choose a reason for hiding this comment

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

Looks neato to me! 👍 ❤️

Lots less validation of supervisord and lots more "this is hairy and here's a few reasons you don't want to do it". 🤘

# 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 😍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants