From d6286acdb21a23bac135d78ef00969ba7a3d5394 Mon Sep 17 00:00:00 2001 From: Daniel Hodgson Date: Thu, 4 Mar 2021 18:00:40 -0800 Subject: [PATCH] Fix for issue #420, entrypoint has a race condition where installation fails if DB is not ready in time. --- Dockerfile-alpine.template | 3 +++ Dockerfile-debian.template | 3 +++ docker-entrypoint.sh | 25 +++++++++++++++++++++++++ 3 files changed, 31 insertions(+) diff --git a/Dockerfile-alpine.template b/Dockerfile-alpine.template index 0a9484d4af..11caae156c 100644 --- a/Dockerfile-alpine.template +++ b/Dockerfile-alpine.template @@ -128,5 +128,8 @@ RUN set -ex; \ COPY *.sh upgrade.exclude / COPY config/* /usr/src/nextcloud/config/ +# wait-for-it.sh is used for waiting on networked DB's to become available during install +ADD https://raw.githubusercontent.com/vishnubob/wait-for-it/81b1373f17855a4dc21156cfe1694c31d7d1792e/wait-for-it.sh /usr/bin/wait-for-it + ENTRYPOINT ["/entrypoint.sh"] CMD ["%%CMD%%"] diff --git a/Dockerfile-debian.template b/Dockerfile-debian.template index a6c4e21590..5ce9079c9c 100644 --- a/Dockerfile-debian.template +++ b/Dockerfile-debian.template @@ -145,5 +145,8 @@ RUN set -ex; \ COPY *.sh upgrade.exclude / COPY config/* /usr/src/nextcloud/config/ +# wait-for-it.sh is used for waiting on networked DB's to become available during install +ADD https://raw.githubusercontent.com/vishnubob/wait-for-it/81b1373f17855a4dc21156cfe1694c31d7d1792e/wait-for-it.sh /usr/bin/wait-for-it + ENTRYPOINT ["/entrypoint.sh"] CMD ["%%CMD%%"] diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index bee572c2e5..d3cdff351a 100755 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -19,6 +19,21 @@ run_as() { fi } +#Test for a port in host string, set default port if none provided +get_host_string() { + local host_string="$1" + local default_port="$2" + local host="" + local port="" + + case "$host_string" in + (*:*) host="$host_string";; + (*) host="${host_string}:${default_port}";; + esac + + echo "$host" +} + # usage: file_env VAR [DEFAULT] # ie: file_env 'XYZ_DB_PASSWORD' 'example' # (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of @@ -139,17 +154,27 @@ if expr "$1" : "apache" 1>/dev/null || [ "$1" = "php-fpm" ] || [ "${NEXTCLOUD_UP # shellcheck disable=SC2016 install_options=$install_options' --database mysql --database-name "$MYSQL_DATABASE" --database-user "$MYSQL_USER" --database-pass "$MYSQL_PASSWORD" --database-host "$MYSQL_HOST"' install=true + network_db=true + db_host=$(get_host_string $MYSQL_HOST 3306) #Add default port for MySQL to host string if no port is provided elif [ -n "${POSTGRES_DB+x}" ] && [ -n "${POSTGRES_USER+x}" ] && [ -n "${POSTGRES_PASSWORD+x}" ] && [ -n "${POSTGRES_HOST+x}" ]; then echo "Installing with PostgreSQL database" # shellcheck disable=SC2016 install_options=$install_options' --database pgsql --database-name "$POSTGRES_DB" --database-user "$POSTGRES_USER" --database-pass "$POSTGRES_PASSWORD" --database-host "$POSTGRES_HOST"' install=true + network_db=true + db_host=$(get_host_string $POSTGRES_HOST 5432) #Add default port for Postgres to host string if no port is provided fi if [ "$install" = true ]; then echo "starting nextcloud installation" max_retries=10 try=0 + + if [ "$network_db" = true ]; then + #Wait indefinitely for DB to become available by default, otherwise wait seconds defined by $WAIT_TIMEOUT + wait-for-it -t ${WAIT_TIMEOUT:-0} $db_host -- echo "Database service online" + fi + until run_as "php /var/www/html/occ maintenance:install $install_options" || [ "$try" -gt "$max_retries" ] do echo "retrying install..."