mirror of
https://github.com/dokku/dokku.git
synced 2026-05-18 05:05:46 +02:00
This change converts existing CHECKS files into a healthchecks key that is understood by 'docker-container-healthchecker'. This tool supports a number of different types of container healthchecks - command, http, uptime - and can perform healthchecks against non-web processes. The use of the old CHECKS file is now deprecated, and will be removed in the next minor version. Users can use the 'docker-container-healthchecker' to convert existing CHECKS files to the new format automatically. Closes #2760
163 lines
6.0 KiB
Bash
Executable File
163 lines
6.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
# Hook to check server against list of checks specified in CHECKS file.
|
|
#
|
|
# The CHECKS file may contain empty lines, comments (lines starting with #),
|
|
# settings (NAME=VALUE) and check instructions.
|
|
#
|
|
# The format of a check instruction is a path, optionally followed by the
|
|
# expected content. For example:
|
|
#
|
|
# / My Amazing App
|
|
# /stylesheets/index.css .body
|
|
# /scripts/index.js $(function()
|
|
# /images/logo.png
|
|
#
|
|
# To check an application that supports multiple hostnames, use relative URLs
|
|
# that include the hostname, for example:
|
|
#
|
|
# //admin.example.com Admin Dashboard
|
|
# //static.example.com/logo.png
|
|
#
|
|
# You can also specify the protocol to explicitly check HTTPS requests.
|
|
#
|
|
# The default behavior is to wait for 5 seconds before running the first check,
|
|
# and timeout each check to 30 seconds.
|
|
#
|
|
# By default, checks will be retried 5 times.
|
|
|
|
# You can change these by setting WAIT, TIMEOUT and ATTEMPTS to different values, for
|
|
# example:
|
|
#
|
|
# WAIT=30 # Wait 1/2 minute
|
|
# TIMEOUT=60 # Timeout after a minute
|
|
# ATTEMPTS=10 # retry checks 10 times
|
|
#
|
|
set -eo pipefail
|
|
[[ $DOKKU_TRACE ]] && set -x
|
|
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
|
|
source "$PLUGIN_AVAILABLE_PATH/checks/functions"
|
|
source "$PLUGIN_AVAILABLE_PATH/config/functions"
|
|
source "$PLUGIN_AVAILABLE_PATH/scheduler-docker-local/internal-functions"
|
|
|
|
trigger-scheduler-docker-local-check-deploy() {
|
|
declare desc="scheduler-docker-local check-deploy plugin trigger"
|
|
declare trigger="check-deploy"
|
|
declare APP="$1" DOKKU_APP_CONTAINER_ID="$2" DOKKU_APP_CONTAINER_TYPE="$3" DOKKU_APP_LISTEN_PORT="$4" DOKKU_APP_LISTEN_IP="$5" CONTAINER_INDEX="$6"
|
|
local content
|
|
|
|
local DOKKU_SCHEDULER=$(get_app_scheduler "$APP")
|
|
if [[ "$DOKKU_SCHEDULER" != "docker-local" ]]; then
|
|
return
|
|
fi
|
|
|
|
if [[ -z "$DOKKU_APP_LISTEN_PORT" ]] && [[ -f "$DOKKU_ROOT/$APP/PORT" ]]; then
|
|
local DOKKU_APP_LISTEN_PORT=$(<"$DOKKU_ROOT/$APP/PORT")
|
|
fi
|
|
if [[ -z "$DOKKU_APP_CONTAINER_ID" ]]; then
|
|
local DOKKU_APP_CIDS=($(get_app_container_ids "$APP"))
|
|
local DOKKU_APP_CONTAINER_ID=${DOKKU_APP_CIDS[0]}
|
|
fi
|
|
|
|
# source global and in-app envs to get DOKKU_CHECKS_WAIT and any other necessary vars
|
|
eval "$(config_export global)"
|
|
eval "$(config_export app "$APP")"
|
|
|
|
if [[ "$(is_app_proctype_checks_skipped "$APP" "$DOKKU_APP_CONTAINER_TYPE")" == "true" ]]; then
|
|
dokku_log_info2_quiet "Zero downtime checks have been skipped ($DOKKU_APP_CONTAINER_TYPE.$CONTAINER_INDEX)"
|
|
exit 0
|
|
fi
|
|
|
|
# Wait this many seconds (default 5) for server to start before running checks.
|
|
local WAIT="${DOKKU_CHECKS_WAIT:-5}"
|
|
# Wait this many seconds (default 30) for each response.
|
|
local TIMEOUT="${DOKKU_CHECKS_TIMEOUT:-30}"
|
|
# use this number of retries for checks
|
|
local ATTEMPTS="${DOKKU_CHECKS_ATTEMPTS:-5}"
|
|
|
|
local CHECKS_FILENAME="$(fn-scheduler-docker-local-get-process-specific-checks-file-path "$APP")"
|
|
local IMAGE_TAG="$(get_running_image_tag "$APP")"
|
|
local IMAGE=$(get_deploying_app_image_name "$APP" "$IMAGE_TAG")
|
|
|
|
local TMP_APP_JSON_OUTPUT=$(mktemp "/tmp/dokku-${DOKKU_PID}-${FUNCNAME[0]}.XXXXXX")
|
|
trap "rm -rf '$TMP_APP_JSON_OUTPUT' >/dev/null" RETURN INT TERM EXIT
|
|
|
|
plugn trigger app-json-get-content "$APP" >"$TMP_APP_JSON_OUTPUT"
|
|
if [[ -s "${CHECKS_FILENAME}" ]]; then
|
|
# Reads name/value pairs, sets the WAIT and TIMEOUT variables
|
|
exec <"$CHECKS_FILENAME"
|
|
local line
|
|
local NAME
|
|
local VALUE
|
|
while read -r line; do
|
|
line=$(strip_inline_comments "$line")
|
|
# Name/value pair
|
|
if [[ "$line" =~ ^.+= ]]; then
|
|
NAME=${line%=*}
|
|
VALUE=${line#*=}
|
|
[[ "$NAME" == "WAIT" ]] && local WAIT=$VALUE
|
|
[[ "$NAME" == "TIMEOUT" ]] && local TIMEOUT=$VALUE
|
|
[[ "$NAME" == "ATTEMPTS" ]] && local ATTEMPTS=$VALUE
|
|
fi
|
|
done
|
|
|
|
dokku_log_warn "Deprecated: Usage of the CHECKS file is deprecated in favor of healthchecks in app.json"
|
|
dokku_log_warn "Please move your healthchecks to app.json."
|
|
content="$(docker-container-healthchecker convert "$CHECKS_FILENAME" --app-json "$TMP_APP_JSON_OUTPUT" --pretty)"
|
|
echo "$content" >"$TMP_APP_JSON_OUTPUT"
|
|
fi
|
|
|
|
checks_check_deploy_cleanup() {
|
|
declare desc="print container output"
|
|
local id="$1"
|
|
|
|
if [[ $id ]]; then
|
|
dokku_log_info2_quiet "Start of $APP container output ($DOKKU_APP_CONTAINER_TYPE.$CONTAINER_INDEX)"
|
|
dokku_container_log_verbose_quiet "$id"
|
|
dokku_log_info2_quiet "End of $APP container output ($DOKKU_APP_CONTAINER_TYPE.$CONTAINER_INDEX)"
|
|
fi
|
|
}
|
|
trap "checks_check_deploy_cleanup $DOKKU_APP_CONTAINER_ID" RETURN INT TERM EXIT
|
|
|
|
local DOKKU_DEFAULT_CHECKS_WAIT="${DOKKU_DEFAULT_CHECKS_WAIT:-10}"
|
|
content="$(docker-container-healthchecker add "$DOKKU_APP_CONTAINER_TYPE" --app-json "$TMP_APP_JSON_OUTPUT" --if-empty --pretty --uptime "$DOKKU_DEFAULT_CHECKS_WAIT")"
|
|
echo "$content" >"$TMP_APP_JSON_OUTPUT"
|
|
|
|
local FAILEDCHECKS=0
|
|
local SSL="$DOKKU_ROOT/$APP/tls"
|
|
declare -a ARG_ARRAY
|
|
ARG_ARRAY+=("--app-json")
|
|
ARG_ARRAY+=("$TMP_APP_JSON_OUTPUT")
|
|
ARG_ARRAY+=("--process-type")
|
|
ARG_ARRAY+=("$DOKKU_APP_CONTAINER_TYPE")
|
|
|
|
if [[ -e "$SSL/server.crt" && -e "$SSL/server.key" ]]; then
|
|
ARG_ARRAY+=("--header")
|
|
ARG_ARRAY+=("X-Forwarded-Proto: https")
|
|
fi
|
|
|
|
if [[ -n "$DOKKU_APP_LISTEN_IP" ]]; then
|
|
ARG_ARRAY+=("--ip-address")
|
|
ARG_ARRAY+=("$DOKKU_APP_LISTEN_IP")
|
|
fi
|
|
|
|
if [[ -n "$DOKKU_APP_LISTEN_PORT" ]]; then
|
|
ARG_ARRAY+=("--port")
|
|
ARG_ARRAY+=("$DOKKU_APP_LISTEN_PORT")
|
|
fi
|
|
|
|
docker-container-healthchecker check "$DOKKU_APP_CONTAINER_ID" "${ARG_ARRAY[@]}" || FAILEDCHECKS="$?"
|
|
|
|
if [[ $FAILEDCHECKS -gt 0 ]]; then
|
|
"$DOCKER_BIN" container update --restart=no "$DOKKU_APP_CONTAINER_ID" &>/dev/null || true
|
|
"$DOCKER_BIN" container stop "$DOKKU_APP_CONTAINER_ID" || true
|
|
dokku_log_warn "Could not start due to $FAILEDCHECKS failed checks ($DOKKU_APP_CONTAINER_TYPE.$CONTAINER_INDEX)"
|
|
return 1
|
|
fi
|
|
|
|
trap - EXIT
|
|
dokku_log_verbose "All checks successful ($DOKKU_APP_CONTAINER_TYPE.$CONTAINER_INDEX)"
|
|
}
|
|
|
|
trigger-scheduler-docker-local-check-deploy "$@"
|