Merge pull request #5472 from dokku/5381-compose-proxy-lifecycle

This commit is contained in:
josegonzalez
2022-12-01 02:16:45 -05:00
committed by GitHub
15 changed files with 135 additions and 31 deletions

View File

@@ -5,6 +5,8 @@
- The output of `run:detached` now uses the container name - eg. `node-js-app.run.1` - vs the container id.
- The ID of `cron` tasks is now base36-encoded instead of base64-encoded.
- The `nginx.conf.sigil` is now extracted when source code is extracted for a build and not from the built image. Users can specify alternative paths via the `nginx-conf-sigil-path` property of the `nginx` plugin. See the [nginx documentation](/docs/networking/proxies/nginx.md#customizing-the-nginx-configuration) for more information on how to configure the `nginx.conf.sigil` path for your application.
- The existing `pre-restore` hook has been renamed to `scheduler-pre-restore`. There is a new `pre-restore` hook that is triggered within the `ps:restore` command prior to restoring any apps.
- Nginx init commands are now performed via systemctl on Ubuntu systems when `/usr/bin/systemctl` is available.
## Removals

View File

@@ -1753,7 +1753,7 @@ APP="$1"; IMAGE_TAG="$2"; IMAGE=$(get_app_image_name $APP $IMAGE_TAG)
- Description: Allows you to run commands before all containers are restored
- Invoked by: `dokku ps:restore`
- Arguments: `$DOKKU_SCHEDULER $APP`
- Arguments:
- Example:
```shell
@@ -2187,6 +2187,25 @@ DOKKU_SCHEDULER="$1"; APP="$2";
# TODO
```
### `scheduler-pre-restore`
> Warning: The scheduler plugin trigger apis are under development and may change
> between minor releases until the 1.0 release.
- Description: Allows you to run commands before an app is restored
- Invoked by: `dokku ps:restore`
- Arguments: `$DOKU_SCHEDULER $APP`
- Example:
```shell
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
DOKKU_SCHEDULER="$1"; APP="$2";
# TODO
```
### `scheduler-post-delete`
> Warning: The scheduler plugin trigger apis are under development and may change

View File

@@ -0,0 +1 @@
hook

View File

@@ -131,6 +131,7 @@ cmd-caddy-start() {
local TMP_COMPOSE_FILE=$(mktemp "/tmp/dokku-${DOKKU_PID}-${FUNCNAME[0]}.XXXXXX")
trap "rm -rf '$TMP_COMPOSE_FILE' >/dev/null" RETURN INT TERM EXIT
fn-plugin-property-write "caddy" "--global" "proxy-status" "started"
fn-caddy-template-compose-file "$TMP_COMPOSE_FILE"
"$DOCKER_BIN" compose -f "$TMP_COMPOSE_FILE" -p caddy up -d --quiet-pull
}
@@ -147,6 +148,7 @@ cmd-caddy-stop() {
local TMP_COMPOSE_FILE=$(mktemp "/tmp/dokku-${DOKKU_PID}-${FUNCNAME[0]}.XXXXXX")
trap "rm -rf '$TMP_COMPOSE_FILE' >/dev/null" RETURN INT TERM EXIT
fn-plugin-property-write "caddy" "--global" "proxy-status" "stopped"
fn-caddy-template-compose-file "$TMP_COMPOSE_FILE"
"$DOCKER_BIN" compose -f "$TMP_COMPOSE_FILE" -p caddy down --remove-orphans
}

View File

@@ -0,0 +1,20 @@
#!/usr/bin/env bash
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/caddy-vhosts/command-functions"
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
trigger-caddy-pre-restore() {
declare desc="pre-restore the caddy proxy"
declare trigger="install"
if [[ "$(fn-plugin-property-get "caddy" "--global" "proxy-status")" == "stopped" ]]; then
return
fi
if ! cmd-caddy-start; then
dokku_log_warn "Failed to restore caddy proxy, requests may not route as expected"
fi
}
trigger-caddy-pre-restore "$@"

View File

@@ -110,24 +110,26 @@ cmd-nginx-show-config() {
cat "$DOKKU_ROOT/$APP/nginx.conf"
}
cmd-nginx-stop() {
declare desc="stops the nginx server"
declare cmd="nginx:stop"
[[ "$1" == "$cmd" ]] && shift 1
touch "${DOKKU_LIB_ROOT}/data/nginx-vhosts/nginx.stopped"
fn-nginx-vhosts-nginx-init-cmd "stop"
}
cmd-nginx-start() {
declare desc="starts the nginx server"
declare cmd="nginx:start"
[[ "$1" == "$cmd" ]] && shift 1
rm -f "${DOKKU_LIB_ROOT}/data/nginx-vhosts/nginx.stopped"
fn-plugin-property-write "nginx" "--global" "proxy-status" "started"
fn-nginx-vhosts-nginx-init-cmd "enable"
fn-nginx-vhosts-nginx-init-cmd "start"
}
cmd-nginx-stop() {
declare desc="stops the nginx server"
declare cmd="nginx:stop"
[[ "$1" == "$cmd" ]] && shift 1
fn-plugin-property-write "nginx" "--global" "proxy-status" "stopped"
fn-nginx-vhosts-nginx-init-cmd "stop"
fn-nginx-vhosts-nginx-init-cmd "disable"
}
cmd-nginx-validate-config() {
declare desc="validates and optionally cleans up invalid nginx configurations"
declare cmd="nginx:validate-config"

View File

@@ -69,19 +69,21 @@ trigger-nginx-vhosts-install() {
local mode="0440"
case "$DOKKU_DISTRO" in
debian | raspbian)
echo "%dokku ALL=(ALL) NOPASSWD:/usr/sbin/invoke-rc.d $NGINX_INIT_NAME reload, /usr/sbin/invoke-rc.d $NGINX_INIT_NAME start, /usr/sbin/invoke-rc.d $NGINX_INIT_NAME stop, $NGINX_BIN -t, ${NGINX_BIN} -t -c *" >"$NGINX_SUDOERS_FILE"
echo "%dokku ALL=(ALL) NOPASSWD:/usr/sbin/invoke-rc.d $NGINX_INIT_NAME enable, /usr/sbin/invoke-rc.d $NGINX_INIT_NAME disable, /usr/sbin/invoke-rc.d $NGINX_INIT_NAME reload, /usr/sbin/invoke-rc.d $NGINX_INIT_NAME start, /usr/sbin/invoke-rc.d $NGINX_INIT_NAME stop, $NGINX_BIN -t, ${NGINX_BIN} -t -c *" >"$NGINX_SUDOERS_FILE"
;;
ubuntu)
if [[ -x /usr/bin/sv ]]; then
echo "%dokku ALL=(ALL) NOPASSWD:/usr/bin/sv reload $NGINX_INIT_NAME, /usr/bin/sv start $NGINX_INIT_NAME, /usr/bin/sv stop $NGINX_INIT_NAME, $NGINX_BIN -t, $NGINX_BIN -t -c *" >"$NGINX_SUDOERS_FILE"
echo "%dokku ALL=(ALL) NOPASSWD:/usr/bin/sv enable $NGINX_INIT_NAME, /usr/bin/sv disable $NGINX_INIT_NAME, /usr/bin/sv reload $NGINX_INIT_NAME, /usr/bin/sv start $NGINX_INIT_NAME, /usr/bin/sv stop $NGINX_INIT_NAME, $NGINX_BIN -t, $NGINX_BIN -t -c *" >"$NGINX_SUDOERS_FILE"
elif [[ -x /usr/bin/systemctl ]]; then
echo "%dokku ALL=(ALL) NOPASSWD:/usr/bin/systemctl enable $NGINX_INIT_NAME, /usr/bin/systemctl disable $NGINX_INIT_NAME, /usr/bin/systemctl reload $NGINX_INIT_NAME, /usr/bin/systemctl start $NGINX_INIT_NAME, /usr/bin/systemctl stop $NGINX_INIT_NAME, $NGINX_BIN -t, $NGINX_BIN -t -c *" >"$NGINX_SUDOERS_FILE"
else
echo "%dokku ALL=(ALL) NOPASSWD:/etc/init.d/$NGINX_INIT_NAME reload, /etc/init.d/$NGINX_INIT_NAME start, /etc/init.d/$NGINX_INIT_NAME stop, $NGINX_BIN -t, $NGINX_BIN -t -c *" >"$NGINX_SUDOERS_FILE"
echo "%dokku ALL=(ALL) NOPASSWD:/etc/init.d/$NGINX_INIT_NAME enable, /etc/init.d/$NGINX_INIT_NAME disable, /etc/init.d/$NGINX_INIT_NAME reload, /etc/init.d/$NGINX_INIT_NAME start, /etc/init.d/$NGINX_INIT_NAME stop, $NGINX_BIN -t, $NGINX_BIN -t -c *" >"$NGINX_SUDOERS_FILE"
fi
;;
arch)
echo "%dokku ALL=(ALL) NOPASSWD:/usr/bin/systemctl reload $NGINX_INIT_NAME, /usr/bin/systemctl start $NGINX_INIT_NAME, /usr/bin/systemctl stop $NGINX_INIT_NAME, $NGINX_BIN -t, $NGINX_BIN -t -c *" >"$NGINX_SUDOERS_FILE"
echo "%dokku ALL=(ALL) NOPASSWD:/usr/bin/systemctl enable $NGINX_INIT_NAME, /usr/bin/systemctl disable $NGINX_INIT_NAME, /usr/bin/systemctl reload $NGINX_INIT_NAME, /usr/bin/systemctl start $NGINX_INIT_NAME, /usr/bin/systemctl stop $NGINX_INIT_NAME, $NGINX_BIN -t, $NGINX_BIN -t -c *" >"$NGINX_SUDOERS_FILE"
;;
esac
@@ -130,10 +132,15 @@ trigger-nginx-vhosts-install() {
fn-nginx-vhosts-migrate-env-vars
fn-nginx-vhosts-migrate-nginx-conf-sigil
if [[ -f "${DOKKU_LIB_ROOT}/data/nginx-vhosts/nginx.stopped" ]]; then
rm -f "${DOKKU_LIB_ROOT}/data/nginx-vhosts/nginx.stopped"
fn-plugin-property-write "nginx" "--global" "proxy-status" "stopped"
fi
# avoid failing runit init calls on install
# the runit binaries are not yet available during dockerfile building
# and therefore both these calls will fail
if [[ ! -x /usr/bin/sv ]] && [[ ! -f "${DOKKU_LIB_ROOT}/data/nginx-vhosts/nginx.stopped" ]]; then
if [[ ! -x /usr/bin/sv ]] && [[ "$(fn-plugin-property-get "nginx" "--global" "proxy-status")" != "stopped" ]]; then
fn-nginx-vhosts-nginx-init-cmd start || fn-nginx-vhosts-nginx-init-cmd reload
fi
}

