Files
dokku/plugins/scheduler-docker-local/scheduler-deploy
Jose Diaz-Gonzalez 7d73cf78c4 feat: split scheduler-docker-local report into raw, computed, and global
The bare `init-process` and `parallel-schedule-count` keys previously returned the computed value, so external tooling could not tell whether a property had been set on the app or was merely defaulting. Both properties are now also configurable with `--global`, the report exposes `computed-*` and `global-*` keys alongside the bare raw keys, and the deploy path honors the global value before falling back to the linuxserver.io vendor heuristic.
2026-05-11 22:29:28 -04:00

129 lines
5.8 KiB
Bash
Executable File

#!/usr/bin/env bash
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-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-scheduler-deploy() {
declare desc="deploys an image tag for a given application"
declare trigger="scheduler-deploy"
declare DOKKU_SCHEDULER="$1" APP="$2" IMAGE_TAG="$3" PROCESS_TYPE="$4"
local PROCESS_TYPE
if [[ "$DOKKU_SCHEDULER" != "docker-local" ]]; then
return
fi
rm -f "${DOKKU_LIB_ROOT}/data/scheduler-docker-local/$APP/failed-containers"
local DOCKER_RUN_LABEL_ARGS="--label=com.dokku.app-name=$APP --label=com.dokku.container-type=deploy"
local DOKKU_DOCKER_STOP_TIMEOUT DOKKU_HEROKUISH DOKKU_NETWORK_BIND_ALL IMAGE
DOKKU_HEROKUISH=false
DOKKU_CNB=false
IMAGE="$(get_deploying_app_image_name "$APP" "$IMAGE_TAG")"
is_image_cnb_based "$IMAGE" && DOKKU_CNB=true
is_image_herokuish_based "$IMAGE" "$APP" && DOKKU_HEROKUISH=true
local IMAGE_SOURCE_TYPE="dockerfile"
[[ "$DOKKU_HEROKUISH" == "true" ]] && IMAGE_SOURCE_TYPE="herokuish"
[[ "$DOKKU_CNB" == "true" ]] && IMAGE_SOURCE_TYPE="pack"
local oldids=$(get_app_container_ids "$APP" "$PROCESS_TYPE")
DOKKU_NETWORK_BIND_ALL="$(plugn trigger network-get-property "$APP" bind-all-interfaces)"
DOKKU_DOCKER_STOP_TIMEOUT="$(plugn trigger ps-get-property "$APP" stop-timeout-seconds)"
[[ $DOKKU_DOCKER_STOP_TIMEOUT ]] && DOCKER_STOP_TIME_ARG="-t=${DOKKU_DOCKER_STOP_TIMEOUT}"
DOKKU_START_CMD="$(fn-plugin-property-get-default "ps" "$APP" "start-cmd" "")"
local PROCFILE_EXISTS=false
if plugn trigger procfile-exists "$APP" 2>/dev/null; then
PROCFILE_EXISTS=true
fi
local DOKKU_WAIT_TO_RETIRE="$(plugn trigger checks-get-property "$APP" wait-to-retire)"
export DOKKU_WAIT_TO_RETIRE
local TMP_FILE=$(mktemp "/tmp/dokku-${DOKKU_PID}-${FUNCNAME[0]}.XXXXXX")
trap "rm -rf '$TMP_FILE' >/dev/null" RETURN INT TERM EXIT
local line
local PROC_TYPE
local PROC_COUNT
while read -r line || [[ -n "$line" ]]; do
local PROC_TYPE=${line%%=*}
local PROC_COUNT=${line#*=}
if [[ -n "$PROCESS_TYPE" ]] && [[ "$PROC_TYPE" != "$PROCESS_TYPE" ]]; then
continue
fi
local PROC_CMD=$(plugn trigger procfile-get-command "$APP" "$PROC_TYPE" "5000" 2>/dev/null || echo '')
if [[ "$PROCFILE_EXISTS" == true ]] && [[ "$PROC_CMD" == "" ]]; then
dokku_log_warn "Skipping $PROC_TYPE as it is missing from the current Procfile"
continue
fi
if [[ "$PROC_TYPE" != "web" ]]; then
echo "$PLUGIN_AVAILABLE_PATH/scheduler-docker-local/bin/scheduler-deploy-process $APP $IMAGE_SOURCE_TYPE $IMAGE $IMAGE_TAG $PROC_TYPE $PROC_COUNT" >>"$TMP_FILE"
continue
fi
DOKKU_NETWORK_BIND_ALL="$DOKKU_NETWORK_BIND_ALL" DOKKU_HEROKUISH="$DOKKU_HEROKUISH" DOKKU_CNB="$DOKKU_CNB" DOCKER_RUN_LABEL_ARGS="$DOCKER_RUN_LABEL_ARGS" DOKKU_START_CMD="$DOKKU_START_CMD" DOCKER_STOP_TIME_ARG="$DOCKER_STOP_TIME_ARG" "$PLUGIN_AVAILABLE_PATH/scheduler-docker-local/bin/scheduler-deploy-process" "$APP" "$IMAGE_SOURCE_TYPE" "$IMAGE" "$IMAGE_TAG" "$PROC_TYPE" "$PROC_COUNT"
done < <(plugn trigger ps-current-scale "$APP")
PARALLEL_DEPLOY_COUNT="$(fn-scheduler-docker-local-computed-parallel-schedule-count "$APP")"
DOKKU_NETWORK_BIND_ALL="$DOKKU_NETWORK_BIND_ALL" DOKKU_HEROKUISH="$DOKKU_HEROKUISH" DOKKU_CNB="$DOKKU_CNB" DOCKER_RUN_LABEL_ARGS="$DOCKER_RUN_LABEL_ARGS" DOKKU_START_CMD="$DOKKU_START_CMD" DOCKER_STOP_TIME_ARG="$DOCKER_STOP_TIME_ARG" parallel --will-cite --halt soon,fail=1 --jobs "$PARALLEL_DEPLOY_COUNT" --ungroup <"$TMP_FILE"
dokku_log_info1 "Running post-deploy"
plugn trigger core-post-deploy "$APP" "$port" "$ipaddr" "$IMAGE_TAG"
plugn trigger post-deploy "$APP" "$port" "$ipaddr" "$IMAGE_TAG"
# kill the old container
if [[ -n "$oldids" ]]; then
# Send SIGTERM to old containers immediately so the application can begin
# graceful shutdown the moment proxy traffic switches to the new containers.
# We use `container kill --signal=SIGTERM` rather than `container stop`
# because it returns immediately and docker does not follow up with a
# SIGKILL on its own when the signal is something other than SIGKILL -
# the existing background block below remains responsible for the
# eventual hard stop after the wait-to-retire grace period.
for oldid in $oldids; do
if "$DOCKER_BIN" container inspect "$oldid" &>/dev/null; then
"$DOCKER_BIN" container kill --signal=SIGTERM "$oldid" &>/dev/null || true
fi
done
# Let the old container finish processing requests, before terminating it
dokku_log_info1 "Shutting down old containers in $DOKKU_WAIT_TO_RETIRE seconds"
(
exec >/dev/null 2>/dev/null </dev/null
trap '' INT HUP
sleep "$DOKKU_WAIT_TO_RETIRE"
for oldid in $oldids; do
if ! "$DOCKER_BIN" container inspect "$oldid" &>/dev/null; then
continue
fi
# Disable the container restart policy
"$DOCKER_BIN" container update --restart=no "$oldid" &>/dev/null || true
# Attempt to stop, if that fails, then force a kill as docker seems
# to not send SIGKILL as the docs would indicate. If that fails, move
# on to the next.
"$DOCKER_BIN" container stop $DOCKER_STOP_TIME_ARG "$oldid" \
|| "$DOCKER_BIN" container kill "$oldid" \
|| plugn trigger retire-container-failed "$APP" "$oldid" # plugin trigger for event logging
done
) &
disown -a
# Use trap since disown/nohup don't seem to keep child alive
# Give child process just enough time to set the traps
sleep 0.1
fi
}
trigger-scheduler-docker-local-scheduler-deploy "$@"