From 33f872183e61c88f389bc26aff2feae03f5de64b Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Fri, 17 Apr 2015 15:23:59 -0700 Subject: [PATCH 01/37] initial pass at container-level scaling --- dokku | 106 +++++++++++++++++++------------ plugins/checks/check-deploy | 26 ++++---- plugins/common/functions | 8 +++ plugins/nginx-vhosts/commands | 23 +++++-- plugins/nginx-vhosts/post-deploy | 4 +- plugins/ps/commands | 21 +++++- plugins/ps/functions | 45 +++++++++++++ plugins/ps/pre-deploy | 8 +++ 8 files changed, 180 insertions(+), 61 deletions(-) create mode 100755 plugins/ps/functions create mode 100755 plugins/ps/pre-deploy diff --git a/dokku b/dokku index c48397b98..e3ac8da70 100755 --- a/dokku +++ b/dokku @@ -66,53 +66,78 @@ case "$1" in APP="$2"; IMAGE="dokku/$APP" pluginhook pre-deploy $APP - if [[ -f "$DOKKU_ROOT/$APP/CONTAINER" ]]; then - oldid=$(< "$DOKKU_ROOT/$APP/CONTAINER") - fi - - # start the app - DOCKER_ARGS=$(: | pluginhook docker-args $APP deploy) - DOCKER_ARGS+=$(: | pluginhook docker-args-deploy $APP) - BIND_EXTERNAL=$(pluginhook bind-external-ip $APP) - is_image_buildstep_based "$IMAGE" && DOKKU_BUILDSTEP=true - [[ -n "$DOKKU_BUILDSTEP" ]] && START_CMD="/start web" - [[ -z "$DOKKU_BUILDSTEP" ]] && DOKKU_DOCKERFILE_PORT=$(dokku config:get $APP DOKKU_DOCKERFILE_PORT || true) + DOKKU_SCALE_FILE="$DOKKU_ROOT/$APP/DOKKU_SCALE" - if [[ "$BIND_EXTERNAL" = "false" ]];then - port=${DOKKU_DOCKERFILE_PORT:=5000} - id=$(docker run -d -e PORT=$port $DOCKER_ARGS $IMAGE $START_CMD) - ipaddr=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' $id) - else - id=$(docker run -d -p 5000 -e PORT=5000 $DOCKER_ARGS $IMAGE $START_CMD) - port=$(docker port $id 5000 | sed 's/[0-9.]*://') - ipaddr=127.0.0.1 - fi + while read line || [ -n "$line" ] + do + PROC_NAME=${line%%=*} + PROC_COUNT=${line#*=} + CONTAINER_NUM=1 - # if we can't post-deploy successfully, kill new container - kill_new() { - docker inspect $id &> /dev/null && docker kill $id > /dev/null - trap - INT TERM EXIT - kill -9 $$ - } + while [[ $CONTAINER_NUM -le $PROC_COUNT ]];do + DOKKU_CONTAINER_ID_FILE="$DOKKU_ROOT/$APP/CONTAINER.$PROC_NAME.$CONTAINER_NUM" + DOKKU_IP_FILE="$DOKKU_ROOT/$APP/IP.$PROC_NAME.$CONTAINER_NUM" + DOKKU_PORT_FILE="$DOKKU_ROOT/$APP/PORT.$PROC_NAME.$CONTAINER_NUM" - # run checks first, then post-deploy hooks, which switches Nginx traffic - trap kill_new INT TERM EXIT - dokku_log_info1 "Running pre-flight checks" - pluginhook check-deploy $APP $port $ipaddr $id - trap - INT TERM EXIT + # try old form even in case we're migrating dokku versions + if [[ -f "$DOKKU_CONTAINER_ID_FILE" ]]; then + oldids+=" " + oldids+=$(< "$DOKKU_CONTAINER_ID_FILE") + oldids+=" " + elif [[ -f "$DOKKU_ROOT/$APP/CONTAINER" ]]; then + oldids+=$(< "$DOKKU_ROOT/$APP/CONTAINER") + fi - # now using the new container - echo $id > "$DOKKU_ROOT/$APP/CONTAINER" - echo $ipaddr > "$DOKKU_ROOT/$APP/IP" - echo $port > "$DOKKU_ROOT/$APP/PORT" - echo "http://$(< "$DOKKU_ROOT/HOSTNAME"):$port" > "$DOKKU_ROOT/$APP/URL" + # start the app + DOCKER_ARGS=$(: | pluginhook docker-args $APP deploy) + DOCKER_ARGS+=$(: | pluginhook docker-args-deploy $APP) + BIND_EXTERNAL=$(pluginhook bind-external-ip $APP) + + [[ -n "$DOKKU_BUILDSTEP" ]] && START_CMD="/start $PROC_NAME" + [[ -z "$DOKKU_BUILDSTEP" ]] && DOKKU_DOCKERFILE_PORT=$(dokku config:get $APP DOKKU_DOCKERFILE_PORT || true) + + + if [[ "$BIND_EXTERNAL" = "false" ]];then + port=${DOKKU_DOCKERFILE_PORT:=5000} + id=$(docker run -d -e PORT=$port $DOCKER_ARGS $IMAGE $START_CMD) + ipaddr=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' $id) + else + id=$(docker run -d -p 5000 -e PORT=5000 $DOCKER_ARGS $IMAGE $START_CMD) + port=$(docker port $id 5000 | sed 's/[0-9.]*://') + ipaddr=127.0.0.1 + fi + + # if we can't post-deploy successfully, kill new container + kill_new() { + docker inspect $id &> /dev/null && docker kill $id > /dev/null + trap - INT TERM EXIT + kill -9 $$ + } + + # run checks first, then post-deploy hooks, which switches Nginx traffic + trap kill_new INT TERM EXIT + dokku_log_info1 "Running pre-flight checks" + pluginhook check-deploy $APP $port $ipaddr $id + trap - INT TERM EXIT + + # now using the new container + echo $id > "$DOKKU_CONTAINER_ID_FILE" + echo $ipaddr > "$DOKKU_IP_FILE" + echo $port > "$DOKKU_PORT_FILE" + echo "http://$(< "$DOKKU_ROOT/HOSTNAME"):$port" > "$DOKKU_ROOT/$APP/URL" + + # cleanup pre-migration files + rm -f $DOKKU_ROOT/$APP/CONTAINER $DOKKU_ROOT/$APP/IP $DOKKU_ROOT/$APP/PORT + CONTAINER_NUM=$(( CONTAINER_NUM + 1 )) + done + done < "$DOKKU_SCALE_FILE" dokku_log_info1 "Running post-deploy" - pluginhook post-deploy $APP $port $ipaddr + pluginhook post-deploy $APP $port $ipaddr # kill the old container - if [[ -n "$oldid" ]]; then + if [[ -n "$oldids" ]]; then # Let the old container finish processing requests, before terminating it WAIT="${DOKKU_WAIT_TO_RETIRE:-60}" dokku_log_info1 "Shutting down old container in $WAIT seconds" @@ -120,13 +145,14 @@ case "$1" in exec >/dev/null 2>/dev/null \"$EXPECTED\"" [[ $DOKKU_TRACE ]] && dokku_log_verbose "$ curl $CURL_ARGS" - + # Capture HTTP response or CURL error message if OUTPUT=$(curl -# $CURL_ARGS 2>&1) ; then # OUTPUT contains the HTTP response @@ -178,7 +178,7 @@ do FAILEDCHECKS=$(( FAILEDCHECKS + 1 )) fi done - + if [ $FAILEDCHECKS -gt 0 ]; then dokku_log_warn "Check attempt $ATTEMPT/$ATTEMPTS failed." SUCCESS=0 diff --git a/plugins/common/functions b/plugins/common/functions index 8db3af6dd..a48b5c499 100755 --- a/plugins/common/functions +++ b/plugins/common/functions @@ -135,3 +135,11 @@ parse_args() { done return 0 } + +copy_from_image() { + local APP="$1"; local IMAGE="dokku/$APP"; local SRC_FILE="$2"; local DST_DIR="$3"; verify_app_name $APP + + CID=$(docker run -d $IMAGE bash) + docker cp "$CID:$SRC_FILE" "$DST_DIR" + docker rm -f "$CID" +} diff --git a/plugins/nginx-vhosts/commands b/plugins/nginx-vhosts/commands index 19b48df10..bd52c7c58 100755 --- a/plugins/nginx-vhosts/commands +++ b/plugins/nginx-vhosts/commands @@ -34,11 +34,18 @@ case "$1" in WILDCARD_SSL="$DOKKU_ROOT/tls" SSL="$DOKKU_ROOT/$APP/tls" - if [[ -z "$DOKKU_APP_LISTEN_PORT" ]] && [[ -f "$DOKKU_ROOT/$APP/PORT" ]]; then - DOKKU_APP_LISTEN_PORT=$(< "$DOKKU_ROOT/$APP/PORT") - fi - if [[ -z "$DOKKU_APP_LISTEN_IP" ]] && [[ -f "$DOKKU_ROOT/$APP/IP" ]]; then - DOKKU_APP_LISTEN_IP=$(< "$DOKKU_ROOT/$APP/IP") + if [[ -z "$DOKKU_APP_LISTEN_PORT" ]] && [[ -z "$DOKKU_APP_LISTEN_IP" ]]; then + shopt -s nullglob + for DOKKU_APP_IP_FILE in $DOKKU_ROOT/$APP/IP.*;do + DOKKU_APP_PORT_FILE=$(echo $DOKKU_APP_IP_FILE | sed -e "s:IP:PORT:g") + DOKKU_APP_LISTENER_IP=$(< $DOKKU_APP_IP_FILE) + DOKKU_APP_LISTENER_PORT=$(< $DOKKU_APP_PORT_FILE) + + DOKKU_APP_LISTENERS+=" " + DOKKU_APP_LISTENERS+="$DOKKU_APP_LISTENER_IP:$DOKKU_APP_LISTENER_PORT" + DOKKU_APP_LISTENERS+=" " + done + shopt -u nullglob fi [[ -f "$DOKKU_ROOT/ENV" ]] && source $DOKKU_ROOT/ENV @@ -100,6 +107,12 @@ EOF if [[ -n "$DOKKU_APP_LISTEN_PORT" ]] && [[ -n "$DOKKU_APP_LISTEN_IP" ]]; then echo "upstream $APP { server $DOKKU_APP_LISTEN_IP:$DOKKU_APP_LISTEN_PORT; }" >> $NGINX_CONF + elif [[ -n "$DOKKU_APP_LISTENERS" ]]; then + echo "upstream $APP { " >> $NGINX_CONF + for listener in $DOKKU_APP_LISTENERS;do + echo " server $listener;" >> $NGINX_CONF + done + echo "}" >> $NGINX_CONF fi dokku_log_info1 "Creating $SCHEME nginx.conf" diff --git a/plugins/nginx-vhosts/post-deploy b/plugins/nginx-vhosts/post-deploy index c803c980b..3b1940dc3 100755 --- a/plugins/nginx-vhosts/post-deploy +++ b/plugins/nginx-vhosts/post-deploy @@ -2,7 +2,7 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x source "$(dirname $0)/../common/functions" -APP="$1"; PORT="$2"; IP="$3" +APP="$1" NO_VHOST=$(dokku config:get $APP NO_VHOST || true) if [[ -n "$NO_VHOST" ]]; then @@ -11,4 +11,4 @@ elif [[ ! -f "$DOKKU_ROOT/$APP/VHOST" ]]; then dokku domains:setup $APP fi -dokku nginx:build-config $APP $PORT $IP +dokku nginx:build-config $APP diff --git a/plugins/ps/commands b/plugins/ps/commands index 4fd227b76..be707dc10 100755 --- a/plugins/ps/commands +++ b/plugins/ps/commands @@ -1,12 +1,13 @@ #!/usr/bin/env bash set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x source "$(dirname $0)/../common/functions" +source "$(dirname $0)/functions" release_and_deploy() { source "$(dirname $0)/../common/functions" local APP="$1"; local IMAGE="dokku/$APP" - if [[ -f "$DOKKU_ROOT/$APP/CONTAINER" ]]; then + if ls $DOKKU_ROOT/$APP/CONTAINER.* &> /dev/null; then if is_image_buildstep_based "$IMAGE"; then IMAGE_SOURCE_TYPE="buildstep" else @@ -97,9 +98,27 @@ case "$1" in done ;; + ps:scale) + [[ -z $2 ]] && echo "Please specify an app to run the command on" && exit 1 + verify_app_name "$2" + + APP="$2"; DOKKU_SCALE_FILE="$DOKKU_ROOT/$APP/DOKKU_SCALE" + shift 2 + + generate_scale_file "$APP" + if [[ -z "$@" ]];then + dokku_log_info1 "Scaling for $APP" + dokku_log_info2 "$(< $DOKKU_SCALE_FILE)" + else + set_scale "$APP" "$@" + fi + release_and_deploy "$APP" + ;; + help | ps:help) cat && cat< List processes running in app container(s) + ps:scale = [=] Set how many processes of a given process to run ps:start Start app container(s) ps:stop Stop app container(s) ps:rebuild Rebuild an app diff --git a/plugins/ps/functions b/plugins/ps/functions new file mode 100755 index 000000000..9664e875d --- /dev/null +++ b/plugins/ps/functions @@ -0,0 +1,45 @@ +#!/usr/bin/env bash +set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x +source "$(dirname $0)/../common/functions" + +generate_scale_file() { + local APP="$1"; local DOKKU_SCALE_FILE="$DOKKU_ROOT/$APP/DOKKU_SCALE" + if [[ ! -f $DOKKU_SCALE_FILE ]]; then + copy_from_image "$APP" "/app/DOKKU_SCALE" "$DOKKU_ROOT/$APP" || dokku_log_info1_quiet "DOKKU_SCALE not found in app image" + if [[ ! -f $DOKKU_SCALE_FILE ]]; then + local TMP_WORK_DIR=$(mktemp -d DOKKU_SCALE.XXXXX) + trap 'rm -rf $TMP_WORK_DIR' EXIT + + copy_from_image "$APP" /app/Procfile $TMP_WORK_DIR || true + if [[ -f $TMP_WORK_DIR/Procfile ]];then + local PROCFILE="$TMP_WORK_DIR/Procfile" + while read line || [ -n "$line" ] + do + local PROC_NAME=${line%%:*} + echo "$PROC_NAME=1" >> $DOKKU_SCALE_FILE + done < "$PROCFILE" + else + echo "default=1" >> $DOKKU_SCALE_FILE + fi + + dokku_log_info1_quiet "New DOKKU_SCALE file generated" + dokku_log_info1_quiet "$(< $DOKKU_SCALE_FILE)" + fi + fi +} + +set_scale() { + local APP="$1"; local DOKKU_SCALE_FILE="$DOKKU_ROOT/$APP/DOKKU_SCALE" + shift 1 + local SCALE_SETTINGS=("$@") + for procscale in "${SCALE_SETTINGS[@]}"; do + PROC_NAME=${procscale%%=*} + PROC_COUNT=${procscale#*=} + dokku_log_info1_quiet "Scaling $APP:$PROC_NAME to $PROC_COUNT" + if (egrep -q ^${PROC_NAME}= $DOKKU_SCALE_FILE > /dev/null 2>&1);then + sed --in-place "s:^${PROC_NAME}=.*:$PROC_NAME=$PROC_COUNT:g" $DOKKU_SCALE_FILE + else + echo "$PROC_NAME=$PROC_COUNT" >> $DOKKU_SCALE_FILE + fi + done +} diff --git a/plugins/ps/pre-deploy b/plugins/ps/pre-deploy new file mode 100755 index 000000000..bc4f77c94 --- /dev/null +++ b/plugins/ps/pre-deploy @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x +source "$(dirname $0)/../common/functions" +source "$(dirname $0)/functions" + +APP="$1" + +generate_scale_file $APP From e27d0e6fa5c14b1741fc282c3db580ff76c4d502 Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Fri, 17 Apr 2015 18:57:37 -0700 Subject: [PATCH 02/37] wrap container id checks and reading into common function that attempts new and old style container id files aggregate log streams --- dokku | 10 +-------- plugins/00_dokku-standard/commands | 25 ++++++++++++++++----- plugins/apps/commands | 11 ++++----- plugins/checks/check-deploy | 5 +++-- plugins/common/functions | 25 +++++++++++++++++++++ plugins/nginx-vhosts/commands | 12 +++++----- plugins/ps/commands | 36 +++++++++++++++++------------- 7 files changed, 80 insertions(+), 44 deletions(-) diff --git a/dokku b/dokku index e3ac8da70..550d29037 100755 --- a/dokku +++ b/dokku @@ -74,21 +74,13 @@ case "$1" in PROC_NAME=${line%%=*} PROC_COUNT=${line#*=} CONTAINER_NUM=1 + oldids=$(get_container_ids $APP) while [[ $CONTAINER_NUM -le $PROC_COUNT ]];do DOKKU_CONTAINER_ID_FILE="$DOKKU_ROOT/$APP/CONTAINER.$PROC_NAME.$CONTAINER_NUM" DOKKU_IP_FILE="$DOKKU_ROOT/$APP/IP.$PROC_NAME.$CONTAINER_NUM" DOKKU_PORT_FILE="$DOKKU_ROOT/$APP/PORT.$PROC_NAME.$CONTAINER_NUM" - # try old form even in case we're migrating dokku versions - if [[ -f "$DOKKU_CONTAINER_ID_FILE" ]]; then - oldids+=" " - oldids+=$(< "$DOKKU_CONTAINER_ID_FILE") - oldids+=" " - elif [[ -f "$DOKKU_ROOT/$APP/CONTAINER" ]]; then - oldids+=$(< "$DOKKU_ROOT/$APP/CONTAINER") - fi - # start the app DOCKER_ARGS=$(: | pluginhook docker-args $APP deploy) DOCKER_ARGS+=$(: | pluginhook docker-args-deploy $APP) diff --git a/plugins/00_dokku-standard/commands b/plugins/00_dokku-standard/commands index a4d50b49d..d8d4dd7ee 100755 --- a/plugins/00_dokku-standard/commands +++ b/plugins/00_dokku-standard/commands @@ -114,8 +114,11 @@ case "$1" in dokku_col_log_info2_quiet "App Name" "Container id" for app in $apps; do - if [[ -f $app/CONTAINER ]]; then - dokku_col_log_msg "$(basename $app)" "$(< $app/CONTAINER)" + DOKKU_APP_CIDS=$(get_container_ids "$(basename $app)") + if [[ -n $DOKKU_APP_CIDS ]]; then + for DOKKU_APP_CID in $DOKKU_APP_CIDS; do + dokku_col_log_msg "$(basename $app)" "$DOKKU_APP_CID" + done else dokku_col_log_msg "$(basename $app)" fi @@ -127,13 +130,23 @@ case "$1" in verify_app_name "$2" APP="$2"; - if [[ -f "$DOKKU_ROOT/$APP/CONTAINER" ]]; then - CONTAINER=$(<$DOKKU_ROOT/$APP/CONTAINER) + if (is_deployed $APP); then + CONTAINER_IDS=( $(get_container_ids $APP) ) + LAST_CONTAINER_ID=${CONTAINER_IDS[${#CONTAINER_IDS[@]} - 1]} + if [[ $3 == "-t" ]]; then - docker logs --follow $CONTAINER + DOKKU_LOGS_ARGS="--follow" else - docker logs $CONTAINER | tail -n 100 + DOKKU_LOGS_ARGS="--tail 100" fi + for CID in "${CONTAINER_IDS[@]}";do + if [[ "$CID" != "$LAST_CONTAINER_ID" ]];then + DOKKU_LOGS_CMD+="docker logs $DOKKU_LOGS_ARGS $CID& " + else + DOKKU_LOGS_CMD+="docker logs $DOKKU_LOGS_ARGS $CID; " + fi + done + bash -c "($DOKKU_LOGS_CMD)" else echo "Application's container not found" fi diff --git a/plugins/apps/commands b/plugins/apps/commands index a82aa1e4f..935d2b1f7 100755 --- a/plugins/apps/commands +++ b/plugins/apps/commands @@ -40,11 +40,12 @@ case "$1" in echo "Destroying $APP (including all add-ons)" pluginhook pre-delete $APP - if [[ -f "$DOKKU_ROOT/$APP/CONTAINER" ]]; then - ID=$(< "$DOKKU_ROOT/$APP/CONTAINER") - - docker stop $ID > /dev/null || true - docker rm $ID > /dev/null || true + DOKKU_APP_CIDS=$(get_container_ids $APP) + if [[ -n $DOKKU_APP_CIDS ]]; then + for ID in $DOKKU_APP_CIDS;do + docker stop $ID > /dev/null || true + docker rm $ID > /dev/null || true + done fi docker images | grep $IMAGE | awk '{print $3}' | xargs docker rmi &> /dev/null & diff --git a/plugins/checks/check-deploy b/plugins/checks/check-deploy index a6a67deb8..632f5d4e4 100755 --- a/plugins/checks/check-deploy +++ b/plugins/checks/check-deploy @@ -44,8 +44,9 @@ fi if [[ -z "$DOKKU_APP_LISTEN_IP" ]] && [[ -f "$DOKKU_ROOT/$APP/IP" ]]; then DOKKU_APP_LISTEN_IP=$(< "$DOKKU_ROOT/$APP/IP") fi -if [[ -z "$DOKKU_APP_CONTAINER_ID" ]] && [[ -f "$DOKKU_ROOT/$APP/CONTAINER" ]]; then - DOKKU_APP_CONTAINER_ID=$(< "$DOKKU_ROOT/$APP/CONTAINER") +if [[ -z "$DOKKU_APP_CONTAINER_ID" ]]; then + DOKKU_APP_CIDS=( $(get_container_ids $APP) ) + DOKKU_APP_CONTAINER_ID=${DOKKU_APP_CIDS[0]} fi diff --git a/plugins/common/functions b/plugins/common/functions index a48b5c499..809d7435d 100755 --- a/plugins/common/functions +++ b/plugins/common/functions @@ -143,3 +143,28 @@ copy_from_image() { docker cp "$CID:$SRC_FILE" "$DST_DIR" docker rm -f "$CID" } + +is_deployed() { + APP="$1" + verify_app_name $APP + if [[ -f $DOKKU_ROOT/$APP/CONTAINER ]] || ls $DOKKU_ROOT/$APP/CONTAINER.* &> /dev/null;then + return 0 + else + return 1 + fi +} + +get_container_ids() { + APP="$1" + verify_app_name $APP + [[ -f $DOKKU_ROOT/$APP/CONTAINER ]] && DOKKU_CIDS+=$(< $DOKKU_ROOT/$APP/CONTAINER) + + shopt -s nullglob + for DOKKU_CID_FILE in $DOKKU_ROOT/$APP/CONTAINER.*; do + DOKKU_CIDS+=" " + DOKKU_CIDS+=$(< $DOKKU_CID_FILE) + DOKKU_CIDS+=" " + done + shopt -u nullglob + echo $DOKKU_CIDS +} diff --git a/plugins/nginx-vhosts/commands b/plugins/nginx-vhosts/commands index bd52c7c58..8ec5b41d7 100755 --- a/plugins/nginx-vhosts/commands +++ b/plugins/nginx-vhosts/commands @@ -118,14 +118,12 @@ EOF dokku_log_info1 "Creating $SCHEME nginx.conf" mv $NGINX_CONF "$DOKKU_ROOT/$APP/nginx.conf" - if [[ -n "$DOKKU_APP_LISTEN_PORT" ]] && [[ -n "$DOKKU_APP_LISTEN_IP" ]]; then - dokku_log_info1 "Running nginx-pre-reload" - pluginhook nginx-pre-reload $APP $DOKKU_APP_LISTEN_PORT $DOKKU_APP_LISTEN_IP + dokku_log_info1 "Running nginx-pre-reload" + pluginhook nginx-pre-reload $APP $DOKKU_APP_LISTEN_PORT $DOKKU_APP_LISTEN_IP - dokku_log_verbose "Reloading nginx" - validate_nginx - restart_nginx - fi + dokku_log_verbose "Reloading nginx" + validate_nginx + restart_nginx echo "# THIS FILE IS GENERATED BY DOKKU - DO NOT EDIT, YOUR CHANGES WILL BE OVERWRITTEN" > $URLS_PATH xargs -i echo "https://{}" <<< "${SSL_VHOSTS}" >> $URLS_PATH diff --git a/plugins/ps/commands b/plugins/ps/commands index be707dc10..f1a25d7f0 100755 --- a/plugins/ps/commands +++ b/plugins/ps/commands @@ -29,20 +29,22 @@ case "$1" in [[ -z $2 ]] && echo "Please specify an app to run the command on" && exit 1 verify_app_name "$2" - APP="$2"; [[ -f "$DOKKU_ROOT/$APP/CONTAINER" ]] && CONTAINER_ID=$(< "$DOKKU_ROOT/$APP/CONTAINER") - [[ -z "$CONTAINER_ID" ]] && echo "App $APP has not been deployed" && exit 0 + APP="$2"; CONTAINER_IDS=$(get_container_ids $APP) + ! (is_deployed $APP) && echo "App $APP has not been deployed" && exit 0 - docker exec -ti "$CONTAINER_ID" /bin/bash -c "ps auxwww" + for CID in $CONTAINER_IDS; do + docker exec -ti "$CID" /bin/bash -c "ps auxwww" + done ;; ps:start) [[ -z $2 ]] && echo "Please specify an app to run the command on" && exit 1 verify_app_name "$2" - APP="$2"; [[ -f "$DOKKU_ROOT/$APP/CONTAINER" ]] && CONTAINER_ID=$(< "$DOKKU_ROOT/$APP/CONTAINER") - [[ -z "$CONTAINER_ID" ]] && echo "App $APP has not been deployed" && exit 0 + APP="$2"; CONTAINER_IDS=( $(get_container_ids $APP) ) + ! (is_deployed $APP) && echo "App $APP has not been deployed" && exit 0 - if [[ "$(docker ps -q --no-trunc| grep -q $CONTAINER_ID; echo $?)" != "0" ]]; then + if [[ "$(docker ps -q --no-trunc| grep -q ${CONTAINER_IDS[0]}; echo $?)" != "0" ]]; then release_and_deploy $APP else echo "App $APP already running" @@ -53,12 +55,15 @@ case "$1" in [[ -z $2 ]] && echo "Please specify an app to run the command on" && exit 1 verify_app_name "$2" - APP="$2"; [[ -f "$DOKKU_ROOT/$APP/CONTAINER" ]] && CONTAINER_ID=$(< "$DOKKU_ROOT/$APP/CONTAINER") - [[ -z "$CONTAINER_ID" ]] && echo "App $APP has not been deployed" && exit 0 + APP="$2"; CONTAINER_IDS=$(get_container_ids $APP) + ! (is_deployed $APP) && echo "App $APP has not been deployed" && exit 0 - if [[ "$(docker ps -q --no-trunc| grep -q $CONTAINER_ID; echo $?)" = "0" ]]; then + CONTAINER_IDS_EGREP_PATTERN=$(echo $CONTAINER_IDS | xargs | sed -e "s: :|:g") + if [[ "$(docker ps -q --no-trunc| egrep -q $CONTAINER_IDS_EGREP_PATTERN; echo $?)" = "0" ]]; then echo "Stopping $APP ..." - docker stop $CONTAINER_ID > /dev/null + for CID in $CONTAINER_IDS;do + docker stop $CID > /dev/null + done else echo "App $APP already stopped" fi @@ -74,18 +79,19 @@ case "$1" in ps:rebuildall) shopt -s nullglob - for app in $DOKKU_ROOT/*/CONTAINER; do - APP=$(basename "$(dirname $app)"); - dokku ps:rebuild $APP + for app in $DOKKU_ROOT/*; do + APP=$(basename "$(dirname $app)") + is_deployed && dokku ps:rebuild $APP done + shopt -u nullglob ;; ps:restart) [[ -z $2 ]] && echo "Please specify an app to run the command on" && exit 1 verify_app_name "$2" - APP="$2"; [[ -f "$DOKKU_ROOT/$APP/CONTAINER" ]] && CONTAINER_ID=$(< "$DOKKU_ROOT/$APP/CONTAINER") - [[ -z "$CONTAINER_ID" ]] && echo "App $APP has not been deployed" && exit 0 + APP="$2" + ! (is_deployed $APP) && echo "App $APP has not been deployed" && exit 0 release_and_deploy $APP ;; From 99d2601f2f89d134d4059cdd7cda9eb49c8e8f32 Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Fri, 17 Apr 2015 20:17:42 -0700 Subject: [PATCH 03/37] fix tests --- plugins/00_dokku-standard/commands | 4 ++- tests/unit/client.bats | 30 +++++++++++++--------- tests/unit/core_ports.bats | 2 +- tests/unit/ps-buildstep.bats | 40 ++++++++++++++++++------------ tests/unit/ps-dockerfile.bats | 40 ++++++++++++++++++------------ 5 files changed, 70 insertions(+), 46 deletions(-) diff --git a/plugins/00_dokku-standard/commands b/plugins/00_dokku-standard/commands index d8d4dd7ee..9ad493436 100755 --- a/plugins/00_dokku-standard/commands +++ b/plugins/00_dokku-standard/commands @@ -194,7 +194,9 @@ case "$1" in if [[ -f "$DOKKU_ROOT/VHOST" ]]; then echo "$SCHEME://$(< "$DOKKU_ROOT/VHOST")" else - echo "$SCHEME://$(< "$DOKKU_ROOT/HOSTNAME"):$(< "$DOKKU_ROOT/$APP/PORT")" + for PORT_FILE in $DOKKU_ROOT/$APP/PORT.*; do + echo "$SCHEME://$(< "$DOKKU_ROOT/HOSTNAME"):$(< "$PORT_FILE")" + done fi ;; diff --git a/tests/unit/client.bats b/tests/unit/client.bats index 2d5e5e677..786b23524 100644 --- a/tests/unit/client.bats +++ b/tests/unit/client.bats @@ -131,10 +131,12 @@ teardown() { echo "output: "$output echo "status: "$status assert_success - run bash -c "docker ps -q --no-trunc | grep -q $(< $DOKKU_ROOT/$TEST_APP/CONTAINER)" - echo "output: "$output - echo "status: "$status - assert_success + for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.*; do + run bash -c "docker ps -q --no-trunc | grep -q $(< $CID_FILE)" + echo "output: "$output + echo "status: "$status + assert_success + done } @test "(client) ps:stop" { @@ -143,10 +145,12 @@ teardown() { echo "output: "$output echo "status: "$status assert_success - run bash -c "docker ps -q --no-trunc | grep -q $(< $DOKKU_ROOT/$TEST_APP/CONTAINER)" - echo "output: "$output - echo "status: "$status - assert_failure + for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.*; do + run bash -c "docker ps -q --no-trunc | grep -q $(< $CID_FILE)" + echo "output: "$output + echo "status: "$status + assert_failure + done } @test "(client) ps:restart" { @@ -155,8 +159,10 @@ teardown() { echo "output: "$output echo "status: "$status assert_success - run bash -c "docker ps -q --no-trunc | grep -q $(< $DOKKU_ROOT/$TEST_APP/CONTAINER)" - echo "output: "$output - echo "status: "$status - assert_success + for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.*; do + run bash -c "docker ps -q --no-trunc | grep -q $(< $CID_FILE)" + echo "output: "$output + echo "status: "$status + assert_success + done } diff --git a/tests/unit/core_ports.bats b/tests/unit/core_ports.bats index f0076b381..0f4de64a3 100644 --- a/tests/unit/core_ports.bats +++ b/tests/unit/core_ports.bats @@ -111,7 +111,7 @@ teardown() { @test "(core) dockerfile port exposure" { deploy_app dockerfile - run bash -c "grep upstream $DOKKU_ROOT/$TEST_APP/nginx.conf | grep 3000" + run bash -c "grep -A1 upstream $DOKKU_ROOT/$TEST_APP/nginx.conf | grep 3000" echo "output: "$output echo "status: "$status assert_success diff --git a/tests/unit/ps-buildstep.bats b/tests/unit/ps-buildstep.bats index 934a57b65..1eb0d5c70 100644 --- a/tests/unit/ps-buildstep.bats +++ b/tests/unit/ps-buildstep.bats @@ -26,35 +26,43 @@ teardown() { echo "output: "$output echo "status: "$status assert_success - run bash -c "docker ps -q --no-trunc | grep -q $(< $DOKKU_ROOT/$TEST_APP/CONTAINER)" - echo "output: "$output - echo "status: "$status - assert_failure + for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.*; do + run bash -c "docker ps -q --no-trunc | grep -q $(< $CID_FILE)" + echo "output: "$output + echo "status: "$status + assert_failure + done run bash -c "dokku ps:start $TEST_APP" echo "output: "$output echo "status: "$status assert_success - run bash -c "docker ps -q --no-trunc | grep -q $(< $DOKKU_ROOT/$TEST_APP/CONTAINER)" - echo "output: "$output - echo "status: "$status - assert_success + for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.*; do + run bash -c "docker ps -q --no-trunc | grep -q $(< $CID_FILE)" + echo "output: "$output + echo "status: "$status + assert_success + done run bash -c "dokku ps:restart $TEST_APP" echo "output: "$output echo "status: "$status assert_success - run bash -c "docker ps -q --no-trunc | grep -q $(< $DOKKU_ROOT/$TEST_APP/CONTAINER)" - echo "output: "$output - echo "status: "$status - assert_success + for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.*; do + run bash -c "docker ps -q --no-trunc | grep -q $(< $CID_FILE)" + echo "output: "$output + echo "status: "$status + assert_success + done run bash -c "dokku ps:rebuild $TEST_APP" echo "output: "$output echo "status: "$status assert_success - run bash -c "docker ps -q --no-trunc | grep -q $(< $DOKKU_ROOT/$TEST_APP/CONTAINER)" - echo "output: "$output - echo "status: "$status - assert_success + for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.*; do + run bash -c "docker ps -q --no-trunc | grep -q $(< $CID_FILE)" + echo "output: "$output + echo "status: "$status + assert_success + done } diff --git a/tests/unit/ps-dockerfile.bats b/tests/unit/ps-dockerfile.bats index de4fea29e..bfd187982 100644 --- a/tests/unit/ps-dockerfile.bats +++ b/tests/unit/ps-dockerfile.bats @@ -26,35 +26,43 @@ teardown() { echo "output: "$output echo "status: "$status assert_success - run bash -c "docker ps -q --no-trunc | grep -q $(< $DOKKU_ROOT/$TEST_APP/CONTAINER)" - echo "output: "$output - echo "status: "$status - assert_failure + for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.*; do + run bash -c "docker ps -q --no-trunc | grep -q $(< $CID_FILE)" + echo "output: "$output + echo "status: "$status + assert_failure + done run bash -c "dokku ps:start $TEST_APP" echo "output: "$output echo "status: "$status assert_success - run bash -c "docker ps -q --no-trunc | grep -q $(< $DOKKU_ROOT/$TEST_APP/CONTAINER)" - echo "output: "$output - echo "status: "$status - assert_success + for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.*; do + run bash -c "docker ps -q --no-trunc | grep -q $(< $CID_FILE)" + echo "output: "$output + echo "status: "$status + assert_success + done run bash -c "dokku ps:restart $TEST_APP" echo "output: "$output echo "status: "$status assert_success - run bash -c "docker ps -q --no-trunc | grep -q $(< $DOKKU_ROOT/$TEST_APP/CONTAINER)" - echo "output: "$output - echo "status: "$status - assert_success + for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.*; do + run bash -c "docker ps -q --no-trunc | grep -q $(< $CID_FILE)" + echo "output: "$output + echo "status: "$status + assert_success + done run bash -c "dokku ps:rebuild $TEST_APP" echo "output: "$output echo "status: "$status assert_success - run bash -c "docker ps -q --no-trunc | grep -q $(< $DOKKU_ROOT/$TEST_APP/CONTAINER)" - echo "output: "$output - echo "status: "$status - assert_success + for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.*; do + run bash -c "docker ps -q --no-trunc | grep -q $(< $CID_FILE)" + echo "output: "$output + echo "status: "$status + assert_success + done } From 5c85e8bf658c15207c13b12b366a89b182688b02 Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Fri, 17 Apr 2015 20:21:41 -0700 Subject: [PATCH 04/37] app repo SCALE file takes precedence over local settings --- plugins/ps/functions | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/plugins/ps/functions b/plugins/ps/functions index 9664e875d..0feb92bd8 100755 --- a/plugins/ps/functions +++ b/plugins/ps/functions @@ -4,27 +4,25 @@ source "$(dirname $0)/../common/functions" generate_scale_file() { local APP="$1"; local DOKKU_SCALE_FILE="$DOKKU_ROOT/$APP/DOKKU_SCALE" + copy_from_image "$APP" "/app/DOKKU_SCALE" "$DOKKU_ROOT/$APP" || dokku_log_info1_quiet "DOKKU_SCALE not found in app image" if [[ ! -f $DOKKU_SCALE_FILE ]]; then - copy_from_image "$APP" "/app/DOKKU_SCALE" "$DOKKU_ROOT/$APP" || dokku_log_info1_quiet "DOKKU_SCALE not found in app image" - if [[ ! -f $DOKKU_SCALE_FILE ]]; then - local TMP_WORK_DIR=$(mktemp -d DOKKU_SCALE.XXXXX) - trap 'rm -rf $TMP_WORK_DIR' EXIT + local TMP_WORK_DIR=$(mktemp -d DOKKU_SCALE.XXXXX) + trap 'rm -rf $TMP_WORK_DIR' EXIT - copy_from_image "$APP" /app/Procfile $TMP_WORK_DIR || true - if [[ -f $TMP_WORK_DIR/Procfile ]];then - local PROCFILE="$TMP_WORK_DIR/Procfile" - while read line || [ -n "$line" ] - do - local PROC_NAME=${line%%:*} - echo "$PROC_NAME=1" >> $DOKKU_SCALE_FILE - done < "$PROCFILE" - else - echo "default=1" >> $DOKKU_SCALE_FILE - fi - - dokku_log_info1_quiet "New DOKKU_SCALE file generated" - dokku_log_info1_quiet "$(< $DOKKU_SCALE_FILE)" + copy_from_image "$APP" /app/Procfile $TMP_WORK_DIR || true + if [[ -f $TMP_WORK_DIR/Procfile ]];then + local PROCFILE="$TMP_WORK_DIR/Procfile" + while read line || [ -n "$line" ] + do + local PROC_NAME=${line%%:*} + echo "$PROC_NAME=1" >> $DOKKU_SCALE_FILE + done < "$PROCFILE" + else + echo "default=1" >> $DOKKU_SCALE_FILE fi + + dokku_log_info1_quiet "New DOKKU_SCALE file generated" + dokku_log_info1_quiet "$(< $DOKKU_SCALE_FILE)" fi } From 389b5efa067b9ad6a5bd2e4d4f3c4888d940ec85 Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Fri, 17 Apr 2015 20:40:20 -0700 Subject: [PATCH 05/37] only release and deploy if we're modifying scale settings --- plugins/common/functions | 2 +- plugins/ps/commands | 2 +- plugins/ps/functions | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/common/functions b/plugins/common/functions index 809d7435d..a58738e29 100755 --- a/plugins/common/functions +++ b/plugins/common/functions @@ -141,7 +141,7 @@ copy_from_image() { CID=$(docker run -d $IMAGE bash) docker cp "$CID:$SRC_FILE" "$DST_DIR" - docker rm -f "$CID" + docker rm -f "$CID" &> /dev/null } is_deployed() { diff --git a/plugins/ps/commands b/plugins/ps/commands index f1a25d7f0..e6e35c916 100755 --- a/plugins/ps/commands +++ b/plugins/ps/commands @@ -117,8 +117,8 @@ case "$1" in dokku_log_info2 "$(< $DOKKU_SCALE_FILE)" else set_scale "$APP" "$@" + release_and_deploy "$APP" fi - release_and_deploy "$APP" ;; help | ps:help) diff --git a/plugins/ps/functions b/plugins/ps/functions index 0feb92bd8..8b10b350d 100755 --- a/plugins/ps/functions +++ b/plugins/ps/functions @@ -4,7 +4,7 @@ source "$(dirname $0)/../common/functions" generate_scale_file() { local APP="$1"; local DOKKU_SCALE_FILE="$DOKKU_ROOT/$APP/DOKKU_SCALE" - copy_from_image "$APP" "/app/DOKKU_SCALE" "$DOKKU_ROOT/$APP" || dokku_log_info1_quiet "DOKKU_SCALE not found in app image" + copy_from_image "$APP" "/app/DOKKU_SCALE" "$DOKKU_ROOT/$APP" 2>/dev/null || dokku_log_info1_quiet "DOKKU_SCALE not found in app image" if [[ ! -f $DOKKU_SCALE_FILE ]]; then local TMP_WORK_DIR=$(mktemp -d DOKKU_SCALE.XXXXX) trap 'rm -rf $TMP_WORK_DIR' EXIT From d42bb79d38d5fd2d650ca06af6c51319768ff874 Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Fri, 17 Apr 2015 21:48:47 -0700 Subject: [PATCH 06/37] handle non-herokuish deploys that don't create Procfiles. i.e. buildpack-nginx --- plugins/ps/functions | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/plugins/ps/functions b/plugins/ps/functions index 8b10b350d..4c5a1a398 100755 --- a/plugins/ps/functions +++ b/plugins/ps/functions @@ -9,18 +9,25 @@ generate_scale_file() { local TMP_WORK_DIR=$(mktemp -d DOKKU_SCALE.XXXXX) trap 'rm -rf $TMP_WORK_DIR' EXIT - copy_from_image "$APP" /app/Procfile $TMP_WORK_DIR || true + copy_from_image "$APP" /app/Procfile $TMP_WORK_DIR 2>/dev/null || true + copy_from_image "$APP" /app/.release $TMP_WORK_DIR 2>/dev/null || true + if [[ -f $TMP_WORK_DIR/Procfile ]];then local PROCFILE="$TMP_WORK_DIR/Procfile" - while read line || [ -n "$line" ] - do - local PROC_NAME=${line%%:*} - echo "$PROC_NAME=1" >> $DOKKU_SCALE_FILE - done < "$PROCFILE" + elif [[ -f $TMP_WORK_DIR/.release ]];then + local PROCFILE="$TMP_WORK_DIR/.release" else echo "default=1" >> $DOKKU_SCALE_FILE fi + while read line || [ -n "$line" ] + do + local PROC_NAME=${line%%:*} + local PROC_CMD=${line#*:} + [[ "$PROC_NAME" =~ -.* ]] && continue + [[ -n "$PROC_CMD" ]] && echo "$PROC_NAME=1" >> $DOKKU_SCALE_FILE + done < "$PROCFILE" + dokku_log_info1_quiet "New DOKKU_SCALE file generated" dokku_log_info1_quiet "$(< $DOKKU_SCALE_FILE)" fi From 0f8be7c946a1251d4369ee7ecafa105838431081 Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Sat, 18 Apr 2015 10:21:28 -0700 Subject: [PATCH 07/37] fix missing tmpdir prefix --- tests/unit/test_helper.bash | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unit/test_helper.bash b/tests/unit/test_helper.bash index 08d16f8ae..6f89e3a86 100644 --- a/tests/unit/test_helper.bash +++ b/tests/unit/test_helper.bash @@ -98,7 +98,7 @@ add_domain() { deploy_app() { APP_TYPE="$1"; APP_TYPE=${APP_TYPE:="nodejs-express"} - TMP=$(mktemp -d -t "$TARGET.XXXXX") + TMP=$(mktemp -d -t "dokku.me.XXXXX") rmdir $TMP && cp -r ./tests/apps/$APP_TYPE $TMP cd $TMP git init @@ -113,7 +113,7 @@ deploy_app() { } setup_client_repo() { - TMP=$(mktemp -d -t "$TARGET.XXXXX") + TMP=$(mktemp -d -t "dokku.me.XXXXX") rmdir $TMP && cp -r ./tests/apps/nodejs-express $TMP cd $TMP git init From 435f7e69eb8b71c6cfc45e8bdacffd87154bcc20 Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Sat, 18 Apr 2015 10:37:17 -0700 Subject: [PATCH 08/37] only attempt copy if image exists --- plugins/common/functions | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/plugins/common/functions b/plugins/common/functions index a58738e29..f3cb3af8b 100755 --- a/plugins/common/functions +++ b/plugins/common/functions @@ -139,9 +139,14 @@ parse_args() { copy_from_image() { local APP="$1"; local IMAGE="dokku/$APP"; local SRC_FILE="$2"; local DST_DIR="$3"; verify_app_name $APP - CID=$(docker run -d $IMAGE bash) - docker cp "$CID:$SRC_FILE" "$DST_DIR" - docker rm -f "$CID" &> /dev/null + DOKKU_APP_IMAGES=$(docker images -q $IMAGE) + if [[ -n "$DOKKU_APP_IMAGES" ]]; then + CID=$(docker run -d $IMAGE bash) + docker cp "$CID:$SRC_FILE" "$DST_DIR" + docker rm -f "$CID" &> /dev/null + else + return 1 + fi } is_deployed() { From d5cc7595fd9224b8cb6812e17f218de150091ba2 Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Sat, 18 Apr 2015 10:38:07 -0700 Subject: [PATCH 09/37] default web proc. avoid unclear file not found error when procfile is missing --- plugins/ps/functions | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/plugins/ps/functions b/plugins/ps/functions index 4c5a1a398..73b2d6de9 100755 --- a/plugins/ps/functions +++ b/plugins/ps/functions @@ -6,7 +6,7 @@ generate_scale_file() { local APP="$1"; local DOKKU_SCALE_FILE="$DOKKU_ROOT/$APP/DOKKU_SCALE" copy_from_image "$APP" "/app/DOKKU_SCALE" "$DOKKU_ROOT/$APP" 2>/dev/null || dokku_log_info1_quiet "DOKKU_SCALE not found in app image" if [[ ! -f $DOKKU_SCALE_FILE ]]; then - local TMP_WORK_DIR=$(mktemp -d DOKKU_SCALE.XXXXX) + local TMP_WORK_DIR=$(mktemp --tmpdir=/tmp -d DOKKU_SCALE.XXXXX) trap 'rm -rf $TMP_WORK_DIR' EXIT copy_from_image "$APP" /app/Procfile $TMP_WORK_DIR 2>/dev/null || true @@ -17,16 +17,18 @@ generate_scale_file() { elif [[ -f $TMP_WORK_DIR/.release ]];then local PROCFILE="$TMP_WORK_DIR/.release" else - echo "default=1" >> $DOKKU_SCALE_FILE + echo "web=1" >> $DOKKU_SCALE_FILE fi - while read line || [ -n "$line" ] - do - local PROC_NAME=${line%%:*} - local PROC_CMD=${line#*:} - [[ "$PROC_NAME" =~ -.* ]] && continue - [[ -n "$PROC_CMD" ]] && echo "$PROC_NAME=1" >> $DOKKU_SCALE_FILE - done < "$PROCFILE" + if [[ -f $PROCFILE ]]; then + while read line || [ -n "$line" ] + do + local PROC_NAME=${line%%:*} + local PROC_CMD=${line#*:} + [[ "$PROC_NAME" =~ -.* ]] && continue + [[ -n "$PROC_CMD" ]] && echo "$PROC_NAME=1" >> $DOKKU_SCALE_FILE + done < "$PROCFILE" + fi dokku_log_info1_quiet "New DOKKU_SCALE file generated" dokku_log_info1_quiet "$(< $DOKKU_SCALE_FILE)" From bbc03dbfdda63dd67ac35ea9baff9d2af2e35634 Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Sat, 18 Apr 2015 15:39:08 -0700 Subject: [PATCH 10/37] helper functions --- plugins/common/functions | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/plugins/common/functions b/plugins/common/functions index f3cb3af8b..9c16a900f 100755 --- a/plugins/common/functions +++ b/plugins/common/functions @@ -110,12 +110,31 @@ verify_app_name() { return 0 } +verify_app_image() { + local APP="$1"; local IMAGE="dokku/$APP" + DOKKU_APP_IMAGES=$(docker images -q $IMAGE) + if [[ -n "$DOKKU_APP_IMAGES" ]]; then + return 0 + else + return 1 + fi +} + is_image_buildstep_based() { # circleci can't support --rm as they run lxc in lxc [[ ! -f "/home/ubuntu/.circlerc" ]] && local DOCKER_ARGS="--rm" docker run --entrypoint="/bin/bash" $DOCKER_ARGS "$@" -c "[[ -f /exec ]]" } +is_number() { + local NUMBER=$1; local NUM_RE='^[0-9]+$' + if [[ $NUMBER =~ $NUM_RE ]];then + return 0 + else + return 1 + fi +} + parse_args() { for arg in "$@"; do case "$arg" in @@ -139,8 +158,7 @@ parse_args() { copy_from_image() { local APP="$1"; local IMAGE="dokku/$APP"; local SRC_FILE="$2"; local DST_DIR="$3"; verify_app_name $APP - DOKKU_APP_IMAGES=$(docker images -q $IMAGE) - if [[ -n "$DOKKU_APP_IMAGES" ]]; then + if verify_app_image "$APP"; then CID=$(docker run -d $IMAGE bash) docker cp "$CID:$SRC_FILE" "$DST_DIR" docker rm -f "$CID" &> /dev/null From 14cc01dd5b4bb4acf1e3909ae258092b1d09fabf Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Sat, 18 Apr 2015 15:39:48 -0700 Subject: [PATCH 11/37] use helper functions --- plugins/ps/commands | 2 +- plugins/ps/functions | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/ps/commands b/plugins/ps/commands index e6e35c916..8855ba21f 100755 --- a/plugins/ps/commands +++ b/plugins/ps/commands @@ -7,7 +7,7 @@ release_and_deploy() { source "$(dirname $0)/../common/functions" local APP="$1"; local IMAGE="dokku/$APP" - if ls $DOKKU_ROOT/$APP/CONTAINER.* &> /dev/null; then + if verify_app_image "$APP"; then if is_image_buildstep_based "$IMAGE"; then IMAGE_SOURCE_TYPE="buildstep" else diff --git a/plugins/ps/functions b/plugins/ps/functions index 73b2d6de9..d77af8d1d 100755 --- a/plugins/ps/functions +++ b/plugins/ps/functions @@ -31,7 +31,7 @@ generate_scale_file() { fi dokku_log_info1_quiet "New DOKKU_SCALE file generated" - dokku_log_info1_quiet "$(< $DOKKU_SCALE_FILE)" + dokku_log_info2_quiet "$(< $DOKKU_SCALE_FILE)" fi } @@ -42,6 +42,7 @@ set_scale() { for procscale in "${SCALE_SETTINGS[@]}"; do PROC_NAME=${procscale%%=*} PROC_COUNT=${procscale#*=} + is_number $PROC_COUNT || dokku_log_fail "ps:scale $PROC_COUNT is not a number" dokku_log_info1_quiet "Scaling $APP:$PROC_NAME to $PROC_COUNT" if (egrep -q ^${PROC_NAME}= $DOKKU_SCALE_FILE > /dev/null 2>&1);then sed --in-place "s:^${PROC_NAME}=.*:$PROC_NAME=$PROC_COUNT:g" $DOKKU_SCALE_FILE From 930987ad02eebe6e515e380b51a1f42ec7977c27 Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Sat, 18 Apr 2015 15:40:31 -0700 Subject: [PATCH 12/37] container/ip/port file cleanup when scaling down. more tests --- dokku | 22 ++++++++--- tests/unit/ps-buildstep.bats | 72 +++++++++++++++++++++++++++++------ tests/unit/ps-dockerfile.bats | 72 +++++++++++++++++++++++++++++------ 3 files changed, 138 insertions(+), 28 deletions(-) diff --git a/dokku b/dokku index 550d29037..b1acacf6c 100755 --- a/dokku +++ b/dokku @@ -73,13 +73,13 @@ case "$1" in do PROC_NAME=${line%%=*} PROC_COUNT=${line#*=} - CONTAINER_NUM=1 + CONTAINER_INDEX=1 oldids=$(get_container_ids $APP) - while [[ $CONTAINER_NUM -le $PROC_COUNT ]];do - DOKKU_CONTAINER_ID_FILE="$DOKKU_ROOT/$APP/CONTAINER.$PROC_NAME.$CONTAINER_NUM" - DOKKU_IP_FILE="$DOKKU_ROOT/$APP/IP.$PROC_NAME.$CONTAINER_NUM" - DOKKU_PORT_FILE="$DOKKU_ROOT/$APP/PORT.$PROC_NAME.$CONTAINER_NUM" + while [[ $CONTAINER_INDEX -le $PROC_COUNT ]];do + DOKKU_CONTAINER_ID_FILE="$DOKKU_ROOT/$APP/CONTAINER.$PROC_NAME.$CONTAINER_INDEX" + DOKKU_IP_FILE="$DOKKU_ROOT/$APP/IP.$PROC_NAME.$CONTAINER_INDEX" + DOKKU_PORT_FILE="$DOKKU_ROOT/$APP/PORT.$PROC_NAME.$CONTAINER_INDEX" # start the app DOCKER_ARGS=$(: | pluginhook docker-args $APP deploy) @@ -121,8 +121,18 @@ case "$1" in # cleanup pre-migration files rm -f $DOKKU_ROOT/$APP/CONTAINER $DOKKU_ROOT/$APP/IP $DOKKU_ROOT/$APP/PORT - CONTAINER_NUM=$(( CONTAINER_NUM + 1 )) + + CONTAINER_INDEX=$(( CONTAINER_INDEX + 1 )) done + # cleanup when we scale down + if [[ "$PROC_COUNT" == 0 ]]; then + CONTAINER_IDX_OFFSET=0 + else + CONTAINER_IDX_OFFSET=$((PROC_COUNT + 1)) + fi + find $DOKKU_ROOT/$APP -name "CONTAINER.$PROC_NAME.*" | tail -n +$CONTAINER_IDX_OFFSET | xargs rm -f + find $DOKKU_ROOT/$APP -name "IP.$PROC_NAME.*" | tail -n +$CONTAINER_IDX_OFFSET | xargs rm -f + find $DOKKU_ROOT/$APP -name "PORT.$PROC_NAME.*" | tail -n +$CONTAINER_IDX_OFFSET | xargs rm -f done < "$DOKKU_SCALE_FILE" dokku_log_info1 "Running post-deploy" diff --git a/tests/unit/ps-buildstep.bats b/tests/unit/ps-buildstep.bats index 1eb0d5c70..c4379af38 100644 --- a/tests/unit/ps-buildstep.bats +++ b/tests/unit/ps-buildstep.bats @@ -3,25 +3,26 @@ load test_helper setup() { - deploy_app + create_app } teardown() { destroy_app } -# @test "(ps) buildstep" { -# # CI support: 'Ah. I just spoke with our Docker expert -- -# # looks like docker exec is built to work with docker-under-libcontainer, -# # but we're using docker-under-lxc. I don't have an estimated time for the fix, sorry -# skip "circleci does not support docker exec at the moment." -# run bash -c "dokku ps $TEST_APP | grep -q \"node web.js\"" -# echo "output: "$output -# echo "status: "$status -# assert_success -# } +@test "(ps) buildstep" { + # CI support: 'Ah. I just spoke with our Docker expert -- + # looks like docker exec is built to work with docker-under-libcontainer, + # but we're using docker-under-lxc. I don't have an estimated time for the fix, sorry + skip "circleci does not support docker exec at the moment." + run bash -c "dokku ps $TEST_APP | grep -q \"node web.js\"" + echo "output: "$output + echo "status: "$status + assert_success +} @test "(ps) buildstep" { + deploy_app run bash -c "dokku ps:stop $TEST_APP" echo "output: "$output echo "status: "$status @@ -66,3 +67,52 @@ teardown() { assert_success done } + +@test "(ps:scale) buildstep" { + run bash -c "dokku ps:scale $TEST_APP web=2" + echo "output: "$output + echo "status: "$status + assert_success + + deploy_app + CIDS="" + for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.web.*; do + CIDS+=$(< $CID_FILE) + CIDS+=" " + done + CIDS_PATTERN=$(echo $CIDS | sed -e "s: :|:g") + run bash -c "docker ps -q --no-trunc | egrep \"$CIDS_PATTERN\" | wc -l | grep 2" + echo "output: "$output + echo "status: "$status + assert_success + + run bash -c "dokku ps:scale $TEST_APP web=1" + echo "output: "$output + echo "status: "$status + assert_success + CIDS="" + for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.web.*; do + CIDS+=$(< $CID_FILE) + CIDS+=" " + done + CIDS_PATTERN=$(echo $CIDS | sed -e "s: :|:g") + run bash -c "docker ps -q --no-trunc | egrep \"$CIDS_PATTERN\" | wc -l | grep 1" + echo "output: "$output + echo "status: "$status + assert_success + + run bash -c "dokku ps:scale $TEST_APP web=0" + echo "output: "$output + echo "status: "$status + assert_success + CIDS="" + shopt -s nullglob + for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.web.*; do + CIDS+=$(< $CID_FILE) + CIDS+=" " + done + run bash -c "[[ -z \"$CIDS\" ]]" + echo "output: "$output + echo "status: "$status + assert_success +} diff --git a/tests/unit/ps-dockerfile.bats b/tests/unit/ps-dockerfile.bats index bfd187982..131546525 100644 --- a/tests/unit/ps-dockerfile.bats +++ b/tests/unit/ps-dockerfile.bats @@ -3,25 +3,26 @@ load test_helper setup() { - deploy_app dockerfile + create_app } teardown() { destroy_app } -# @test "(ps) dockerfile" { -# # CI support: 'Ah. I just spoke with our Docker expert -- -# # looks like docker exec is built to work with docker-under-libcontainer, -# # but we're using docker-under-lxc. I don't have an estimated time for the fix, sorry -# skip "circleci does not support docker exec at the moment." -# run bash -c "dokku ps $TEST_APP | grep -q \"node web.js\"" -# echo "output: "$output -# echo "status: "$status -# assert_success -# } +@test "(ps) dockerfile" { + # CI support: 'Ah. I just spoke with our Docker expert -- + # looks like docker exec is built to work with docker-under-libcontainer, + # but we're using docker-under-lxc. I don't have an estimated time for the fix, sorry + skip "circleci does not support docker exec at the moment." + run bash -c "dokku ps $TEST_APP | grep -q \"node web.js\"" + echo "output: "$output + echo "status: "$status + assert_success +} @test "(ps) dockerfile" { + deploy_app dockerfile run bash -c "dokku ps:stop $TEST_APP" echo "output: "$output echo "status: "$status @@ -66,3 +67,52 @@ teardown() { assert_success done } + +@test "(ps:scale) dockerfile" { + run bash -c "dokku ps:scale $TEST_APP web=2" + echo "output: "$output + echo "status: "$status + assert_success + + deploy_app dockerfile + CIDS="" + for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.web.*; do + CIDS+=$(< $CID_FILE) + CIDS+=" " + done + CIDS_PATTERN=$(echo $CIDS | sed -e "s: :|:g") + run bash -c "docker ps -q --no-trunc | egrep \"$CIDS_PATTERN\" | wc -l | grep 2" + echo "output: "$output + echo "status: "$status + assert_success + + run bash -c "dokku ps:scale $TEST_APP web=1" + echo "output: "$output + echo "status: "$status + assert_success + CIDS="" + for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.web.*; do + CIDS+=$(< $CID_FILE) + CIDS+=" " + done + CIDS_PATTERN=$(echo $CIDS | sed -e "s: :|:g") + run bash -c "docker ps -q --no-trunc | egrep \"$CIDS_PATTERN\" | wc -l | grep 1" + echo "output: "$output + echo "status: "$status + assert_success + + run bash -c "dokku ps:scale $TEST_APP web=0" + echo "output: "$output + echo "status: "$status + assert_success + CIDS="" + shopt -s nullglob + for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.web.*; do + CIDS+=$(< $CID_FILE) + CIDS+=" " + done + run bash -c "[[ -z \"$CIDS\" ]]" + echo "output: "$output + echo "status: "$status + assert_success +} From d88efd5cc48d3dd59b64a8198fde575b523de3c6 Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Mon, 20 Apr 2015 13:57:20 -0700 Subject: [PATCH 13/37] no need to find beyond a depth of 1. also bombs when the app cache dir is owned by the container user --- dokku | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dokku b/dokku index b1acacf6c..acfaa0256 100755 --- a/dokku +++ b/dokku @@ -130,9 +130,9 @@ case "$1" in else CONTAINER_IDX_OFFSET=$((PROC_COUNT + 1)) fi - find $DOKKU_ROOT/$APP -name "CONTAINER.$PROC_NAME.*" | tail -n +$CONTAINER_IDX_OFFSET | xargs rm -f - find $DOKKU_ROOT/$APP -name "IP.$PROC_NAME.*" | tail -n +$CONTAINER_IDX_OFFSET | xargs rm -f - find $DOKKU_ROOT/$APP -name "PORT.$PROC_NAME.*" | tail -n +$CONTAINER_IDX_OFFSET | xargs rm -f + find $DOKKU_ROOT/$APP -name "CONTAINER.$PROC_NAME.*" -maxdepth 1 | tail -n +$CONTAINER_IDX_OFFSET | xargs rm -f + find $DOKKU_ROOT/$APP -name "IP.$PROC_NAME.*" -maxdepth 1 | tail -n +$CONTAINER_IDX_OFFSET | xargs rm -f + find $DOKKU_ROOT/$APP -name "PORT.$PROC_NAME.*" -maxdepth 1 | tail -n +$CONTAINER_IDX_OFFSET | xargs rm -f done < "$DOKKU_SCALE_FILE" dokku_log_info1 "Running post-deploy" From d44788721fb7df17ff8caaa6ac3a67db8ba394e0 Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Mon, 20 Apr 2015 19:32:44 -0700 Subject: [PATCH 14/37] format multiple scale lines --- plugins/ps/functions | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/ps/functions b/plugins/ps/functions index d77af8d1d..21d44dc1c 100755 --- a/plugins/ps/functions +++ b/plugins/ps/functions @@ -31,7 +31,10 @@ generate_scale_file() { fi dokku_log_info1_quiet "New DOKKU_SCALE file generated" - dokku_log_info2_quiet "$(< $DOKKU_SCALE_FILE)" + while read line || [ -n "$line" ] + do + dokku_log_info2_quiet "$line" + done < "$DOKKU_SCALE_FILE" fi } From 9a704bc6566dec654677b0d1b102fb6829973621 Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Mon, 20 Apr 2015 20:01:13 -0700 Subject: [PATCH 15/37] use test in both cases --- plugins/common/functions | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/common/functions b/plugins/common/functions index 9c16a900f..3d137b420 100755 --- a/plugins/common/functions +++ b/plugins/common/functions @@ -169,8 +169,7 @@ copy_from_image() { is_deployed() { APP="$1" - verify_app_name $APP - if [[ -f $DOKKU_ROOT/$APP/CONTAINER ]] || ls $DOKKU_ROOT/$APP/CONTAINER.* &> /dev/null;then + if [[ -f "$DOKKU_ROOT/$APP/CONTAINER" ]] || [[ $(ls $DOKKU_ROOT/$APP/CONTAINER.* &> /dev/null; echo $?) -eq 0 ]];then return 0 else return 1 From ddf893bc8a42273c149c5f341f710579047e9649 Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Mon, 20 Apr 2015 20:01:40 -0700 Subject: [PATCH 16/37] fix rebuildall and restartall --- plugins/ps/commands | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/plugins/ps/commands b/plugins/ps/commands index 8855ba21f..67e5f7d92 100755 --- a/plugins/ps/commands +++ b/plugins/ps/commands @@ -80,8 +80,9 @@ case "$1" in ps:rebuildall) shopt -s nullglob for app in $DOKKU_ROOT/*; do - APP=$(basename "$(dirname $app)") - is_deployed && dokku ps:rebuild $APP + [[ ! -d $app ]] && continue + APP=$(basename $app) + is_deployed $APP && dokku ps:rebuild $APP done shopt -u nullglob ;; @@ -98,10 +99,12 @@ case "$1" in ps:restartall) shopt -s nullglob - for app in $DOKKU_ROOT/*/CONTAINER; do - APP=$(basename "$(dirname $app)"); + for app in $DOKKU_ROOT/*; do + [[ ! -d $app ]] && continue + APP=$(basename $app) dokku ps:restart $APP done + shopt -u nullglob ;; ps:scale) From 636e139e4a1d4b808639262d668162204e2b2f5b Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Mon, 20 Apr 2015 20:08:39 -0700 Subject: [PATCH 17/37] only balance web containers --- plugins/nginx-vhosts/commands | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/nginx-vhosts/commands b/plugins/nginx-vhosts/commands index 8ec5b41d7..de3aec189 100755 --- a/plugins/nginx-vhosts/commands +++ b/plugins/nginx-vhosts/commands @@ -36,7 +36,7 @@ case "$1" in if [[ -z "$DOKKU_APP_LISTEN_PORT" ]] && [[ -z "$DOKKU_APP_LISTEN_IP" ]]; then shopt -s nullglob - for DOKKU_APP_IP_FILE in $DOKKU_ROOT/$APP/IP.*;do + for DOKKU_APP_IP_FILE in $DOKKU_ROOT/$APP/IP.web.*;do DOKKU_APP_PORT_FILE=$(echo $DOKKU_APP_IP_FILE | sed -e "s:IP:PORT:g") DOKKU_APP_LISTENER_IP=$(< $DOKKU_APP_IP_FILE) DOKKU_APP_LISTENER_PORT=$(< $DOKKU_APP_PORT_FILE) From 715921c60eaa22dc481c738ac3ce264dab49202b Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Mon, 20 Apr 2015 20:10:53 -0700 Subject: [PATCH 18/37] comment out skipped test to save time --- tests/unit/ps-dockerfile.bats | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/unit/ps-dockerfile.bats b/tests/unit/ps-dockerfile.bats index 131546525..75b9ba1d7 100644 --- a/tests/unit/ps-dockerfile.bats +++ b/tests/unit/ps-dockerfile.bats @@ -10,16 +10,16 @@ teardown() { destroy_app } -@test "(ps) dockerfile" { - # CI support: 'Ah. I just spoke with our Docker expert -- - # looks like docker exec is built to work with docker-under-libcontainer, - # but we're using docker-under-lxc. I don't have an estimated time for the fix, sorry - skip "circleci does not support docker exec at the moment." - run bash -c "dokku ps $TEST_APP | grep -q \"node web.js\"" - echo "output: "$output - echo "status: "$status - assert_success -} +# @test "(ps) dockerfile" { +# # CI support: 'Ah. I just spoke with our Docker expert -- +# # looks like docker exec is built to work with docker-under-libcontainer, +# # but we're using docker-under-lxc. I don't have an estimated time for the fix, sorry +# skip "circleci does not support docker exec at the moment." +# run bash -c "dokku ps $TEST_APP | grep -q \"node web.js\"" +# echo "output: "$output +# echo "status: "$status +# assert_success +# } @test "(ps) dockerfile" { deploy_app dockerfile From 7348d7790c12212fe204e20c7d11a7ca96390407 Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Mon, 20 Apr 2015 20:11:30 -0700 Subject: [PATCH 19/37] test scaling different proc types --- tests/apps/nodejs-express/Procfile | 1 + tests/unit/ps-buildstep.bats | 173 +++++++++++++++-------------- 2 files changed, 91 insertions(+), 83 deletions(-) diff --git a/tests/apps/nodejs-express/Procfile b/tests/apps/nodejs-express/Procfile index ae7366d41..463b397a8 100644 --- a/tests/apps/nodejs-express/Procfile +++ b/tests/apps/nodejs-express/Procfile @@ -1 +1,2 @@ web: node web.js +worker: node web.js diff --git a/tests/unit/ps-buildstep.bats b/tests/unit/ps-buildstep.bats index c4379af38..f702cf0ca 100644 --- a/tests/unit/ps-buildstep.bats +++ b/tests/unit/ps-buildstep.bats @@ -10,109 +10,116 @@ teardown() { destroy_app } -@test "(ps) buildstep" { - # CI support: 'Ah. I just spoke with our Docker expert -- - # looks like docker exec is built to work with docker-under-libcontainer, - # but we're using docker-under-lxc. I don't have an estimated time for the fix, sorry - skip "circleci does not support docker exec at the moment." - run bash -c "dokku ps $TEST_APP | grep -q \"node web.js\"" - echo "output: "$output - echo "status: "$status - assert_success -} +# @test "(ps) buildstep" { +# # CI support: 'Ah. I just spoke with our Docker expert -- +# # looks like docker exec is built to work with docker-under-libcontainer, +# # but we're using docker-under-lxc. I don't have an estimated time for the fix, sorry +# skip "circleci does not support docker exec at the moment." +# run bash -c "dokku ps $TEST_APP | grep -q \"node web.js\"" +# echo "output: "$output +# echo "status: "$status +# assert_success +# } -@test "(ps) buildstep" { - deploy_app - run bash -c "dokku ps:stop $TEST_APP" - echo "output: "$output - echo "status: "$status - assert_success - for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.*; do - run bash -c "docker ps -q --no-trunc | grep -q $(< $CID_FILE)" - echo "output: "$output - echo "status: "$status - assert_failure - done +# @test "(ps) buildstep" { +# deploy_app +# run bash -c "dokku ps:stop $TEST_APP" +# echo "output: "$output +# echo "status: "$status +# assert_success +# for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.*; do +# run bash -c "docker ps -q --no-trunc | grep -q $(< $CID_FILE)" +# echo "output: "$output +# echo "status: "$status +# assert_failure +# done - run bash -c "dokku ps:start $TEST_APP" - echo "output: "$output - echo "status: "$status - assert_success - for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.*; do - run bash -c "docker ps -q --no-trunc | grep -q $(< $CID_FILE)" - echo "output: "$output - echo "status: "$status - assert_success - done +# run bash -c "dokku ps:start $TEST_APP" +# echo "output: "$output +# echo "status: "$status +# assert_success +# for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.*; do +# run bash -c "docker ps -q --no-trunc | grep -q $(< $CID_FILE)" +# echo "output: "$output +# echo "status: "$status +# assert_success +# done - run bash -c "dokku ps:restart $TEST_APP" - echo "output: "$output - echo "status: "$status - assert_success - for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.*; do - run bash -c "docker ps -q --no-trunc | grep -q $(< $CID_FILE)" - echo "output: "$output - echo "status: "$status - assert_success - done +# run bash -c "dokku ps:restart $TEST_APP" +# echo "output: "$output +# echo "status: "$status +# assert_success +# for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.*; do +# run bash -c "docker ps -q --no-trunc | grep -q $(< $CID_FILE)" +# echo "output: "$output +# echo "status: "$status +# assert_success +# done - run bash -c "dokku ps:rebuild $TEST_APP" - echo "output: "$output - echo "status: "$status - assert_success - for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.*; do - run bash -c "docker ps -q --no-trunc | grep -q $(< $CID_FILE)" - echo "output: "$output - echo "status: "$status - assert_success - done -} +# run bash -c "dokku ps:rebuild $TEST_APP" +# echo "output: "$output +# echo "status: "$status +# assert_success +# for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.*; do +# run bash -c "docker ps -q --no-trunc | grep -q $(< $CID_FILE)" +# echo "output: "$output +# echo "status: "$status +# assert_success +# done +# } @test "(ps:scale) buildstep" { - run bash -c "dokku ps:scale $TEST_APP web=2" + run bash -c "dokku ps:scale $TEST_APP web=2 worker=2" echo "output: "$output echo "status: "$status assert_success deploy_app - CIDS="" - for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.web.*; do - CIDS+=$(< $CID_FILE) - CIDS+=" " + for PROC_TYPE in web worker; do + CIDS="" + for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.$PROC_TYPE.*; do + CIDS+=$(< $CID_FILE) + CIDS+=" " + done + CIDS_PATTERN=$(echo $CIDS | sed -e "s: :|:g") + run bash -c "docker ps -q --no-trunc | egrep \"$CIDS_PATTERN\" | wc -l | grep 2" + echo "output: "$output + echo "status: "$status + assert_success done - CIDS_PATTERN=$(echo $CIDS | sed -e "s: :|:g") - run bash -c "docker ps -q --no-trunc | egrep \"$CIDS_PATTERN\" | wc -l | grep 2" - echo "output: "$output - echo "status: "$status - assert_success - run bash -c "dokku ps:scale $TEST_APP web=1" + run bash -c "dokku ps:scale $TEST_APP web=1 worker=1" echo "output: "$output echo "status: "$status assert_success - CIDS="" - for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.web.*; do - CIDS+=$(< $CID_FILE) - CIDS+=" " + for PROC_TYPE in web worker; do + CIDS="" + for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.$PROC_TYPE.*; do + CIDS+=$(< $CID_FILE) + CIDS+=" " + done + CIDS_PATTERN=$(echo $CIDS | sed -e "s: :|:g") + run bash -c "docker ps -q --no-trunc | egrep \"$CIDS_PATTERN\" | wc -l | grep 1" + echo "output: "$output + echo "status: "$status + assert_success done - CIDS_PATTERN=$(echo $CIDS | sed -e "s: :|:g") - run bash -c "docker ps -q --no-trunc | egrep \"$CIDS_PATTERN\" | wc -l | grep 1" - echo "output: "$output - echo "status: "$status - assert_success - run bash -c "dokku ps:scale $TEST_APP web=0" + run bash -c "dokku ps:scale $TEST_APP web=0 worker=0" echo "output: "$output echo "status: "$status assert_success - CIDS="" - shopt -s nullglob - for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.web.*; do - CIDS+=$(< $CID_FILE) - CIDS+=" " + for PROC_TYPE in web worker; do + CIDS="" + shopt -s nullglob + for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.$PROC_TYPE.*; do + CIDS+=$(< $CID_FILE) + CIDS+=" "1 + done + shopt -u nullglob + run bash -c "[[ -z \"$CIDS\" ]]" + echo "output: "$output + echo "status: "$status + assert_success done - run bash -c "[[ -z \"$CIDS\" ]]" - echo "output: "$output - echo "status: "$status - assert_success } From 4ae7af091a501fe5a23da36c07526e109188d45a Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Mon, 20 Apr 2015 20:11:45 -0700 Subject: [PATCH 20/37] don't clobber oids when multiple proc types exist --- dokku | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dokku b/dokku index acfaa0256..514c6520f 100755 --- a/dokku +++ b/dokku @@ -68,13 +68,13 @@ case "$1" in is_image_buildstep_based "$IMAGE" && DOKKU_BUILDSTEP=true DOKKU_SCALE_FILE="$DOKKU_ROOT/$APP/DOKKU_SCALE" + oldids=$(get_container_ids $APP) while read line || [ -n "$line" ] do PROC_NAME=${line%%=*} PROC_COUNT=${line#*=} CONTAINER_INDEX=1 - oldids=$(get_container_ids $APP) while [[ $CONTAINER_INDEX -le $PROC_COUNT ]];do DOKKU_CONTAINER_ID_FILE="$DOKKU_ROOT/$APP/CONTAINER.$PROC_NAME.$CONTAINER_INDEX" From 979c1155c200f9a1a569796b5961cbbaa34ffbc5 Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Mon, 20 Apr 2015 20:37:20 -0700 Subject: [PATCH 21/37] add process with no listener --- tests/apps/nodejs-express/Procfile | 3 ++- tests/apps/nodejs-express/web.js | 2 +- tests/apps/nodejs-express/worker.js | 6 ++++++ 3 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 tests/apps/nodejs-express/worker.js diff --git a/tests/apps/nodejs-express/Procfile b/tests/apps/nodejs-express/Procfile index 463b397a8..91da256cc 100644 --- a/tests/apps/nodejs-express/Procfile +++ b/tests/apps/nodejs-express/Procfile @@ -1,2 +1,3 @@ +cron: node worker.js web: node web.js -worker: node web.js +worker: node worker.js diff --git a/tests/apps/nodejs-express/web.js b/tests/apps/nodejs-express/web.js index 66aa53614..6b8f4d819 100644 --- a/tests/apps/nodejs-express/web.js +++ b/tests/apps/nodejs-express/web.js @@ -9,4 +9,4 @@ app.get('/', function(request, response) { var port = process.env.PORT || 5000; app.listen(port, function() { console.log("Listening on " + port); -}); \ No newline at end of file +}); diff --git a/tests/apps/nodejs-express/worker.js b/tests/apps/nodejs-express/worker.js new file mode 100644 index 000000000..12133530d --- /dev/null +++ b/tests/apps/nodejs-express/worker.js @@ -0,0 +1,6 @@ +function worker() { + console.log('sleeping for 60 seconds'); + setTimeout(worker, 60 * 1000); +} + +worker(); From 3361a20a306d829c8c9d0932092d5d60342289a2 Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Mon, 20 Apr 2015 20:56:07 -0700 Subject: [PATCH 22/37] only check containers running proc named web for now --- dokku | 34 ++++++++++++++++++---------------- plugins/checks/check-deploy | 4 ++-- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/dokku b/dokku index 514c6520f..3c3fe9db2 100755 --- a/dokku +++ b/dokku @@ -72,32 +72,34 @@ case "$1" in while read line || [ -n "$line" ] do - PROC_NAME=${line%%=*} + PROC_TYPE=${line%%=*} PROC_COUNT=${line#*=} CONTAINER_INDEX=1 while [[ $CONTAINER_INDEX -le $PROC_COUNT ]];do - DOKKU_CONTAINER_ID_FILE="$DOKKU_ROOT/$APP/CONTAINER.$PROC_NAME.$CONTAINER_INDEX" - DOKKU_IP_FILE="$DOKKU_ROOT/$APP/IP.$PROC_NAME.$CONTAINER_INDEX" - DOKKU_PORT_FILE="$DOKKU_ROOT/$APP/PORT.$PROC_NAME.$CONTAINER_INDEX" + id=""; port=""; ipaddr="" + DOKKU_CONTAINER_ID_FILE="$DOKKU_ROOT/$APP/CONTAINER.$PROC_TYPE.$CONTAINER_INDEX" + DOKKU_IP_FILE="$DOKKU_ROOT/$APP/IP.$PROC_TYPE.$CONTAINER_INDEX" + DOKKU_PORT_FILE="$DOKKU_ROOT/$APP/PORT.$PROC_TYPE.$CONTAINER_INDEX" # start the app DOCKER_ARGS=$(: | pluginhook docker-args $APP deploy) DOCKER_ARGS+=$(: | pluginhook docker-args-deploy $APP) BIND_EXTERNAL=$(pluginhook bind-external-ip $APP) - [[ -n "$DOKKU_BUILDSTEP" ]] && START_CMD="/start $PROC_NAME" + [[ -n "$DOKKU_BUILDSTEP" ]] && START_CMD="/start $PROC_TYPE" [[ -z "$DOKKU_BUILDSTEP" ]] && DOKKU_DOCKERFILE_PORT=$(dokku config:get $APP DOKKU_DOCKERFILE_PORT || true) - - if [[ "$BIND_EXTERNAL" = "false" ]];then + if [[ "$BIND_EXTERNAL" = "false" ]] && [[ "$PROC_TYPE" == "web" ]];then port=${DOKKU_DOCKERFILE_PORT:=5000} id=$(docker run -d -e PORT=$port $DOCKER_ARGS $IMAGE $START_CMD) ipaddr=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' $id) - else + elif [[ "$BIND_EXTERNAL" = "true" ]] && [[ "$PROC_TYPE" == "web" ]];then id=$(docker run -d -p 5000 -e PORT=5000 $DOCKER_ARGS $IMAGE $START_CMD) port=$(docker port $id 5000 | sed 's/[0-9.]*://') ipaddr=127.0.0.1 + elif [[ "$PROC_TYPE" != "web" ]];then + id=$(docker run -d $DOCKER_ARGS $IMAGE $START_CMD) fi # if we can't post-deploy successfully, kill new container @@ -110,14 +112,14 @@ case "$1" in # run checks first, then post-deploy hooks, which switches Nginx traffic trap kill_new INT TERM EXIT dokku_log_info1 "Running pre-flight checks" - pluginhook check-deploy $APP $port $ipaddr $id + pluginhook check-deploy $APP $id $PROC_TYPE $port $ipaddr trap - INT TERM EXIT # now using the new container - echo $id > "$DOKKU_CONTAINER_ID_FILE" - echo $ipaddr > "$DOKKU_IP_FILE" - echo $port > "$DOKKU_PORT_FILE" - echo "http://$(< "$DOKKU_ROOT/HOSTNAME"):$port" > "$DOKKU_ROOT/$APP/URL" + [[ -n "$id" ]] && echo $id > "$DOKKU_CONTAINER_ID_FILE" + [[ -n "$ipaddr" ]] && echo $ipaddr > "$DOKKU_IP_FILE" + [[ -n "$port" ]] && echo $port > "$DOKKU_PORT_FILE" + [[ -n "$port" ]] && echo "http://$(< "$DOKKU_ROOT/HOSTNAME"):$port" > "$DOKKU_ROOT/$APP/URL" # cleanup pre-migration files rm -f $DOKKU_ROOT/$APP/CONTAINER $DOKKU_ROOT/$APP/IP $DOKKU_ROOT/$APP/PORT @@ -130,9 +132,9 @@ case "$1" in else CONTAINER_IDX_OFFSET=$((PROC_COUNT + 1)) fi - find $DOKKU_ROOT/$APP -name "CONTAINER.$PROC_NAME.*" -maxdepth 1 | tail -n +$CONTAINER_IDX_OFFSET | xargs rm -f - find $DOKKU_ROOT/$APP -name "IP.$PROC_NAME.*" -maxdepth 1 | tail -n +$CONTAINER_IDX_OFFSET | xargs rm -f - find $DOKKU_ROOT/$APP -name "PORT.$PROC_NAME.*" -maxdepth 1 | tail -n +$CONTAINER_IDX_OFFSET | xargs rm -f + find $DOKKU_ROOT/$APP -name "CONTAINER.$PROC_TYPE.*" -maxdepth 1 | tail -n +$CONTAINER_IDX_OFFSET | xargs rm -f + find $DOKKU_ROOT/$APP -name "IP.$PROC_TYPE.*" -maxdepth 1 | tail -n +$CONTAINER_IDX_OFFSET | xargs rm -f + find $DOKKU_ROOT/$APP -name "PORT.$PROC_TYPE.*" -maxdepth 1 | tail -n +$CONTAINER_IDX_OFFSET | xargs rm -f done < "$DOKKU_SCALE_FILE" dokku_log_info1 "Running post-deploy" diff --git a/plugins/checks/check-deploy b/plugins/checks/check-deploy index 632f5d4e4..eda9d54f9 100755 --- a/plugins/checks/check-deploy +++ b/plugins/checks/check-deploy @@ -37,7 +37,7 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x source "$(dirname $0)/../common/functions" -APP="$1"; DOKKU_APP_LISTEN_PORT="$2"; DOKKU_APP_LISTEN_IP="$3"; DOKKU_APP_CONTAINER_ID="$4" +APP="$1"; DOKKU_APP_CONTAINER_ID="$2"; DOKKU_APP_CONTAINER_TYPE="$3"; DOKKU_APP_LISTEN_PORT="$4"; DOKKU_APP_LISTEN_IP="$5" if [[ -z "$DOKKU_APP_LISTEN_PORT" ]] && [[ -f "$DOKKU_ROOT/$APP/PORT" ]]; then DOKKU_APP_LISTEN_PORT=$(< "$DOKKU_ROOT/$APP/PORT") fi @@ -78,7 +78,7 @@ cleanup() { } trap cleanup EXIT -if [[ ! -s "${TMPDIR}/CHECKS" ]] ; then +if [[ ! -s "${TMPDIR}/CHECKS" ]] || [[ "$DOKKU_APP_CONTAINER_TYPE" != "web" ]]; then dokku_log_verbose "For more efficient zero downtime deployments, create a file CHECKS." dokku_log_verbose "See http://progrium.viewdocs.io/dokku/checks-examples.md for examples" dokku_log_verbose "CHECKS file not found in container: Running simple container check..." From 33258663f42e9c8aebc2a0b7b83a7b53a5b1f8a7 Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Mon, 20 Apr 2015 20:57:12 -0700 Subject: [PATCH 23/37] uncomment my accidental comment out --- tests/unit/ps-buildstep.bats | 86 ++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/tests/unit/ps-buildstep.bats b/tests/unit/ps-buildstep.bats index f702cf0ca..e10534239 100644 --- a/tests/unit/ps-buildstep.bats +++ b/tests/unit/ps-buildstep.bats @@ -21,52 +21,52 @@ teardown() { # assert_success # } -# @test "(ps) buildstep" { -# deploy_app -# run bash -c "dokku ps:stop $TEST_APP" -# echo "output: "$output -# echo "status: "$status -# assert_success -# for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.*; do -# run bash -c "docker ps -q --no-trunc | grep -q $(< $CID_FILE)" -# echo "output: "$output -# echo "status: "$status -# assert_failure -# done +@test "(ps) buildstep" { + deploy_app + run bash -c "dokku ps:stop $TEST_APP" + echo "output: "$output + echo "status: "$status + assert_success + for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.*; do + run bash -c "docker ps -q --no-trunc | grep -q $(< $CID_FILE)" + echo "output: "$output + echo "status: "$status + assert_failure + done -# run bash -c "dokku ps:start $TEST_APP" -# echo "output: "$output -# echo "status: "$status -# assert_success -# for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.*; do -# run bash -c "docker ps -q --no-trunc | grep -q $(< $CID_FILE)" -# echo "output: "$output -# echo "status: "$status -# assert_success -# done + run bash -c "dokku ps:start $TEST_APP" + echo "output: "$output + echo "status: "$status + assert_success + for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.*; do + run bash -c "docker ps -q --no-trunc | grep -q $(< $CID_FILE)" + echo "output: "$output + echo "status: "$status + assert_success + done -# run bash -c "dokku ps:restart $TEST_APP" -# echo "output: "$output -# echo "status: "$status -# assert_success -# for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.*; do -# run bash -c "docker ps -q --no-trunc | grep -q $(< $CID_FILE)" -# echo "output: "$output -# echo "status: "$status -# assert_success -# done + run bash -c "dokku ps:restart $TEST_APP" + echo "output: "$output + echo "status: "$status + assert_success + for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.*; do + run bash -c "docker ps -q --no-trunc | grep -q $(< $CID_FILE)" + echo "output: "$output + echo "status: "$status + assert_success + done -# run bash -c "dokku ps:rebuild $TEST_APP" -# echo "output: "$output -# echo "status: "$status -# assert_success -# for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.*; do -# run bash -c "docker ps -q --no-trunc | grep -q $(< $CID_FILE)" -# echo "output: "$output -# echo "status: "$status -# assert_success -# done -# } + run bash -c "dokku ps:rebuild $TEST_APP" + echo "output: "$output + echo "status: "$status + assert_success + for CID_FILE in $DOKKU_ROOT/$TEST_APP/CONTAINER.*; do + run bash -c "docker ps -q --no-trunc | grep -q $(< $CID_FILE)" + echo "output: "$output + echo "status: "$status + assert_success + done +} @test "(ps:scale) buildstep" { run bash -c "dokku ps:scale $TEST_APP web=2 worker=2" From 807e1b97b4302fa4d949ac6dea3a0cb2dd1c091a Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Mon, 20 Apr 2015 21:15:56 -0700 Subject: [PATCH 24/37] [ci skip] scaling docs --- docs/process-management.md | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/docs/process-management.md b/docs/process-management.md index 619ec8f60..7c24bf402 100644 --- a/docs/process-management.md +++ b/docs/process-management.md @@ -4,10 +4,38 @@ Dokku supports rudimentary process (really container) management via the `ps` pl ``` ps List processes running in app container(s) +ps:rebuildall Rebuild all apps +ps:rebuild Rebuild an app +ps:restartall Restart all deployed app containers +ps:restart Restart app container(s) +ps:scale = [=] Set how many processes of a given process to run ps:start Start app container(s) ps:stop Stop app container(s) -ps:restart Restart app container(s) -ps:restartall Restart all deployed app containers ``` *NOTE*: As of v0.3.14, `dokku deploy:all` in now deprecated by `ps:restartall` and will be removed in a future version. + + +## Scaling + +Dokku allows you to run multiple process types at different container counts. For example, if you had an app that contained 1 web app listener and 1 background job processor, dokku will, by default, spin up 1 container for each process type defined in the Procfile. If you wanted 2 job processors running simultaneously, you can modify this behavior in a few ways. + +## Include a DOKKU_SCALE file in your repo + +Dokku expects this file to contain one line for every process defined in your Procfile. Example: +``` +web=1 +worker=2 +``` + + +## Use the ps:scale command. Example: +``` +dokku ps:scale app_name web=1 worker=2 +``` +*NOTE*: Dokku will always use the DOKKU_SCALE file that ships with the repo to override any local settings. + + +## The web proctype + +Like Heroku, we handle the `web` proctype differently from others. The `web` proctype is the only proctype that will invoke custom checks as defined by a CHECKS file. It is also the only proctype that will be launched in a container that is either proxied via nginx or bound to an external port. From 2cb957d1dd503d0fee2b3b146b44b2c5b7dbeeac Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Tue, 21 Apr 2015 20:17:14 -0700 Subject: [PATCH 25/37] move release_and_deploy to plugin functions. only attempt Procfile copy if we're buildstep based --- plugins/ps/commands | 21 --------------------- plugins/ps/functions | 39 +++++++++++++++++++++++++++++++++------ 2 files changed, 33 insertions(+), 27 deletions(-) diff --git a/plugins/ps/commands b/plugins/ps/commands index 67e5f7d92..92e28d1cc 100755 --- a/plugins/ps/commands +++ b/plugins/ps/commands @@ -3,27 +3,6 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x source "$(dirname $0)/../common/functions" source "$(dirname $0)/functions" -release_and_deploy() { - source "$(dirname $0)/../common/functions" - local APP="$1"; local IMAGE="dokku/$APP" - - if verify_app_image "$APP"; then - if is_image_buildstep_based "$IMAGE"; then - IMAGE_SOURCE_TYPE="buildstep" - else - IMAGE_SOURCE_TYPE="dockerfile" - fi - - dokku_log_info1 "Releasing $APP ..." - dokku release "$APP" "$IMAGE_SOURCE_TYPE" - dokku_log_info1 "Deploying $APP ..." - dokku deploy "$APP" - dokku_log_info2 "Application deployed:" - dokku urls $APP | sed "s/^/ /" - echo - fi -} - case "$1" in ps) [[ -z $2 ]] && echo "Please specify an app to run the command on" && exit 1 diff --git a/plugins/ps/functions b/plugins/ps/functions index 21d44dc1c..49238e4fd 100755 --- a/plugins/ps/functions +++ b/plugins/ps/functions @@ -2,6 +2,27 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x source "$(dirname $0)/../common/functions" +release_and_deploy() { + source "$(dirname $0)/../common/functions" + local APP="$1"; local IMAGE="dokku/$APP" + + if verify_app_image "$APP"; then + if is_image_buildstep_based "$IMAGE"; then + IMAGE_SOURCE_TYPE="buildstep" + else + IMAGE_SOURCE_TYPE="dockerfile" + fi + + dokku_log_info1 "Releasing $APP ..." + dokku release "$APP" "$IMAGE_SOURCE_TYPE" + dokku_log_info1 "Deploying $APP ..." + dokku deploy "$APP" + dokku_log_info2 "Application deployed:" + dokku urls $APP | sed "s/^/ /" + echo + fi +} + generate_scale_file() { local APP="$1"; local DOKKU_SCALE_FILE="$DOKKU_ROOT/$APP/DOKKU_SCALE" copy_from_image "$APP" "/app/DOKKU_SCALE" "$DOKKU_ROOT/$APP" 2>/dev/null || dokku_log_info1_quiet "DOKKU_SCALE not found in app image" @@ -9,13 +30,18 @@ generate_scale_file() { local TMP_WORK_DIR=$(mktemp --tmpdir=/tmp -d DOKKU_SCALE.XXXXX) trap 'rm -rf $TMP_WORK_DIR' EXIT - copy_from_image "$APP" /app/Procfile $TMP_WORK_DIR 2>/dev/null || true - copy_from_image "$APP" /app/.release $TMP_WORK_DIR 2>/dev/null || true - if [[ -f $TMP_WORK_DIR/Procfile ]];then - local PROCFILE="$TMP_WORK_DIR/Procfile" - elif [[ -f $TMP_WORK_DIR/.release ]];then - local PROCFILE="$TMP_WORK_DIR/.release" + if is_image_buildstep_based "$APP"; then + copy_from_image "$APP" /app/Procfile $TMP_WORK_DIR 2>/dev/null || true + copy_from_image "$APP" /app/.release $TMP_WORK_DIR 2>/dev/null || true + + if [[ -f $TMP_WORK_DIR/Procfile ]];then + local PROCFILE="$TMP_WORK_DIR/Procfile" + elif [[ -f $TMP_WORK_DIR/.release ]];then + local PROCFILE="$TMP_WORK_DIR/.release" + else + echo "web=1" >> $DOKKU_SCALE_FILE + fi else echo "web=1" >> $DOKKU_SCALE_FILE fi @@ -54,3 +80,4 @@ set_scale() { fi done } + From e74c6460fbf6898f678fafdedc630569bbc73506 Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Tue, 21 Apr 2015 20:25:05 -0700 Subject: [PATCH 26/37] make semantic sense of _image functions --- plugins/common/functions | 8 ++++---- plugins/ps/functions | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/plugins/common/functions b/plugins/common/functions index 3d137b420..9bee74b3b 100755 --- a/plugins/common/functions +++ b/plugins/common/functions @@ -110,8 +110,8 @@ verify_app_name() { return 0 } -verify_app_image() { - local APP="$1"; local IMAGE="dokku/$APP" +verify_image() { + local IMAGE="$1" DOKKU_APP_IMAGES=$(docker images -q $IMAGE) if [[ -n "$DOKKU_APP_IMAGES" ]]; then return 0 @@ -156,9 +156,9 @@ parse_args() { } copy_from_image() { - local APP="$1"; local IMAGE="dokku/$APP"; local SRC_FILE="$2"; local DST_DIR="$3"; verify_app_name $APP + local IMAGE="$1"; local SRC_FILE="$2"; local DST_DIR="$3"; verify_app_name $APP - if verify_app_image "$APP"; then + if verify_image "$IMAGE"; then CID=$(docker run -d $IMAGE bash) docker cp "$CID:$SRC_FILE" "$DST_DIR" docker rm -f "$CID" &> /dev/null diff --git a/plugins/ps/functions b/plugins/ps/functions index 49238e4fd..cf0eff73a 100755 --- a/plugins/ps/functions +++ b/plugins/ps/functions @@ -6,7 +6,7 @@ release_and_deploy() { source "$(dirname $0)/../common/functions" local APP="$1"; local IMAGE="dokku/$APP" - if verify_app_image "$APP"; then + if verify_image "$IMAGE"; then if is_image_buildstep_based "$IMAGE"; then IMAGE_SOURCE_TYPE="buildstep" else @@ -24,16 +24,16 @@ release_and_deploy() { } generate_scale_file() { - local APP="$1"; local DOKKU_SCALE_FILE="$DOKKU_ROOT/$APP/DOKKU_SCALE" - copy_from_image "$APP" "/app/DOKKU_SCALE" "$DOKKU_ROOT/$APP" 2>/dev/null || dokku_log_info1_quiet "DOKKU_SCALE not found in app image" + local APP="$1"; local IMAGE="dokku/$APP"; local DOKKU_SCALE_FILE="$DOKKU_ROOT/$APP/DOKKU_SCALE" + copy_from_image "$IMAGE" "/app/DOKKU_SCALE" "$DOKKU_ROOT/$APP" 2>/dev/null || dokku_log_info1_quiet "DOKKU_SCALE not found in app image" if [[ ! -f $DOKKU_SCALE_FILE ]]; then local TMP_WORK_DIR=$(mktemp --tmpdir=/tmp -d DOKKU_SCALE.XXXXX) trap 'rm -rf $TMP_WORK_DIR' EXIT - if is_image_buildstep_based "$APP"; then - copy_from_image "$APP" /app/Procfile $TMP_WORK_DIR 2>/dev/null || true - copy_from_image "$APP" /app/.release $TMP_WORK_DIR 2>/dev/null || true + if is_image_buildstep_based "$IMAGE"; then + copy_from_image "$IMAGE" /app/Procfile $TMP_WORK_DIR 2>/dev/null || true + copy_from_image "$IMAGE" /app/.release $TMP_WORK_DIR 2>/dev/null || true if [[ -f $TMP_WORK_DIR/Procfile ]];then local PROCFILE="$TMP_WORK_DIR/Procfile" From 9d504fe93a3f486c1e55df1ba8edbcfcc7b38118 Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Tue, 21 Apr 2015 21:36:03 -0700 Subject: [PATCH 27/37] make sure we cleanup tmp. logging when we hit edge cases --- plugins/ps/functions | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/ps/functions b/plugins/ps/functions index cf0eff73a..e17233023 100755 --- a/plugins/ps/functions +++ b/plugins/ps/functions @@ -28,7 +28,7 @@ generate_scale_file() { copy_from_image "$IMAGE" "/app/DOKKU_SCALE" "$DOKKU_ROOT/$APP" 2>/dev/null || dokku_log_info1_quiet "DOKKU_SCALE not found in app image" if [[ ! -f $DOKKU_SCALE_FILE ]]; then local TMP_WORK_DIR=$(mktemp --tmpdir=/tmp -d DOKKU_SCALE.XXXXX) - trap 'rm -rf $TMP_WORK_DIR' EXIT + trap 'rm -rf $TMP_WORK_DIR' INT TERM EXIT RETURN if is_image_buildstep_based "$IMAGE"; then @@ -40,9 +40,11 @@ generate_scale_file() { elif [[ -f $TMP_WORK_DIR/.release ]];then local PROCFILE="$TMP_WORK_DIR/.release" else + dokku_log_info1 "No Procfile or .release file found. Defaulting to a single web process" echo "web=1" >> $DOKKU_SCALE_FILE fi else + dokku_log_info1 "Dockerfile build detected. Defaulting to a single web process" echo "web=1" >> $DOKKU_SCALE_FILE fi From eb0935a69111942b73478a1ca785699a491ebf52 Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Tue, 21 Apr 2015 21:50:50 -0700 Subject: [PATCH 28/37] make dokku ls pretty --- plugins/00_dokku-standard/commands | 14 ++++++++------ plugins/common/functions | 24 ++++++++++++------------ 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/plugins/00_dokku-standard/commands b/plugins/00_dokku-standard/commands index 9ad493436..b99d55f98 100755 --- a/plugins/00_dokku-standard/commands +++ b/plugins/00_dokku-standard/commands @@ -109,18 +109,20 @@ case "$1" in ;; ls) - apps=$(ls -d $DOKKU_ROOT/*/ 2>/dev/null) || (echo "You haven't depoyed any applications yet" && exit 1) + dokku_apps=$(ls -d $DOKKU_ROOT/*/ 2>/dev/null) || (echo "You haven't depoyed any applications yet" && exit 1) - dokku_col_log_info2_quiet "App Name" "Container id" + dokku_3col_log_info2_quiet "App Name" "Container Type" "Container Id" - for app in $apps; do - DOKKU_APP_CIDS=$(get_container_ids "$(basename $app)") + for dokku_app in $dokku_apps; do + APP=$(basename $dokku_app) + DOKKU_APP_CIDS=$(get_container_ids $APP) if [[ -n $DOKKU_APP_CIDS ]]; then for DOKKU_APP_CID in $DOKKU_APP_CIDS; do - dokku_col_log_msg "$(basename $app)" "$DOKKU_APP_CID" + DOKKU_APP_CONTAINER_TYPE=$(grep -l $DOKKU_APP_CID $DOKKU_ROOT/$APP/CONTAINER.* | awk -F. '{ print $2 }') + dokku_3col_log_msg "$APP" "$DOKKU_APP_CONTAINER_TYPE" "$DOKKU_APP_CID" done else - dokku_col_log_msg "$(basename $app)" + dokku_3col_log_msg "$APP" "NOT_DEPLOYED" "NOT_DEPLOYED" fi done ;; diff --git a/plugins/common/functions b/plugins/common/functions index 9bee74b3b..10df17574 100755 --- a/plugins/common/functions +++ b/plugins/common/functions @@ -33,37 +33,37 @@ dokku_log_info2_quiet() { fi } -dokku_col_log_info1() { - printf "%-40s %-40s\n" "-----> $@" +dokku_3col_log_info1() { + printf "%-30s %-30s %-30s\n" "-----> $@" } -dokku_col_log_info1_quiet() { +dokku_3col_log_info1_quiet() { if [[ -z "$DOKKU_QUIET_OUTPUT" ]];then - printf "%-40s %-40s\n" "-----> $@" + printf "%-30s %-30s %-30s\n" "-----> $@" else return 0 fi } -dokku_col_log_info2() { - printf "%-40s %-40s\n" "=====> $@" +dokku_3col_log_info2() { + printf "%-30s %-30s %-30s\n" "=====> $@" } -dokku_col_log_info2_quiet() { +dokku_3col_log_info2_quiet() { if [[ -z "$DOKKU_QUIET_OUTPUT" ]];then - printf "%-40s %-40s\n" "=====> $@" + printf "%-30s %-30s %-30s\n" "=====> $@" else return 0 fi } -dokku_col_log_msg() { - printf "%-40s %-40s\n" "$@" +dokku_3col_log_msg() { + printf "%-30s %-30s %-30s\n" "$@" } -dokku_col_log_msg_quiet() { +dokku_3col_log_msg_quiet() { if [[ -z "$DOKKU_QUIET_OUTPUT" ]];then - printf "%-40s %-40s\n" "$@" + printf "%-30s %-30s %-30s\n" "$@" else return 0 fi From c2fa8d14c998d6e02427e6064f7e9530e46e1fd7 Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Tue, 21 Apr 2015 22:13:45 -0700 Subject: [PATCH 29/37] scale web to 1 by default and ignore all others --- docs/process-management.md | 2 +- plugins/ps/functions | 34 +++------------------------------- 2 files changed, 4 insertions(+), 32 deletions(-) diff --git a/docs/process-management.md b/docs/process-management.md index 7c24bf402..17e541b69 100644 --- a/docs/process-management.md +++ b/docs/process-management.md @@ -18,7 +18,7 @@ ps:stop Stop app container(s) ## Scaling -Dokku allows you to run multiple process types at different container counts. For example, if you had an app that contained 1 web app listener and 1 background job processor, dokku will, by default, spin up 1 container for each process type defined in the Procfile. If you wanted 2 job processors running simultaneously, you can modify this behavior in a few ways. +Dokku allows you to run multiple process types at different container counts. For example, if you had an app that contained 1 web app listener and 1 background job processor, dokku can, spin up 1 container for each process type defined in the Procfile. By default we will only start the web process. However, if you wanted 2 job processors running simultaneously, you can modify this behavior in a few ways. ## Include a DOKKU_SCALE file in your repo diff --git a/plugins/ps/functions b/plugins/ps/functions index e17233023..e92632564 100755 --- a/plugins/ps/functions +++ b/plugins/ps/functions @@ -25,38 +25,10 @@ release_and_deploy() { generate_scale_file() { local APP="$1"; local IMAGE="dokku/$APP"; local DOKKU_SCALE_FILE="$DOKKU_ROOT/$APP/DOKKU_SCALE" - copy_from_image "$IMAGE" "/app/DOKKU_SCALE" "$DOKKU_ROOT/$APP" 2>/dev/null || dokku_log_info1_quiet "DOKKU_SCALE not found in app image" + copy_from_image "$IMAGE" "/app/DOKKU_SCALE" "$DOKKU_ROOT/$APP" 2>/dev/null || true if [[ ! -f $DOKKU_SCALE_FILE ]]; then - local TMP_WORK_DIR=$(mktemp --tmpdir=/tmp -d DOKKU_SCALE.XXXXX) - trap 'rm -rf $TMP_WORK_DIR' INT TERM EXIT RETURN - - - if is_image_buildstep_based "$IMAGE"; then - copy_from_image "$IMAGE" /app/Procfile $TMP_WORK_DIR 2>/dev/null || true - copy_from_image "$IMAGE" /app/.release $TMP_WORK_DIR 2>/dev/null || true - - if [[ -f $TMP_WORK_DIR/Procfile ]];then - local PROCFILE="$TMP_WORK_DIR/Procfile" - elif [[ -f $TMP_WORK_DIR/.release ]];then - local PROCFILE="$TMP_WORK_DIR/.release" - else - dokku_log_info1 "No Procfile or .release file found. Defaulting to a single web process" - echo "web=1" >> $DOKKU_SCALE_FILE - fi - else - dokku_log_info1 "Dockerfile build detected. Defaulting to a single web process" - echo "web=1" >> $DOKKU_SCALE_FILE - fi - - if [[ -f $PROCFILE ]]; then - while read line || [ -n "$line" ] - do - local PROC_NAME=${line%%:*} - local PROC_CMD=${line#*:} - [[ "$PROC_NAME" =~ -.* ]] && continue - [[ -n "$PROC_CMD" ]] && echo "$PROC_NAME=1" >> $DOKKU_SCALE_FILE - done < "$PROCFILE" - fi + dokku_log_info1_quiet "DOKKU_SCALE not found in app image. Defaulting to a single web process" + echo "web=1" >> $DOKKU_SCALE_FILE dokku_log_info1_quiet "New DOKKU_SCALE file generated" while read line || [ -n "$line" ] From e1f8654a74f7360856babdb53b61f35ca925084a Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Tue, 21 Apr 2015 22:21:47 -0700 Subject: [PATCH 30/37] attempt to stop containers instead of just killing --- dokku | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dokku b/dokku index 3c3fe9db2..3e1c45d14 100755 --- a/dokku +++ b/dokku @@ -150,7 +150,7 @@ case "$1" in trap '' INT HUP sleep $WAIT for oldid in $oldids; do - docker kill $oldid + docker stop $oldid done ) & disown -a # Use trap since disown/nohup don't seem to keep child alive From 7c1ef003b70d23d138c3184480852081666a6cf0 Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Tue, 21 Apr 2015 23:13:47 -0700 Subject: [PATCH 31/37] set DYNO env var based on proc type --- dokku | 1 + 1 file changed, 1 insertion(+) diff --git a/dokku b/dokku index 3e1c45d14..ff9f45cba 100755 --- a/dokku +++ b/dokku @@ -84,6 +84,7 @@ case "$1" in # start the app DOCKER_ARGS=$(: | pluginhook docker-args $APP deploy) + DOCKER_ARGS+=" -e DYNO=$PROC_TYPE " DOCKER_ARGS+=$(: | pluginhook docker-args-deploy $APP) BIND_EXTERNAL=$(pluginhook bind-external-ip $APP) From 1fa19591bfc23142dc20c34b7d38cb4d6fc0adbe Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Tue, 21 Apr 2015 23:14:22 -0700 Subject: [PATCH 32/37] sort correctly --- dokku | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dokku b/dokku index ff9f45cba..24c83659d 100755 --- a/dokku +++ b/dokku @@ -133,9 +133,9 @@ case "$1" in else CONTAINER_IDX_OFFSET=$((PROC_COUNT + 1)) fi - find $DOKKU_ROOT/$APP -name "CONTAINER.$PROC_TYPE.*" -maxdepth 1 | tail -n +$CONTAINER_IDX_OFFSET | xargs rm -f - find $DOKKU_ROOT/$APP -name "IP.$PROC_TYPE.*" -maxdepth 1 | tail -n +$CONTAINER_IDX_OFFSET | xargs rm -f - find $DOKKU_ROOT/$APP -name "PORT.$PROC_TYPE.*" -maxdepth 1 | tail -n +$CONTAINER_IDX_OFFSET | xargs rm -f + find $DOKKU_ROOT/$APP -maxdepth 1 -name "CONTAINER.$PROC_TYPE.*" | sort -t . -k 4 -n | tail -n +$CONTAINER_IDX_OFFSET | xargs rm -f + find $DOKKU_ROOT/$APP -maxdepth 1 -name "IP.$PROC_TYPE.*" | sort -t . -k 4 -n | tail -n +$CONTAINER_IDX_OFFSET | xargs rm -f + find $DOKKU_ROOT/$APP -maxdepth 1 -name "PORT.$PROC_TYPE.*" | sort -t . -k 4 -n | tail -n +$CONTAINER_IDX_OFFSET | xargs rm -f done < "$DOKKU_SCALE_FILE" dokku_log_info1 "Running post-deploy" From 39dd4fc7007d8e727c7e3114a8a69c4987f0d4aa Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Tue, 21 Apr 2015 23:22:08 -0700 Subject: [PATCH 33/37] fix typo in output --- plugins/00_dokku-standard/commands | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/00_dokku-standard/commands b/plugins/00_dokku-standard/commands index b99d55f98..c653e0422 100755 --- a/plugins/00_dokku-standard/commands +++ b/plugins/00_dokku-standard/commands @@ -109,7 +109,7 @@ case "$1" in ;; ls) - dokku_apps=$(ls -d $DOKKU_ROOT/*/ 2>/dev/null) || (echo "You haven't depoyed any applications yet" && exit 1) + dokku_apps=$(ls -d $DOKKU_ROOT/*/ 2>/dev/null) || (echo "You haven't deployed any applications yet" && exit 1) dokku_3col_log_info2_quiet "App Name" "Container Type" "Container Id" From e9663caf5c1f2997e81d96ce37f399bebffbac0d Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Fri, 24 Apr 2015 10:49:18 -0700 Subject: [PATCH 34/37] updated dokku ls output with container status --- plugins/00_dokku-standard/commands | 9 ++++++--- plugins/common/functions | 24 ++++++++++++------------ 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/plugins/00_dokku-standard/commands b/plugins/00_dokku-standard/commands index c653e0422..2c67807f2 100755 --- a/plugins/00_dokku-standard/commands +++ b/plugins/00_dokku-standard/commands @@ -111,18 +111,21 @@ case "$1" in ls) dokku_apps=$(ls -d $DOKKU_ROOT/*/ 2>/dev/null) || (echo "You haven't deployed any applications yet" && exit 1) - dokku_3col_log_info2_quiet "App Name" "Container Type" "Container Id" + dokku_col_log_info1_quiet "App Name" "Container Type" "Container Id" "Status" for dokku_app in $dokku_apps; do APP=$(basename $dokku_app) DOKKU_APP_CIDS=$(get_container_ids $APP) + DOCKER_RUNNING_CONTAINERS=$(docker ps -q --no-trunc) if [[ -n $DOKKU_APP_CIDS ]]; then for DOKKU_APP_CID in $DOKKU_APP_CIDS; do + DOKKU_APP_CONTAINER_STATUS="stopped" + [[ $DOCKER_RUNNING_CONTAINERS =~ $DOKKU_APP_CID ]] && DOKKU_APP_CONTAINER_STATUS="running" DOKKU_APP_CONTAINER_TYPE=$(grep -l $DOKKU_APP_CID $DOKKU_ROOT/$APP/CONTAINER.* | awk -F. '{ print $2 }') - dokku_3col_log_msg "$APP" "$DOKKU_APP_CONTAINER_TYPE" "$DOKKU_APP_CID" + dokku_col_log_msg "$APP" "$DOKKU_APP_CONTAINER_TYPE" "${DOKKU_APP_CID:0:12}" "$DOKKU_APP_CONTAINER_STATUS" done else - dokku_3col_log_msg "$APP" "NOT_DEPLOYED" "NOT_DEPLOYED" + dokku_col_log_msg "$APP" "NOT_DEPLOYED" "NOT_DEPLOYED" "NOT_DEPLOYED" fi done ;; diff --git a/plugins/common/functions b/plugins/common/functions index 10df17574..7bc26b0ce 100755 --- a/plugins/common/functions +++ b/plugins/common/functions @@ -33,37 +33,37 @@ dokku_log_info2_quiet() { fi } -dokku_3col_log_info1() { - printf "%-30s %-30s %-30s\n" "-----> $@" +dokku_col_log_info1() { + printf "%-25s %-25s %-25s %-25s\n" "-----> $@" } -dokku_3col_log_info1_quiet() { +dokku_col_log_info1_quiet() { if [[ -z "$DOKKU_QUIET_OUTPUT" ]];then - printf "%-30s %-30s %-30s\n" "-----> $@" + printf "%-25s %-25s %-25s %-25s\n" "-----> $@" else return 0 fi } -dokku_3col_log_info2() { - printf "%-30s %-30s %-30s\n" "=====> $@" +dokku_col_log_info2() { + printf "%-25s %-25s %-25s %-25s\n" "=====> $@" } -dokku_3col_log_info2_quiet() { +dokku_col_log_info2_quiet() { if [[ -z "$DOKKU_QUIET_OUTPUT" ]];then - printf "%-30s %-30s %-30s\n" "=====> $@" + printf "%-25s %-25s %-25s %-25s\n" "=====> $@" else return 0 fi } -dokku_3col_log_msg() { - printf "%-30s %-30s %-30s\n" "$@" +dokku_col_log_msg() { + printf "%-25s %-25s %-25s %-25s\n" "$@" } -dokku_3col_log_msg_quiet() { +dokku_col_log_msg_quiet() { if [[ -z "$DOKKU_QUIET_OUTPUT" ]];then - printf "%-30s %-30s %-30s\n" "$@" + printf "%-25s %-25s %-25s %-25s\n" "$@" else return 0 fi From a18fa7afbe64b3ecc5b57df2d36a979767858233 Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Fri, 24 Apr 2015 11:30:20 -0700 Subject: [PATCH 35/37] we only need the first container here --- tests/unit/core_ports.bats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/core_ports.bats b/tests/unit/core_ports.bats index 0f4de64a3..b69943942 100644 --- a/tests/unit/core_ports.bats +++ b/tests/unit/core_ports.bats @@ -37,7 +37,7 @@ teardown() { @test "(core) port exposure (with NO_VHOST set)" { deploy_app dokku config:set $TEST_APP NO_VHOST=1 - CONTAINER_ID=$(docker ps --no-trunc| grep dokku/$TEST_APP | grep "start web" | awk '{ print $1 }') + CONTAINER_ID=$(docker ps --no-trunc| grep dokku/$TEST_APP | grep "start web" | awk '{ print $1 }' | head -1) run bash -c "docker port $CONTAINER_ID | sed 's/[0-9.]*://' | egrep '[0-9]*'" echo "output: "$output echo "status: "$status From 290745d3244ac43b56572682c28d5bf773be56a5 Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Fri, 24 Apr 2015 11:31:27 -0700 Subject: [PATCH 36/37] only validate and restart nginx if we're deployed. use REGEX when handling SSL and NON-SSL hosts --- plugins/nginx-vhosts/commands | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/plugins/nginx-vhosts/commands b/plugins/nginx-vhosts/commands index de3aec189..12ac262f6 100755 --- a/plugins/nginx-vhosts/commands +++ b/plugins/nginx-vhosts/commands @@ -83,7 +83,7 @@ EOF fi SSL_VHOSTS=$(egrep "^${SSL_HOSTNAME_REGEX}$|^${SSL_HOSTNAME_ALT_REGEX}$" $VHOST_PATH || exit 0) - NONSSL_VHOSTS=$(egrep -v "^${SSL_HOSTNAME}$|^${SSL_HOSTNAME_ALT}$" $VHOST_PATH || exit 0) + NONSSL_VHOSTS=$(egrep -v "^${SSL_HOSTNAME_REGEX}$|^${SSL_HOSTNAME_ALT_REGEX}$" $VHOST_PATH || exit 0) NGINX_TEMPLATE="$PLUGIN_PATH/nginx-vhosts/templates/nginx.ssl.conf.template" while read line; do @@ -118,12 +118,13 @@ EOF dokku_log_info1 "Creating $SCHEME nginx.conf" mv $NGINX_CONF "$DOKKU_ROOT/$APP/nginx.conf" - dokku_log_info1 "Running nginx-pre-reload" - pluginhook nginx-pre-reload $APP $DOKKU_APP_LISTEN_PORT $DOKKU_APP_LISTEN_IP + if is_deployed "$APP"; then + dokku_log_info1 "Running nginx-pre-reload" + pluginhook nginx-pre-reload $APP $DOKKU_APP_LISTEN_PORT $DOKKU_APP_LISTEN_IP - dokku_log_verbose "Reloading nginx" - validate_nginx - restart_nginx + dokku_log_verbose "Reloading nginx" + validate_nginx && restart_nginx + fi echo "# THIS FILE IS GENERATED BY DOKKU - DO NOT EDIT, YOUR CHANGES WILL BE OVERWRITTEN" > $URLS_PATH xargs -i echo "https://{}" <<< "${SSL_VHOSTS}" >> $URLS_PATH @@ -137,8 +138,10 @@ EOF dokku_log_info1 "VHOST support disabled, deleting nginx.conf" rm "$DOKKU_ROOT/$APP/nginx.conf" - dokku_log_info1 "VHOST support disabled, reloading nginx after nginx.conf deletion" - restart_nginx + if is_deployed "$APP"; then + dokku_log_info1 "VHOST support disabled, reloading nginx after nginx.conf deletion" + validate_nginx && restart_nginx + fi fi fi ;; From 673d43b53272f879c8ee04469910a7211c5f53b9 Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Fri, 24 Apr 2015 11:32:14 -0700 Subject: [PATCH 37/37] output containers to be stopped and killed. attempt a kill on old containers after we attempt to stop them --- dokku | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/dokku b/dokku index 24c83659d..e54319c4b 100755 --- a/dokku +++ b/dokku @@ -145,13 +145,17 @@ case "$1" in if [[ -n "$oldids" ]]; then # Let the old container finish processing requests, before terminating it WAIT="${DOKKU_WAIT_TO_RETIRE:-60}" - dokku_log_info1 "Shutting down old container in $WAIT seconds" + dokku_log_info1 "Shutting down old containers in $WAIT seconds" + for oldid in $oldids; do + dokku_log_info2 "$oldid" + done ( exec >/dev/null 2>/dev/null /dev/null + docker kill $oldid &> /dev/null # force a kill as docker seems to not send SIGKILL as the docs would indicate done ) & disown -a # Use trap since disown/nohup don't seem to keep child alive