-
Notifications
You must be signed in to change notification settings - Fork 212
Home
The s6-overlay-builder project is a series of init scripts and utilities to ease creating Docker images with s6 as a process supervisor.
Build the following Dockerfile and try this guy out:
FROM ubuntu
ADD https://github.com/just-containers/s6-overlay-builder/releases/download/v1.8.5/s6-overlay-portable-amd64.tar.gz /tmp/
RUN tar xzf /tmp/s6-overlay-portable-amd64.tar.gz -C /
RUN apt-get update && \
apt-get install -y nginx && \
echo "daemon off;" >> /etc/nginx/nginx.conf
ENTRYPOINT ["/init"]
CMD ["nginx"]
docker-host $ docker build -t demo .
docker-host $ docker run --name s6demo -d -p 80:80 demo
docker-host $ docker top s6demo acxf
PID TTY STAT TIME COMMAND
3788 ? Ss 0:00 \_ s6-svscan
3827 ? S 0:00 | \_ foreground
3834 ? S 0:00 | | \_ foreground
3879 ? S 0:00 | | \_ nginx
3880 ? S 0:00 | | \_ nginx
3881 ? S 0:00 | | \_ nginx
3882 ? S 0:00 | | \_ nginx
3883 ? S 0:00 | | \_ nginx
3828 ? S 0:00 | \_ s6-supervise
3829 ? S 0:00 | \_ s6-supervise
3830 ? Ss 0:00 | \_ s6-log
docker-host $ curl --head http://127.0.0.1/
HTTP/1.1 200 OK
Server: nginx/1.4.6 (Ubuntu)
Date: Thu, 26 Mar 2015 14:57:34 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 04 Mar 2014 11:46:45 GMT
Connection: keep-alive
ETag: "5315bd25-264"
Accept-Ranges: bytes
The project has the following goals:
- Make it easy to image authors to take advantage of s6
- Still operate like other Docker images
- The s6-overlay provides proper
PID 1
functionality- You'll never have zombie processes hanging around in your container, they will be properly cleaned up.
- Multiple processes in a single container
- Able to operate in "The Docker Way"
- Usable with all base images - Ubuntu, CentOS, Fedora, and even Busybox.
- Distributed as a single .tar.gz file, to keep your image's number of layers small.
One of the oft-repeated Docker mantras is "one process per container", but we disagree. There's nothing inherently bad about running multiple processes in a container. The more abstract "one thing per container" is our policy - a container should do one thing, such as "run a chat service" or "run gitlab." This may involve multiple processes, which is fine.
The other reason image authors shy away from process supervisors is they believe a process supervisor must restart failed services, meaning the Docker container will never die.
This does effectively break the Docker ecosystem - most images run one process that will exit when there's an error. By exiting on error, you allow the system administrator to handle failures however they prefer. If your image will never exit, you now need some alternative method of error recovery and failure notification.
Our policy is that if "the thing" fails, then the container should fail, too. We do this by determining which processes can restart, and which should bring down the container. For example, if cron
or syslog
fails, your container can most likely restart it without any ill effects, but if ejabberd
fails, the container should exit so the system administrator can take action.
Our interpretation of "The Docker Way" is thus:
- Containers should do one thing
- Containers should stop when that thing stops
and our init system is designed to do exactly that! Your images will still behave like other Docker images and fit in with
The project is distributed as a standard .tar.gz file, which you extract at the root of your image. Afterwards, set your ENTRYPOINT
to /init
Right now, we recommend using Docker's ADD
directive instead of running wget
or curl
in a RUN
directive - Docker is able to handle the https URL when you use ADD
, whereas your base image might not be able to use https, or might not even have wget
or curl
installed at all.
From there, you have a couple of options:
- Run your service/program as your image's
CMD
- Write a service script
Using CMD
is a really convenient way to run take advantage of the s6-overlay. Your CMD
can be given at build-time in the Dockerfile, or at runtime on the command line, either way is fine - it will be run under the s6 supervisor, and when it fails or exits, the container will exit. You can even run interactive programs under the s6 supervisor!
For example:
FROM busybox
ADD https://github.com/just-containers/s6-overlay-builder/releases/download/v1.8.5/s6-overlay-portable-amd64.tar.gz /tmp/
RUN tar xzf /tmp/s6-overlay-portable-amd64.tar.gz -C /
ENTRYPOINT ["/init"]
docker-host $ docker build -t s6demo .
docker-host $ docker run -ti s6demo /bin/sh
[fix-attrs.d] applying owners & permissions fixes...
[fix-attrs.d] 00-runscripts: applying...
[fix-attrs.d] 00-runscripts: exited 0.
[fix-attrs.d] done.
[cont-init.d] executing container initialization scripts...
[cont-init.d] done.
[services.d] starting services
[services.d] done.
/ # ps
PID USER COMMAND
1 root s6-svscan -t0 /var/run/s6/services
21 root foreground if /etc/s6/init/init-stage2-redirfd foreground if s6-echo [fix-attrs.d] applying owners & permissions fixes.
22 root s6-supervise s6-fdholderd
23 root s6-supervise s6-svscan-log
24 nobody s6-log -bp -- t /var/log/s6-uncaught-logs
28 root foreground s6-setsid -gq -- with-contenv /bin/sh import -u ? if s6-echo -- /bin/sh exited ${?} foreground s6-svscanctl -t
73 root /bin/sh
76 root ps
/ # exit
/bin/sh exited 0
docker-host $
TODO