Skip to content

Commit 3a76c4b

Browse files
author
Bryan Latten
committed
RFC > Dockerfile: removed supervisor, added S6
Do not merge until workerized processes are converted from supervisor behavior
1 parent 9c7e204 commit 3a76c4b

File tree

16 files changed

+153
-72
lines changed

16 files changed

+153
-72
lines changed

Dockerfile

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,30 +7,49 @@ ENV SIGNAL_BUILD_STOP=99 \
77
CONTAINER_ROLE=web \
88
CONF_NGINX_SITE="/etc/nginx/sites-available/default" \
99
CONF_NGINX_SERVER="/etc/nginx/nginx.conf" \
10-
NOT_ROOT_USER=docker
10+
NOT_ROOT_USER=www-data \
11+
S6_BEHAVIOUR_IF_STAGE2_FAILS=2 \
12+
S6_KILL_FINISH_MAXTIME=5000 \
13+
S6_KILL_GRACETIME=3000
1114

12-
# Create an unprivileged user
13-
RUN useradd -r -s /bin/false $NOT_ROOT_USER
1415

16+
# Ensure base system is up to date
1517
RUN apt-get update && \
16-
apt-get install -yq \
17-
openssl \
18-
ca-certificates \
18+
apt-get upgrade -yqq && \
19+
# Install pre-reqs \
20+
apt-get install -yqq \
1921
software-properties-common \
20-
supervisor \
21-
nano \
2222
&& \
23-
rm -rf /var/lib/apt/lists/*
24-
25-
# Install latest nginx (development PPA is actually mainline development)
26-
RUN add-apt-repository ppa:nginx/development -y && \
27-
apt-get update -yq && \
28-
apt-get install -yq nginx \
23+
# Install latest nginx (development PPA is actually mainline development) \
24+
add-apt-repository ppa:nginx/development -y && \
25+
apt-get update -yqq && \
26+
apt-get install -yqq nginx \
2927
&& \
30-
rm -rf /var/lib/apt/lists/*
28+
# Perform cleanup, ensure unnecessary packages are removed \
29+
apt-get remove --purge -yq \
30+
manpages \
31+
manpages-dev \
32+
man-db \
33+
patch \
34+
make \
35+
unattended-upgrades \
36+
python* \
37+
&& \
38+
apt-get autoclean -y && \
39+
apt-get autoremove -y && \
40+
rm -rf /var/lib/{cache,log}/ && \
41+
rm -rf /var/lib/apt/lists/ && \
42+
rm -rf /tmp/* /var/tmp/*
3143

32-
# # Overlay the root filesystem from this repo
44+
# Overlay the root filesystem from this repo
3345
COPY ./container/root /
3446

47+
# Add S6 overlay build, to avoid having to build from source
48+
RUN tar xzf /tmp/s6-overlay-amd64.tar.gz -C / && \
49+
rm /tmp/s6-overlay-amd64.tar.gz
50+
3551
EXPOSE 80
52+
53+
# NOTE: intentionally NOT using s6 init as the entrypoint
54+
# This would prevent container debugging if any of those service crash
3655
CMD ["/bin/bash", "/run.sh"]

README.md

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,60 @@
11
# docker-nginx
2-
Provides base OS, patches and stable nginx for quick and easy spinup
2+
Provides base OS, patches and stable nginx for quick and easy spinup.
3+
Integrates S6 process supervisor for zombie reaping (as PID 1) and boot coordination.
4+
@see https://github.com/just-containers/s6-overlay
35

6+
### Expectations
7+
8+
Applications using this as a container parent must copy their html/app into the `/var/www/html` folder
9+
10+
11+
12+
### Environment Variables
413

514
Variable | Example | Description
615
--- | --- | ---
716
`SERVER_MAX_BODY_SIZE` | `SERVER_MAX_BODY_SIZE=4M` | Allows the downstream application to specify a non-default `client_max_body_size` configuration for the `server`-level directive in `/etc/nginx/sites-available/default`
817
`SERVER_INDEX` | `SERVER_INDEX index.html index.html index.php` | Changes the default pages to hit for folder and web roots
9-
`SERVER_APP_NAME` | `SERVER_APP_NAME='view'` | Sets a kv pair to be consumed by logging service for easy parsing and searching
18+
`SERVER_APP_NAME` | `SERVER_APP_NAME='view'` | Gets appended to the default logging format
1019
`SERVER_GZIP_OPTIONS` | `SERVER_GZIP_OPTIONS=1` | Allows default set of static content to be served gzipped
1120
`SERVER_SENDFILE` | `SERVER_SENDFILE=off` | Allows runtime to specify value of nginx's `sendfile` (default, on)
1221
`SERVER_KEEPALIVE` | `SERVER_KEEPALIVE=30` | Define HTTP 1.1's keepalive timeout
1322
`SERVER_WORKER_CONNECTIONS` | `SERVER_WORKER_CONNECTIONS=2048` | Sets up the number of connections for worker processes
1423
`SERVER_LOG_MINIMAL` | `SERVER_LOG_MINIMAL=1` | Minimize the logging format, appropriate for development environments
24+
`S6_KILL_FINISH_MAXTIME` | `S6_KILL_FINISH_MAXTIME=1000` | Wait time (in ms) for zombie reaping before sending a kill signal
25+
`S6_KILL_GRACETIME` | `S6_KILL_GRACETIME=500` | Wait time (in ms) for S6 finish scripts before sending kill signal
26+
27+
28+
### Startup/Runtime Modification
1529

30+
To inject changes just before runtime, shell scripts (ending in .sh) may be placed into the
31+
`/etc/cont-init.d` folder. For example, the above environment variables are used to drive nginx configuration at runtime.
32+
As part of the process manager, these scripts are run in advance of the supervised processes. @see https://github.com/just-containers/s6-overlay#executing-initialization-andor-finalization-tasks
1633

17-
### Runtime Commands
1834

19-
To inject things into the runtime process, add shell scripts (ending in .sh) into the
20-
`/run.d` folder. These will be executed during container start.
35+
### Advanced Modification
2136

22-
- If script terminates with a non-zero exit code, container will stop, terminating with the script's exit code, unless...
23-
- If script terminates with exit code of $SIGNAL_BUILD_STOP (99), this will signal the container to stop cleanly. This can be used for multi-stage builds that can be committed
37+
More advanced changes can take effect using the run.d system. Similar to the `/etc/cont-init.d/` script system, any scripts (ending in .sh) in the `/run.d/` folder will be executed ahead of the S6 initialization.
2438

39+
- If run.d script terminates with a non-zero exit code, container will stop, terminating with the script's exit code, unless...
40+
- If script terminates with exit code of $SIGNAL_BUILD_STOP (99), this will signal the container to stop cleanly. This can be used for multi-stage builds
2541

26-
### Long-running processes (workers)
42+
43+
### Long-running processes (workers + crons)
44+
45+
This container image can be shared between web and non-web processes. An example use case would be
46+
a web service and codebase that also has a few crons and background workers. To reuse this container for
47+
those types of workloads:
2748

2849
`docker run {image_id} /worker.sh 3 /bin/binary -parameters -that -binary -receives`
2950

30-
Runs 3 copies of `/bin/binary` that receives any arguments as parameters
51+
Runs `3` copies of `/bin/binary` that receives the parameters `-parameters -that -binary -receives`
52+
53+
54+
### Container Organization
55+
56+
Besides the instructions contained in the Dockerfile, the majority of this
57+
container's use is in configuration and process. The `./container/root` repo directory is overlayed into a container during build. Adding additional files
58+
to the folders in there will be present in the final image.
59+
60+
Nginx is currently set up as an S6 service in `/etc/services-available/nginx`, during default environment conditions, it will symlink itself to be supervised under `/etc/services.d/nginx`. When running under worker entrypoint (`worker.sh`), it will not be S6's `service.d` folder to be supervised.

container/root/run.d/10-nginx.sh renamed to container/root/etc/cont-init.d/10-nginx.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/bin/bash
1+
#!/usr/bin/with-contenv bash
22

33
if [[ $SERVER_APP_NAME ]]
44
then
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/dev/stdout false www-data 0644 2700
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Shouldn't need to be two separate statements, something is requiring it
2+
/tmp/.nginx true www-data 0644 2700
3+
/tmp true www-data 0644 2700
4+

container/root/etc/nginx/nginx.conf

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@
77
# add to the run.d/nginx script
88
#############################################################
99

10-
user www-data;
10+
# Only set when running with superuser permissions, otherwise causes a warning
11+
# user www-data;
12+
1113
worker_processes auto;
1214

13-
pid /tmp/nginx.pid;
15+
pid /tmp/.nginx/nginx.pid;
1416

1517
events {
1618
# @see http://serverfault.com/questions/209014/how-can-i-observe-what-nginx-is-doing-to-solve-1024-worker-connections-are-n
@@ -28,7 +30,7 @@ http {
2830

2931
log_format minimal '$request_method $request_uri $status';
3032

31-
error_log /dev/stdout info;
33+
error_log /dev/stdout;
3234
access_log /dev/stdout main;
3335

3436
sendfile on;
@@ -38,11 +40,11 @@ http {
3840

3941
#gzip on;
4042

41-
client_body_temp_path /tmp/client_body;
42-
fastcgi_temp_path /tmp/fastcgi_temp;
43-
proxy_temp_path /tmp/proxy_temp;
44-
scgi_temp_path /tmp/scgi_temp;
45-
uwsgi_temp_path /tmp/uwsgi_temp;
43+
client_body_temp_path /tmp/.nginx/client_body;
44+
fastcgi_temp_path /tmp/.nginx/fastcgi_temp;
45+
proxy_temp_path /tmp/.nginx/proxy_temp;
46+
scgi_temp_path /tmp/.nginx/scgi_temp;
47+
uwsgi_temp_path /tmp/.nginx/uwsgi_temp;
4648

4749
# Everything available is enabled in the container
4850
include /etc/nginx/sites-available/*;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/usr/bin/execlineb -S1
2+
3+
# @see https://github.com/just-containers/s6-overlay/issues/101
4+
if { s6-test ${1} -ne 0 }
5+
if { s6-test ${1} -ne 256 }
6+
7+
s6-svscanctl -t /var/run/s6/services
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/usr/bin/execlineb -P
2+
s6-setuidgid www-data
3+
4+
nginx -g "daemon off;"

container/root/etc/services.d/.gitkeep

Whitespace-only changes.

container/root/init.sh

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,25 +8,30 @@ STATUS=0
88
# When .sh run scripts fail (exit non-zero), container run will fail
99
# NOTE: if a .sh script exits with 99, this is a stop signal, container must exit cleanly
1010

11-
for file in $RUN_SCRIPTS/*.sh; do
11+
if ls ${RUN_SCRIPTS}/*.sh &>/dev/null
12+
then
13+
for file in $RUN_SCRIPTS/*.sh; do
1214

13-
echo "[init] executing ${file}"
15+
echo "[init] executing ${file}"
1416

15-
# Note: -e will enforce that any subcommand that fails will fail the entire script run
16-
/bin/bash -e $file
17+
# Note: -e will enforce that any subcommand that fails will fail the entire script run
18+
/bin/bash -e $file
1719

18-
STATUS=$? # Captures exit code from script that was run
20+
STATUS=$? # Captures exit code from script that was run
1921

20-
if [[ $STATUS == $SIGNAL_BUILD_STOP ]]
21-
then
22-
echo "[init] exit signalled - ${file}"
23-
exit $STATUS
24-
fi
22+
if [[ $STATUS == $SIGNAL_BUILD_STOP ]]
23+
then
24+
echo "[init] exit signalled - ${file}"
25+
exit $STATUS
26+
fi
2527

26-
if [[ $STATUS != 0 ]]
27-
then
28-
echo "[init] failed executing - ${file}"
29-
exit $STATUS
30-
fi
28+
if [[ $STATUS != 0 ]]
29+
then
30+
echo "[init] failed executing - ${file}"
31+
exit $STATUS
32+
fi
3133

32-
done
34+
done
35+
else
36+
echo "[init] no run.d scripts"
37+
fi

0 commit comments

Comments
 (0)