diff --git a/plugins/00_dokku-standard/exec-app-json-scripts b/plugins/00_dokku-standard/exec-app-json-scripts index 43a586676..6568df294 100755 --- a/plugins/00_dokku-standard/exec-app-json-scripts +++ b/plugins/00_dokku-standard/exec-app-json-scripts @@ -1,6 +1,7 @@ #!/usr/bin/env bash set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" +source "$PLUGIN_AVAILABLE_PATH/config/functions" get_phase_script() { declare desc="extracts app.json from app image and returns the appropriate json key/value" @@ -26,29 +27,50 @@ execute_script() { local SCRIPT_CMD=$(get_phase_script "$IMAGE" "$PHASE_SCRIPT_KEY" 2>/dev/null) if [[ -n "$SCRIPT_CMD" ]];then dokku_log_info1 "Running '$SCRIPT_CMD' in app container" - local COMMAND="export HOME=/app ; " - local COMMAND+=" cd \$HOME ; " - local COMMAND+=" for file in /app/.profile.d/*; do source \$file; done ; " - local COMMAND+=" echo restoring installation cache... ; " - local COMMAND+=" rm -rf /tmp/cache || true ; " - local COMMAND+=" ln -sf /cache /tmp/cache || true ; " - local COMMAND+=" $SCRIPT_CMD ; RC=\$? ;" - local COMMAND+=" echo removing installation cache... ; " - local COMMAND+=" rm -f /tmp/cache || true ; " - local COMMAND+=" exit \$RC " - local CACHE_DIR="$DOKKU_ROOT/$APP/cache" + 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+=" echo restoring installation cache... ; " + COMMAND+=" rm -rf /tmp/cache ; " + COMMAND+=" ln -sf /cache /tmp/cache ; " + COMMAND+=" fi ; " + COMMAND+=" $SCRIPT_CMD ;" + COMMAND+=" if [[ -d '/cache' ]]; then " + COMMAND+=" echo removing installation cache... ; " + COMMAND+=" rm -f /tmp/cache ; " + COMMAND+=" fi " - local DOCKER_ARGS_RESTART_RE="(.*)--restart=.+([\s,$])" + local CACHE_DIR="$DOKKU_ROOT/$APP/cache" local DOCKER_ARGS=$(: | plugn trigger docker-args-deploy "$APP") # strip --restart args from DOCKER_ARGS local DOCKER_ARGS=$(sed -e "s/--restart=[[:graph:]]\+[[:blank:]]\?//g" <<< "$DOCKER_ARGS") # shellcheck disable=SC2086 - local id=$(docker run "$DOKKU_GLOBAL_RUN_ARGS" --label=dokku_phase_script="${PHASE_SCRIPT_KEY}" -d -v "$CACHE_DIR:/cache" $DOCKER_ARGS "$IMAGE" /bin/bash -c "$COMMAND") - test "$(docker wait "$id")" -eq 0 || (dokku_container_log_verbose_quiet "$id"; exit 1) - dokku_container_log_verbose_quiet "$id" - if [[ "$PHASE_SCRIPT_KEY" != "postdeploy" ]];then - docker commit "$id" "$IMAGE" > /dev/null + local id=$(docker run "$DOKKU_GLOBAL_RUN_ARGS" -e DOKKU_TRACE="$DOKKU_TRACE" --label=dokku_phase_script="${PHASE_SCRIPT_KEY}" -d -v "$CACHE_DIR:/cache" $DOCKER_ARGS "$IMAGE" /bin/bash -c "$COMMAND") + if test "$(docker wait "$id")" -eq 0; then + dokku_container_log_verbose_quiet "$id" + if [[ "$PHASE_SCRIPT_KEY" != "postdeploy" ]];then + if ! is_image_herokuish_based "$IMAGE"; then + local DOKKU_DOCKERFILE_ENTRYPOINT=$(config_get "$APP" DOKKU_DOCKERFILE_ENTRYPOINT) + local DOKKU_DOCKERFILE_CMD=$(config_get "$APP" DOKKU_DOCKERFILE_CMD) + [[ -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 + # shellcheck disable=SC2086 + eval docker commit $DOCKER_COMMIT_ARGS "$id" "$IMAGE" > /dev/null + fi + else + dokku_container_log_verbose_quiet "$id" + dokku_log_fail "execution of '$SCRIPT_CMD' failed!" fi fi } diff --git a/plugins/00_dokku-standard/subcommands/build b/plugins/00_dokku-standard/subcommands/build index 1bbdc0fcc..b9ddbce63 100755 --- a/plugins/00_dokku-standard/subcommands/build +++ b/plugins/00_dokku-standard/subcommands/build @@ -37,6 +37,12 @@ dokku_build_cmd() { # extract first port from Dockerfile local DOCKERFILE_PORTS=$(get_dockerfile_exposed_ports Dockerfile) [[ -n "$DOCKERFILE_PORTS" ]] && config_set --no-restart "$APP" DOKKU_DOCKERFILE_PORTS="$DOCKERFILE_PORTS" + + # extract ENTRYPOINT/CMD from Dockerfile + local DOCKERFILE_ENTRYPOINT=$(extract_directive_from_dockerfile Dockerfile ENTRYPOINT) + [[ -n "$DOCKERFILE_ENTRYPOINT" ]] && config_set --no-restart "$APP" DOKKU_DOCKERFILE_ENTRYPOINT="$DOCKERFILE_ENTRYPOINT" + local DOCKERFILE_CMD=$(extract_directive_from_dockerfile Dockerfile CMD) + [[ -n "$DOCKERFILE_CMD" ]] && config_set --no-restart "$APP" DOKKU_DOCKERFILE_CMD="$DOCKERFILE_CMD" plugn trigger pre-build-dockerfile "$APP" [[ "$DOKKU_DOCKERFILE_CACHE_BUILD" == "false" ]] && DOKKU_DOCKER_BUILD_OPTS="$DOKKU_DOCKER_BUILD_OPTS --no-cache" diff --git a/plugins/common/functions b/plugins/common/functions index a997eb815..b1ebcee79 100755 --- a/plugins/common/functions +++ b/plugins/common/functions @@ -571,6 +571,13 @@ get_dockerfile_exposed_ports() { echo "$DOCKERFILE_PORTS" } +extract_directive_from_dockerfile() { + declare desc="return requested directive from passed file path" + local FILE_PATH="$1"; local SEARCH_STRING="$2" + local FOUND_LINE=$(egrep "^${SEARCH_STRING} " "$FILE_PATH" | tail -n1) || true + echo "$FOUND_LINE" +} + get_app_raw_tcp_ports() { declare desc="extracts raw tcp port numbers from DOCKERFILE_PORTS config variable" source "$PLUGIN_AVAILABLE_PATH/config/functions" diff --git a/tests/apps/dockerfile-noexpose/CHECKS b/tests/apps/dockerfile-noexpose/CHECKS index 6439da05f..034f4c73c 100644 --- a/tests/apps/dockerfile-noexpose/CHECKS +++ b/tests/apps/dockerfile-noexpose/CHECKS @@ -1 +1,5 @@ +WAIT=2 # wait 2 seconds +TIMEOUT=5 # set timeout to 5 seconds +ATTEMPTS=2 # try 2 times + / Hello World! diff --git a/tests/apps/dockerfile-procfile/CHECKS b/tests/apps/dockerfile-procfile/CHECKS index f1d88bab3..068926825 100644 --- a/tests/apps/dockerfile-procfile/CHECKS +++ b/tests/apps/dockerfile-procfile/CHECKS @@ -1 +1,5 @@ +WAIT=2 # wait 2 seconds +TIMEOUT=5 # set timeout to 5 seconds +ATTEMPTS=2 # try 2 times + / nodejs/express diff --git a/tests/apps/dockerfile/CHECKS b/tests/apps/dockerfile/CHECKS index 6439da05f..034f4c73c 100644 --- a/tests/apps/dockerfile/CHECKS +++ b/tests/apps/dockerfile/CHECKS @@ -1 +1,5 @@ +WAIT=2 # wait 2 seconds +TIMEOUT=5 # set timeout to 5 seconds +ATTEMPTS=2 # try 2 times + / Hello World! diff --git a/tests/apps/dockerfile/app.json b/tests/apps/dockerfile/app.json new file mode 100644 index 000000000..9b9aa95ce --- /dev/null +++ b/tests/apps/dockerfile/app.json @@ -0,0 +1,38 @@ +{ + "name": "Sample node.js express app", + "description": "Used in dokku's test suite", + "keywords": [ + "nodejs", + "express", + "testing" + ], + "website": "http://dokku.viewdocs.io/dokku/", + "repository": "https://github.com/dokku/dokku", + "logo": "https://raw.githubusercontent.com/dokku/dokku/master/docs/assets/dokku.png", + "scripts": { + "dokku": { + "predeploy": "touch /app/predeploy.test", + "postdeploy": "touch /app/postdeploy.test" + } + }, + "env": { + "SECRET_TOKEN": { + "description": "A secret key for verifying the integrity of signed cookies.", + "value": "secret" + }, + "WEB_CONCURRENCY": { + "description": "The number of processes to run.", + "generator": "echo 5" + } + }, + "image": "gliderlabs/herokuish", + "addons": [ + "dokku-postgres", + "dokku-redis" + ], + "buildpacks": [ + { + "url": "https://github.com/heroku/heroku-buildpack-nodejs" + } + ] +}