mirror of
https://github.com/dokku/dokku.git
synced 2025-12-29 00:25:08 +01:00
Containers can be attached: - after they are created, but before they are started - after a successful deploy, but before the proxy reloads This allows folks to have flexibility around when they would like a container to be made available to a network.
131 lines
5.3 KiB
Bash
Executable File
131 lines
5.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -eo pipefail
|
|
[[ $DOKKU_TRACE ]] && set -x
|
|
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
|
|
source "$PLUGIN_AVAILABLE_PATH/config/functions"
|
|
source "$PLUGIN_AVAILABLE_PATH/ps/functions"
|
|
|
|
get_phase_script() {
|
|
declare desc="extracts app.json from app image and returns the appropriate json key/value"
|
|
declare IMAGE_TAG="$1" PHASE_SCRIPT_KEY="$2"
|
|
local APP_JSON_FILE=$(mktemp "/tmp/dokku-${DOKKU_PID}-${FUNCNAME[0]}.XXXXXX")
|
|
trap "rm -rf '$APP_JSON_FILE' >/dev/null" RETURN INT TERM
|
|
|
|
copy_from_image "$IMAGE" "app.json" "$APP_JSON_FILE" 2>/dev/null || true
|
|
|
|
if [[ ! -f "$APP_JSON_FILE" ]]; then
|
|
return 0
|
|
fi
|
|
|
|
get_json_value ".scripts.dokku.${PHASE_SCRIPT_KEY}" <"$APP_JSON_FILE"
|
|
}
|
|
|
|
get_release_cmd() {
|
|
declare desc="extracts the release command from a given app's procfile"
|
|
declare APP="$1" IMAGE_TAG="$2"
|
|
|
|
extract_procfile "$APP" "$IMAGE_TAG" >/dev/null
|
|
trap "remove_procfile $APP" RETURN INT TERM EXIT
|
|
|
|
get_cmd_from_procfile "$APP" "release" "5000"
|
|
}
|
|
|
|
execute_script() {
|
|
declare desc="executes appropriate phase script key from app.json"
|
|
declare APP="$1" IMAGE_TAG="$2" PHASE_SCRIPT_KEY="$3"
|
|
local IMAGE id SCRIPT_CMD
|
|
|
|
local DOCKER_COMMIT_LABEL_ARGS=("--change" "\"LABEL org.label-schema.schema-version=1.0\"" "--change" "\"LABEL org.label-schema.vendor=dokku\"" "--change" "\"LABEL com.dokku.app-name=$APP\"")
|
|
local DOCKER_RUN_LABEL_ARGS="--label=com.dokku.app-name=$APP"
|
|
|
|
IMAGE=$(get_deploying_app_image_name "$APP" "$IMAGE_TAG")
|
|
if [[ "$PHASE_SCRIPT_KEY" == "release" ]]; then
|
|
SCRIPT_CMD=$(get_release_cmd "$APP" "$IMAGE_TAG" 2>/dev/null || true)
|
|
else
|
|
SCRIPT_CMD=$(get_phase_script "$IMAGE" "$PHASE_SCRIPT_KEY" 2>/dev/null || true)
|
|
fi
|
|
|
|
if [[ -z "$SCRIPT_CMD" ]]; then
|
|
return
|
|
fi
|
|
|
|
dokku_log_exclaim "${PHASE_SCRIPT_KEY^} command declared: '$SCRIPT_CMD'"
|
|
local COMMAND
|
|
COMMAND="set -eo pipefail; [[ \$DOKKU_TRACE ]] && set -x ; "
|
|
COMMAND+=" if [[ -d '/app' ]]; then "
|
|
COMMAND+=" export HOME=/app ; "
|
|
COMMAND+=" cd \$HOME ; "
|
|
COMMAND+=" fi ; "
|
|
COMMAND+=" if [[ -d '/app/.profile.d' ]]; then "
|
|
COMMAND+=" for file in /app/.profile.d/*; do source \$file; done ; "
|
|
COMMAND+=" fi ; "
|
|
COMMAND+=" if [[ -d '/cache' ]]; then "
|
|
COMMAND+=" rm -rf /tmp/cache ; "
|
|
COMMAND+=" ln -sf /cache /tmp/cache ; "
|
|
COMMAND+=" fi ; "
|
|
|
|
if [[ "$SCRIPT_CMD" == /* ]]; then
|
|
local SCRIPT_BIN="$(echo "$SCRIPT_CMD" | cut -d' ' -f1)"
|
|
COMMAND+=" if [[ ! -x \"$SCRIPT_BIN\" ]]; then "
|
|
COMMAND+=" echo specified binary is not executable ; "
|
|
COMMAND+=" exit 1 ; "
|
|
COMMAND+=" fi ; "
|
|
fi
|
|
|
|
COMMAND+=" $SCRIPT_CMD || exit 1;"
|
|
COMMAND+=" if [[ -d '/cache' ]]; then "
|
|
COMMAND+=" rm -f /tmp/cache ; "
|
|
COMMAND+=" fi ; "
|
|
|
|
local CACHE_DIR="$DOKKU_ROOT/$APP/cache"
|
|
local CACHE_HOST_DIR="$DOKKU_HOST_ROOT/$APP/cache"
|
|
[[ -d $CACHE_DIR ]] || mkdir -p "$CACHE_DIR"
|
|
|
|
local DOCKER_ARGS=$(: | plugn trigger docker-args-deploy "$APP" "$IMAGE_TAG")
|
|
# strip --restart args from DOCKER_ARGS
|
|
local DOCKER_ARGS=$(sed -e "s/--restart=[[:graph:]]\+[[:blank:]]\?//g" <<<"$DOCKER_ARGS")
|
|
|
|
local IMAGE_SOURCE_TYPE="dockerfile"
|
|
is_image_herokuish_based "$IMAGE" "$APP" && IMAGE_SOURCE_TYPE="herokuish"
|
|
DOCKER_ARGS+=$(: | plugn trigger docker-args-process-deploy "$APP" "$IMAGE_SOURCE_TYPE" "$IMAGE_TAG")
|
|
|
|
# eval args as array to respect escapes
|
|
declare -a ARG_ARRAY
|
|
eval "ARG_ARRAY=($DOCKER_ARGS)"
|
|
|
|
local DOKKU_APP_SHELL="/bin/bash"
|
|
DOKKU_APP_SHELL="$(config_get --global DOKKU_APP_SHELL || echo "$DOKKU_APP_SHELL")"
|
|
DOKKU_APP_SHELL="$(config_get "$APP" DOKKU_APP_SHELL || echo "$DOKKU_APP_SHELL")"
|
|
[[ -z "$DOKKU_APP_SHELL" ]] && DOKKU_APP_SHELL="/bin/bash"
|
|
|
|
local DOKKU_CONTAINER_EXIT_CODE=0
|
|
id=$("$DOCKER_BIN" container create "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS --env DOKKU_TRACE="$DOKKU_TRACE" --label=dokku_phase_script="${PHASE_SCRIPT_KEY}" -v "$CACHE_HOST_DIR:/cache" "${ARG_ARRAY[@]}" "$IMAGE" "$DOKKU_APP_SHELL" -c "$COMMAND")
|
|
plugn trigger post-container-create "app" "$id" "$APP" "$PHASE_SCRIPT_KEY"
|
|
"$DOCKER_BIN" container start "$id" >/dev/null || DOKKU_CONTAINER_EXIT_CODE=$?
|
|
DOKKU_CONTAINER_EXIT_CODE="$("$DOCKER_BIN" container wait "$id" 2>/dev/null || echo "$DOKKU_CONTAINER_EXIT_CODE")"
|
|
|
|
if [[ "$DOKKU_CONTAINER_EXIT_CODE" -ne 0 ]]; then
|
|
dokku_container_log_verbose_quiet "$id"
|
|
dokku_log_fail "execution of '$SCRIPT_CMD' failed!"
|
|
fi
|
|
|
|
dokku_container_log_verbose_quiet "$id"
|
|
if [[ "$PHASE_SCRIPT_KEY" != "predeploy" ]]; then
|
|
return
|
|
fi
|
|
|
|
if ! is_image_herokuish_based "$IMAGE" "$APP"; then
|
|
local DOKKU_DOCKERFILE_ENTRYPOINT=$(config_get "$APP" DOKKU_DOCKERFILE_ENTRYPOINT)
|
|
local DOKKU_DOCKERFILE_CMD=$(config_get "$APP" DOKKU_DOCKERFILE_CMD)
|
|
[[ -z "$DOKKU_DOCKERFILE_ENTRYPOINT" ]] && DOKKU_DOCKERFILE_ENTRYPOINT="$(get_entrypoint_from_image "$IMAGE")"
|
|
[[ -z "$DOKKU_DOCKERFILE_CMD" ]] && DOKKU_DOCKERFILE_CMD="$(get_cmd_from_image "$IMAGE")"
|
|
|
|
[[ -n "$DOKKU_DOCKERFILE_ENTRYPOINT" ]] && local DOCKER_COMMIT_ENTRYPOINT_CHANGE_ARG="--change='$DOKKU_DOCKERFILE_ENTRYPOINT'"
|
|
[[ -n "$DOKKU_DOCKERFILE_CMD" ]] && local DOCKER_COMMIT_CMD_CHANGE_ARG="--change='$DOKKU_DOCKERFILE_CMD'"
|
|
|
|
local DOCKER_COMMIT_ARGS="$DOCKER_COMMIT_ENTRYPOINT_CHANGE_ARG $DOCKER_COMMIT_CMD_CHANGE_ARG"
|
|
fi
|
|
|
|
eval "$DOCKER_BIN" container commit "${DOCKER_COMMIT_LABEL_ARGS[@]}" "${DOCKER_COMMIT_ARGS[@]}" "$id" "$IMAGE" >/dev/null
|
|
}
|