View File

@@ -132,6 +132,10 @@ fn-nginx-vhosts-nginx-init-cmd() {
# support docker-based installations
if [[ -x /usr/bin/sv ]]; then
sudo /usr/bin/sv "$CMD" "$NGINX_INIT_NAME"
elif [[ -x /usr/bin/systemctl ]]; then
sudo /usr/bin/systemctl "$CMD" "$NGINX_INIT_NAME"
elif [[ "$CMD" == "enable" ]] || [[ "$CMD" == "disable" ]]; then
dokku_log_warn "Running $CMD is not possible for init.d managed services"
else
sudo "/etc/init.d/$NGINX_INIT_NAME" "$CMD"
fi

View File

@@ -0,0 +1,20 @@
#!/usr/bin/env bash
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/nginx-vhosts/command-functions"
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
trigger-nginx-pre-restore() {
declare desc="pre-restore the nginx proxy"
declare trigger="install"
if [[ "$(fn-plugin-property-get "nginx" "--global" "proxy-status")" == "stopped" ]]; then
return
fi
if ! cmd-nginx-start; then
dokku_log_warn "Failed to restore nginx proxy, requests may not route as expected"
fi
}
trigger-nginx-pre-restore "$@"

View File

@@ -115,8 +115,8 @@ func RestartProcess(appName string, processName string) error {
// Restore ensures an app that should be running is running on boot
func Restore(appName string) error {
scheduler := common.GetAppScheduler(appName)
if err := common.PlugnTrigger("pre-restore", []string{scheduler, appName}...); err != nil {
return fmt.Errorf("Error running pre-restore: %s", err)
if err := common.PlugnTrigger("scheduler-pre-restore", []string{scheduler, appName}...); err != nil {
return fmt.Errorf("Error running scheduler-pre-restore: %s", err)
}
common.LogInfo1("Clearing potentially invalid proxy configuration")

View File

@@ -74,6 +74,10 @@ func CommandRestart(appName string, processName string, allApps bool, parallelCo
// CommandRestore starts previously running apps e.g. after reboot
func CommandRestore(appName string, allApps bool, parallelCount int) error {
if err := common.PlugnTrigger("pre-restore", []string{}...); err != nil {
return fmt.Errorf("Error running pre-restore: %s", err)
}
if allApps {
if err := restorePrep(); err != nil {
return err

View File

@@ -3,9 +3,9 @@ set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
trigger-scheduler-docker-local-pre-restore() {
declare desc="scheduler-docker-local pre-restore plugin trigger"
declare trigger="pre-restore"
trigger-scheduler-docker-local-scheduler-pre-restore() {
declare desc="scheduler-docker-local scheduler-pre-restore plugin trigger"
declare trigger="scheduler-pre-restore"
declare DOKKU_SCHEDULER="$1"
if [[ "$DOKKU_SCHEDULER" != "docker-local" ]]; then
@@ -17,4 +17,4 @@ trigger-scheduler-docker-local-pre-restore() {
"$DOCKER_BIN" container rm $("$DOCKER_BIN" container list --all --format "{{.Names}}" --filter "label=$DOKKU_CONTAINER_LABEL" --quiet | grep -E '(.+\..+\.[0-9]+\.[0-9]+$)') &>/dev/null || true
}
trigger-scheduler-docker-local-pre-restore "$@"
trigger-scheduler-docker-local-scheduler-pre-restore "$@"

View File

@@ -135,6 +135,7 @@ cmd-traefik-start() {
local TMP_COMPOSE_FILE=$(mktemp "/tmp/dokku-${DOKKU_PID}-${FUNCNAME[0]}.XXXXXX")
trap "rm -rf '$TMP_COMPOSE_FILE' >/dev/null" RETURN INT TERM EXIT
fn-plugin-property-write "traefik" "--global" "proxy-status" "started"
touch "${DOKKU_LIB_ROOT}/data/traefik/traefik-acme.json"
chmod 600 "${DOKKU_LIB_ROOT}/data/traefik/traefik-acme.json"
fn-traefik-template-compose-file "$TMP_COMPOSE_FILE"
@@ -153,6 +154,7 @@ cmd-traefik-stop() {
local TMP_COMPOSE_FILE=$(mktemp "/tmp/dokku-${DOKKU_PID}-${FUNCNAME[0]}.XXXXXX")
trap "rm -rf '$TMP_COMPOSE_FILE' >/dev/null" RETURN INT TERM EXIT
fn-plugin-property-write "traefik" "--global" "proxy-status" "stopped"
touch "${DOKKU_LIB_ROOT}/data/traefik/traefik-acme.json"
chmod 600 "${DOKKU_LIB_ROOT}/data/traefik/traefik-acme.json"
fn-traefik-template-compose-file "$TMP_COMPOSE_FILE"

View File

@@ -0,0 +1,20 @@
#!/usr/bin/env bash
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/traefik-vhosts/command-functions"
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
trigger-traefik-pre-restore() {
declare desc="pre-restore the traefik proxy"
declare trigger="install"
if [[ "$(fn-plugin-property-get "traefik" "--global" "proxy-status")" == "stopped" ]]; then
return
fi
if ! cmd-traefik-start; then
dokku_log_warn "Failed to restore traefik proxy, requests may not route as expected"
fi
}
trigger-traefik-pre-restore "$@"

View File

@@ -104,6 +104,12 @@ teardown() {
echo "output: $output"
echo "status: $status"
assert_output "5000"
run /bin/bash -c "docker inspect $TEST_APP.web.1 --format '{{ index .Config.Labels \"traefik.http.routers.$TEST_APP-web-http.priority\" }}'"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "12345"
}
@test "(traefik) ssl" {
@@ -112,11 +118,6 @@ teardown() {
echo "status: $status"
assert_success
run /bin/bash -c "dokku traefik:set $TEST_APP priority 12345"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku proxy:set $TEST_APP traefik"
echo "output: $output"
echo "status: $status"
@@ -127,13 +128,13 @@ teardown() {
echo "status: $status"
assert_success
run /bin/bash -c "docker inspect $TEST_APP.web.1 --format '{{ index .Config.Labels \"traefik.http.services.$TEST_APP-web-http-12345.loadbalancer.server.port\" }}'"
run /bin/bash -c "docker inspect $TEST_APP.web.1 --format '{{ index .Config.Labels \"traefik.http.services.$TEST_APP-web-http.loadbalancer.server.port\" }}'"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "5000"
run /bin/bash -c "docker inspect $TEST_APP.web.1 --format '{{ index .Config.Labels \"traefik.http.services.$TEST_APP-web-https-12345.loadbalancer.server.port\" }}'"
run /bin/bash -c "docker inspect $TEST_APP.web.1 --format '{{ index .Config.Labels \"traefik.http.services.$TEST_APP-web-https.loadbalancer.server.port\" }}'"
echo "output: $output"
echo "status: $status"
assert_success
@@ -164,13 +165,13 @@ teardown() {
echo "status: $status"
assert_success
run /bin/bash -c "docker inspect $TEST_APP.web.1 --format '{{ index .Config.Labels \"traefik.http.services.$TEST_APP-web-http-12345.loadbalancer.server.port\" }}'"
run /bin/bash -c "docker inspect $TEST_APP.web.1 --format '{{ index .Config.Labels \"traefik.http.services.$TEST_APP-web-http.loadbalancer.server.port\" }}'"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "5000"
run /bin/bash -c "docker inspect $TEST_APP.web.1 --format '{{ index .Config.Labels \"traefik.http.services.$TEST_APP-web-https-12345.loadbalancer.server.port\" }}'"
run /bin/bash -c "docker inspect $TEST_APP.web.1 --format '{{ index .Config.Labels \"traefik.http.services.$TEST_APP-web-https.loadbalancer.server.port\" }}'"
echo "output: $output"
echo "status: $status"
assert_success