#!/bin/sh # The container's entrypoint: runs netwatch-server and nginx side by # side. TERM or INT stops both, and the container exits 0 if both exit # cleanly. If either exits on its own, the other is stopped too and the # container exits non-zero, so the platform restarts it instead of # leaving it half up. # # No set -e: kill and wait return non-zero here in normal operation. set -u # PORT is the public port nginx listens on, 8080 when unset or empty. # nginx would take a value such as localhost or unix:/tmp/x.sock as an # address and start anyway, so anything but digits stops the container # here, before either process starts. export PORT="${PORT:-8080}" case "$PORT" in *[!0-9]*) echo "entrypoint: PORT must be a port number, not '$PORT'" >&2 exit 1 ;; esac # A stop signal is only noted here; the loop below acts on it. stop_requested="" trap 'stop_requested=yes' TERM INT # netwatch-server runs as the netwatch user and listens on loopback # only, on a port other than the public one; nginx.conf proxies to this # address. The netwatch user has no login shell, hence -s /bin/sh. # busybox su replaces itself with the command instead of staying on as # its parent, so $! is the server's own PID. BIND_ADDRESS=127.0.0.1 PORT=8081 \ su -s /bin/sh netwatch -c 'exec netwatch-server' & backend=$! # nginx starts through the nginx image's own entrypoint, which applies # the image's start-up configuration and then replaces itself with # nginx. Part of that start-up configuration renders nginx.conf into # conf.d with nginx listening on PORT. NGINX_ENVSUBST_FILTER limits # that rendering to PORT: a variable nginx itself uses, such as $uri, # would otherwise be replaced by an environment variable of the same # name. NGINX_ENVSUBST_FILTER='^PORT$' \ /docker-entrypoint.sh nginx -g 'daemon off;' & nginx=$! running() { kill -0 "$1" 2>/dev/null } # POSIX sh cannot wait for whichever of two children exits first, so # look once a second. The shell collects a child that has exited while # it runs sleep, and running() is false for that child from then on. while [ -z "$stop_requested" ] && running "$backend" && running "$nginx"; do sleep 1 done # Stop both, then wait until neither is left. kill -TERM "$backend" "$nginx" 2>/dev/null while running "$backend" || running "$nginx"; do sleep 1 done wait "$backend" backend_status=$? wait "$nginx" nginx_status=$? echo "entrypoint: netwatch-server exited $backend_status," \ "nginx exited $nginx_status" # Success is a requested stop that both processes exited cleanly from. if [ -n "$stop_requested" ] && [ "$backend_status" -eq 0 ] && [ "$nginx_status" -eq 0 ]; then exit 0 fi exit 1