Enhancement: speed-up docker container startup (#11134)

This alters the retry/backoff logic in the init-wait-for-db script to be more
optimistic about database availability. During regular deployment and
operations of paperless-ngx, it's common to restart the application server with
the database instance already running, so we should optimize for this case.

Instead of unconditionally delaying 5 seconds between each connection attempt,
start with a minimum delay of 1 second and increase the delay linearly with
each attempt, maxing out at 10 seconds. This makes the retry count-based
failure mode less practical, so instead we just use a timeout-based approach.*

*NOTE: the original implementation would have an effective timeout of 25s. This
alters the behavior to 60s.

Additionally, this removes an unnecessary 5s delay that was injected in the
postgres case. The script uses a more comprehensive connection check for
postgres than it does mariadb, so if anything this 5s delay after getting an
"ok" response from the DB was extra unnecessary in the postgres case.
This commit is contained in:
Michael Martin
2025-11-17 13:11:49 -08:00
committed by GitHub
parent 0e5ab7f3e0
commit c3ac102eba

View File

@@ -1,70 +1,66 @@
#!/command/with-contenv /usr/bin/bash
# shellcheck shell=bash
# vim: set ft=bash ts=4 sw=4 sts=4 et :
declare -r log_prefix="[init-db-wait]"
set -euo pipefail
declare -r LOG_PREFIX="[init-db-wait]"
declare -ri TIMEOUT=60
declare -i ATTEMPT=0
declare -i DELAY=0
declare -i STARTED_AT=${EPOCHSECONDS:?EPOCHSECONDS var unset}
delay_next_attempt() {
local -i elapsed=$(( EPOCHSECONDS - STARTED_AT ))
local -ri remaining=$(( TIMEOUT - elapsed ))
if (( remaining <= 0 )); then
echo "${LOG_PREFIX} Unable to connect after $elapsed seconds."
exit 1
fi
DELAY+=1
# clamp to remaining time
if (( DELAY > remaining )); then
DELAY=$remaining
fi
ATTEMPT+=1
echo "${LOG_PREFIX} Attempt $ATTEMPT failed! Trying again in $DELAY seconds..."
sleep "$DELAY"
}
wait_for_postgres() {
local attempt_num=1
local -r max_attempts=5
echo "${log_prefix} Waiting for PostgreSQL to start..."
echo "${LOG_PREFIX} Waiting for PostgreSQL to start..."
local -r host="${PAPERLESS_DBHOST:-localhost}"
local -r port="${PAPERLESS_DBPORT:-5432}"
local -r user="${PAPERLESS_DBUSER:-paperless}"
# Disable warning, host and port can't have spaces
# shellcheck disable=SC2086
while [ ! "$(pg_isready -h ${host} -p ${port} --username ${user})" ]; do
if [ $attempt_num -eq $max_attempts ]; then
echo "${log_prefix} Unable to connect to database."
exit 1
else
echo "${log_prefix} Attempt $attempt_num failed! Trying again in 5 seconds..."
fi
attempt_num=$(("$attempt_num" + 1))
sleep 5
while ! pg_isready -h "${host}" -p "${port}" --username "${user}"; do
delay_next_attempt
done
# Extra in case this is a first start
sleep 5
echo "Connected to PostgreSQL"
echo "${LOG_PREFIX} Connected to PostgreSQL"
}
wait_for_mariadb() {
echo "${log_prefix} Waiting for MariaDB to start..."
echo "${LOG_PREFIX} Waiting for MariaDB to start..."
local -r host="${PAPERLESS_DBHOST:=localhost}"
local -r port="${PAPERLESS_DBPORT:=3306}"
local -r host="${PAPERLESS_DBHOST:-localhost}"
local -r port="${PAPERLESS_DBPORT:-3306}"
local attempt_num=1
local -r max_attempts=5
# Disable warning, host and port can't have spaces
# shellcheck disable=SC2086
while ! true > /dev/tcp/$host/$port; do
if [ $attempt_num -eq $max_attempts ]; then
echo "${log_prefix} Unable to connect to database."
exit 1
else
echo "${log_prefix} Attempt $attempt_num failed! Trying again in 5 seconds..."
fi
attempt_num=$(("$attempt_num" + 1))
sleep 5
while ! true > "/dev/tcp/$host/$port"; do
delay_next_attempt
done
echo "Connected to MariaDB"
echo "${LOG_PREFIX} Connected to MariaDB"
}
if [[ "${PAPERLESS_DBENGINE}" == "mariadb" ]]; then
echo "${log_prefix} Waiting for MariaDB to report ready"
if [[ "${PAPERLESS_DBENGINE:-}" == "mariadb" ]]; then
wait_for_mariadb
elif [[ -n "${PAPERLESS_DBHOST}" ]]; then
echo "${log_prefix} Waiting for postgresql to report ready"
elif [[ -n "${PAPERLESS_DBHOST:-}" ]]; then
wait_for_postgres
fi
echo "${log_prefix} Database is ready"
echo "${LOG_PREFIX} Database is ready"