From 0f7cddee4d2e13e85dc8cc59d979dfac3cd70305 Mon Sep 17 00:00:00 2001 From: Thomas LEVEIL Date: Tue, 21 Feb 2017 03:32:12 +0100 Subject: [PATCH] get rid of forego As a side effect, this fixes the crash on restart if files referenced in previous generated configuration are now missing --- Dockerfile | 5 --- Dockerfile.alpine | 5 --- Procfile | 2 - docker-entrypoint.sh | 97 +++++++++++++++++++++++++++++++++++++++---- test/test_restart.py | 34 +++++++++++++++ test/test_restart.yml | 5 +++ 6 files changed, 128 insertions(+), 20 deletions(-) delete mode 100644 Procfile create mode 100644 test/test_restart.py create mode 100644 test/test_restart.yml diff --git a/Dockerfile b/Dockerfile index 6da4b03..a42a544 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,10 +13,6 @@ RUN apt-get update \ RUN echo "daemon off;" >> /etc/nginx/nginx.conf \ && sed -i 's/^http {/&\n server_names_hash_bucket_size 128;/g' /etc/nginx/nginx.conf -# Install Forego -ADD https://github.com/jwilder/forego/releases/download/v0.16.1/forego /usr/local/bin/forego -RUN chmod u+x /usr/local/bin/forego - ENV DOCKER_GEN_VERSION 0.7.3 RUN wget https://github.com/jwilder/docker-gen/releases/download/$DOCKER_GEN_VERSION/docker-gen-linux-amd64-$DOCKER_GEN_VERSION.tar.gz \ @@ -31,4 +27,3 @@ ENV DOCKER_HOST unix:///tmp/docker.sock VOLUME ["/etc/nginx/certs"] ENTRYPOINT ["/app/docker-entrypoint.sh"] -CMD ["forego", "start", "-r"] diff --git a/Dockerfile.alpine b/Dockerfile.alpine index 8715a2a..9f1546c 100644 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -10,10 +10,6 @@ RUN apk add --no-cache --virtual .run-deps \ RUN echo "daemon off;" >> /etc/nginx/nginx.conf \ && sed -i 's/^http {/&\n server_names_hash_bucket_size 128;/g' /etc/nginx/nginx.conf -# Install Forego -ADD https://github.com/jwilder/forego/releases/download/v0.16.1/forego /usr/local/bin/forego -RUN chmod u+x /usr/local/bin/forego - ENV DOCKER_GEN_VERSION 0.7.3 RUN wget --quiet https://github.com/jwilder/docker-gen/releases/download/$DOCKER_GEN_VERSION/docker-gen-alpine-linux-amd64-$DOCKER_GEN_VERSION.tar.gz \ @@ -28,4 +24,3 @@ ENV DOCKER_HOST unix:///tmp/docker.sock VOLUME ["/etc/nginx/certs"] ENTRYPOINT ["/app/docker-entrypoint.sh"] -CMD ["forego", "start", "-r"] diff --git a/Procfile b/Procfile deleted file mode 100644 index 29fe166..0000000 --- a/Procfile +++ /dev/null @@ -1,2 +0,0 @@ -dockergen: docker-gen -watch -notify "nginx -s reload" /app/nginx.tmpl /etc/nginx/conf.d/default.conf -nginx: nginx diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 6353314..1c3f110 100755 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -1,7 +1,86 @@ #!/bin/bash -set -e +############################################################################### +# +# Signals: +# - HUP: reload docker-gen +# - USR1: reload nginx +# +############################################################################### +set -u -# Warn if the DOCKER_HOST socket does not exist +function start_docker_gen { + echo "~~~~~ Starting docker-gen ~~~~~" + { + while true; do + docker-gen -watch -notify "kill -USR1 1" /app/nginx.tmpl /etc/nginx/conf.d/default.conf + echo "docker-gen exited" + echo "~~~~~ Restarting docker-gen ~~~~~~" + done + } & +} + +function start_nginx { + echo "~~~~~ Starting nginx ~~~~~" + { + while true; do + nginx + echo "nginx exited, checking config..." + if nginx -t; then + echo "~~~~~ Restarting nginx ~~~~~~" + else + exit 1 + fi + done + } & +} + + +function reload_nginx { + if pgrep nginx >/dev/null; then + # nginx is already running + echo "~~~~~ Reloading nginx ~~~~~" + pkill -HUP nginx + else + start_nginx + fi +} + +############################################################################### + +function handle_SIGHUP { + echo "~~~~~ Signal HUP received ~~~~~" + if ! pgrep nginx >/dev/null; then + echo "~~~~~ Starting nginx ~~~~~" + nginx & + fi + pkill -HUP docker-gen # forward SIGHUP to docker-gen + wait +} + +function handle_SIGUSR1 { + echo "~~~~~ Signal USR1 received ~~~~~" + reload_nginx + wait +} + +############################################################################### + +# If the user has run provided a command, run it instead +if [ $# -ne 0 ]; then + exec "$@" +fi + +cat <<-OEBANNER + ███╗ ██╗ ██████╗ ██╗███╗ ██╗██╗ ██╗ ██████╗ ██████╗ ██████╗ ██╗ ██╗██╗ ██╗ + ████╗ ██║██╔════╝ ██║████╗ ██║╚██╗██╔╝ ██╔══██╗██╔══██╗██╔═══██╗╚██╗██╔╝╚██╗ ██╔╝ + ██╔██╗ ██║██║ ███╗██║██╔██╗ ██║ ╚███╔╝█████╗██████╔╝██████╔╝██║ ██║ ╚███╔╝ ╚████╔╝ + ██║╚██╗██║██║ ██║██║██║╚██╗██║ ██╔██╗╚════╝██╔═══╝ ██╔══██╗██║ ██║ ██╔██╗ ╚██╔╝ + ██║ ╚████║╚██████╔╝██║██║ ╚████║██╔╝ ██╗ ██║ ██║ ██║╚██████╔╝██╔╝ ██╗ ██║ + ╚═╝ ╚═══╝ ╚═════╝ ╚═╝╚═╝ ╚═══╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ +OEBANNER + + +# Error if the DOCKER_HOST socket does not exist if [[ $DOCKER_HOST == unix://* ]]; then socket_file=${DOCKER_HOST#unix://} if ! [ -S $socket_file ]; then @@ -10,13 +89,15 @@ if [[ $DOCKER_HOST == unix://* ]]; then Typically you should run your jwilder/nginx-proxy with: \`-v /var/run/docker.sock:$socket_file:ro\` See the documentation at http://git.io/vZaGJ EOT - socketMissing=1 + exit 1 fi fi -# If the user has run the default command and the socket doesn't exist, fail -if [ "$socketMissing" = 1 -a "$1" = forego -a "$2" = start -a "$3" = '-r' ]; then - exit 1 -fi -exec "$@" +trap handle_SIGHUP HUP +trap handle_SIGUSR1 USR1 +trap "exit 0" TERM + +rm /etc/nginx/conf.d/default.conf +start_docker_gen +wait \ No newline at end of file diff --git a/test/test_restart.py b/test/test_restart.py new file mode 100644 index 0000000..9b8c522 --- /dev/null +++ b/test/test_restart.py @@ -0,0 +1,34 @@ +import pytest +import time + + +def test_dockergen_is_running(docker_compose): + assert docker_compose.containers.get("reverseproxy").exec_run("pgrep docker-gen") != '' + + +def test_nginx_is_running(docker_compose): + assert docker_compose.containers.get("reverseproxy").exec_run("pgrep nginx") != '' + + +def test_nginx_answers_with_503(docker_compose, nginxproxy): + r = nginxproxy.get("http://nginx-proxy/") + assert r.status_code == 503 + + +def test_survive_restart(docker_compose, nginxproxy): + docker_compose.containers.get("reverseproxy").restart() + time.sleep(2) # give time to eventually fail + assert docker_compose.containers.get("reverseproxy").status == "running" + + +def test_dockergen_is_still_running(docker_compose): + assert docker_compose.containers.get("reverseproxy").exec_run("pgrep -c docker-gen") != '' + + +def test_nginx_is_still_running(docker_compose): + assert docker_compose.containers.get("reverseproxy").exec_run("pgrep -c nginx") != '' + + +def test_nginx_still_answers_with_503(docker_compose, nginxproxy): + r = nginxproxy.get("http://nginx-proxy/") + assert r.status_code == 503 diff --git a/test/test_restart.yml b/test/test_restart.yml new file mode 100644 index 0000000..0457fb7 --- /dev/null +++ b/test/test_restart.yml @@ -0,0 +1,5 @@ +reverseproxy: + container_name: reverseproxy + image: jwilder/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro