Files
dokku/dokku
Jose Diaz-Gonzalez e66671f3c5 feat: implement the caddy plugin
This plugin uses a docker-compose based Caddy installation in conjunction with injected container labels to route requests. It only exposes the minimal necessary for routing traffic to docker containers. Users wishing to customize further labels may explore using the docker-options plugin to attach additional labels during the 'deploy' phase.
2022-08-10 14:13:19 -04:00

258 lines
7.8 KiB
Bash
Executable File

#!/usr/bin/env bash
set -eo pipefail
shopt -s nullglob
export DOCKER_BIN=docker
if [[ -r /etc/default/dokku ]]; then
# shellcheck disable=SC1091
source /etc/default/dokku
fi
export DOKKU_ROOT=${DOKKU_ROOT:=~dokku}
if [[ -f "$DOKKU_ROOT/dokkurc" ]]; then
if [[ -r $DOKKU_ROOT/dokkurc ]]; then
source "$DOKKU_ROOT/dokkurc"
else
echo "Unable to read $DOKKU_ROOT/dokkurc for sourcing" 1>&2
exit 1
fi
fi
if [[ -d $DOKKU_ROOT/.dokkurc ]]; then
for f in $DOKKU_ROOT/.dokkurc/*; do
if [[ -r "$f" ]]; then
source "$f"
else
echo "Unable to read $f for sourcing" 1>&2
exit 1
fi
done
fi
[[ $DOKKU_TRACE ]] && set -x
export DOKKU_HOST_ROOT=${DOKKU_HOST_ROOT:=$DOKKU_ROOT}
export DOKKU_DISTRO
# shellcheck disable=SC1091
DOKKU_DISTRO=$(
. /etc/os-release >/dev/null 2>&1 || true
echo "$ID"
)
# Specify twice so that only host-level
# configuration can ever override the DOCKER_BIN value
export DOCKER_BIN=${DOCKER_BIN:="docker"}
export DOKKU_IMAGE=${DOKKU_IMAGE:="gliderlabs/herokuish:latest-20"}
export DOKKU_CNB_BUILDER=${DOKKU_CNB_BUILDER:="heroku/buildpacks"}
export DOKKU_LIB_ROOT=${DOKKU_LIB_PATH:="/var/lib/dokku"}
export PLUGIN_PATH=${PLUGIN_PATH:="$DOKKU_LIB_ROOT/plugins"}
export PLUGIN_AVAILABLE_PATH=${PLUGIN_AVAILABLE_PATH:="$PLUGIN_PATH/available"}
export PLUGIN_ENABLED_PATH=${PLUGIN_ENABLED_PATH:="$PLUGIN_PATH/enabled"}
export PLUGIN_CORE_PATH=${PLUGIN_CORE_PATH:="$DOKKU_LIB_ROOT/core-plugins"}
export PLUGIN_CORE_AVAILABLE_PATH=${PLUGIN_CORE_AVAILABLE_PATH:="$PLUGIN_CORE_PATH/available"}
export PLUGIN_CORE_ENABLED_PATH=${PLUGIN_CORE_ENABLED_PATH:="$PLUGIN_CORE_PATH/enabled"}
export DOKKU_SYSTEM_GROUP=${DOKKU_SYSTEM_GROUP:="dokku"}
export DOKKU_SYSTEM_USER=${DOKKU_SYSTEM_USER:="dokku"}
export DOKKU_API_VERSION=1
export DOKKU_NOT_IMPLEMENTED_EXIT=10
export DOKKU_VALID_EXIT=0
export DOKKU_PID="$BASHPID"
export DOKKU_LOGS_DIR=${DOKKU_LOGS_DIR:="/var/log/dokku"}
export DOKKU_LOGS_HOST_DIR=${DOKKU_LOGS_HOST_DIR:=$DOKKU_LOGS_DIR}
export DOKKU_EVENTS_LOGFILE=${DOKKU_EVENTS_LOGFILE:="$DOKKU_LOGS_DIR/events.log"}
export DOKKU_CONTAINER_LABEL=dokku
export DOKKU_GLOBAL_BUILD_ARGS="--label=org.label-schema.schema-version=1.0 --label=org.label-schema.vendor=dokku --label=$DOKKU_CONTAINER_LABEL"
export DOKKU_GLOBAL_RUN_ARGS="--label=org.label-schema.schema-version=1.0 --label=org.label-schema.vendor=dokku --label=$DOKKU_CONTAINER_LABEL"
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
parse_args "$@"
args=("$@")
skip_arg=false
if [[ "${args[0]}" =~ ^--.* ]]; then
for arg in "$@"; do
$skip_arg && skip_arg=false && continue
if [[ "$arg" == "--version" ]]; then
continue
fi
if [[ "$arg" == "--app" ]]; then
shift 2 && skip_arg=true
elif [[ "$arg" =~ ^--.* ]]; then
shift 1
else
break
fi
done
fi
! has_tty && DOKKU_QUIET_OUTPUT=1
if [[ $(id -un) != "dokku" ]]; then
unset TMP TMPDIR TEMP TEMPDIR
if [[ ! $1 =~ plugin:* ]] && [[ $1 != "ssh-keys:add" ]] && [[ $1 != "ssh-keys:remove" ]]; then
export SSH_USER=$(id -un)
sudo -u dokku -E -H "$0" "$@"
exit $?
fi
fi
if [[ $1 =~ ^plugin:.* && $1 != "plugin:help" && $1 != "plugin:list" ]] || [[ $1 == "ssh-keys:add" ]] || [[ $1 == "ssh-keys:remove" ]]; then
if [[ $(id -un) != "root" ]]; then
dokku_log_fail "This command must be run as root"
else
export SSH_USER=root
fi
fi
if [[ -n "$SSH_ORIGINAL_COMMAND" ]]; then
export -n SSH_ORIGINAL_COMMAND
if [[ $1 =~ config-* ]] || [[ $1 =~ docker-options* ]]; then
# shellcheck disable=SC2086
xargs $0 <<<$SSH_ORIGINAL_COMMAND
exit $?
else
set -f
# shellcheck disable=SC2086
$0 $SSH_ORIGINAL_COMMAND
set +f
exit $?
fi
fi
if ! dokku_auth "$@"; then
dokku_log_fail "Access denied"
exit 1
fi
execute_dokku_cmd() {
declare desc="executes dokku sub-commands"
local PLUGIN_NAME="$1"
local PLUGIN_CMD=$PLUGIN_NAME
local implemented=0
local script
local argv=("$@")
case "$PLUGIN_NAME" in
events | events:*)
local PLUGIN_NAME=${PLUGIN_NAME/events/20_events}
;;
caddy | caddy:*)
local PLUGIN_NAME=${PLUGIN_NAME/caddy/caddy-vhosts}
;;
nginx | nginx:*)
local PLUGIN_NAME=${PLUGIN_NAME/nginx/nginx-vhosts}
;;
traefik | traefik:*)
local PLUGIN_NAME=${PLUGIN_NAME/traefik/traefik-vhosts}
;;
deploy | cleanup | url | urls | report)
local PLUGIN_NAME="00_dokku-standard"
;;
esac
if [[ "$(readlink -f "$PLUGIN_ENABLED_PATH/${PLUGIN_NAME%%:*}")" == *core-plugins* ]]; then
[[ ${argv[0]} == "$PLUGIN_CMD" ]] && shift 1
if [[ -n $DOKKU_APP_NAME ]]; then
set -- "$DOKKU_APP_NAME" "$@"
fi
set -- "$PLUGIN_CMD" "$@"
fi
if [[ -x $PLUGIN_ENABLED_PATH/$PLUGIN_NAME/subcommands/default ]]; then
"$PLUGIN_ENABLED_PATH/$PLUGIN_NAME/subcommands/default" "$@"
implemented=1
elif [[ -x $PLUGIN_ENABLED_PATH/$PLUGIN_NAME/subcommands/$PLUGIN_CMD ]]; then
"$PLUGIN_ENABLED_PATH/$PLUGIN_NAME/subcommands/$PLUGIN_CMD" "$@"
implemented=1
elif [[ -x $PLUGIN_ENABLED_PATH/${PLUGIN_NAME%%:*}/subcommands/${1#*:} ]] && [[ -n "${1#*:}" ]]; then
"$PLUGIN_ENABLED_PATH/${PLUGIN_NAME%%:*}/subcommands/${1#*:}" "$@"
implemented=1
fi
if [[ $implemented -eq 0 ]]; then
for script in $PLUGIN_ENABLED_PATH/*/commands; do
set +e
$script "$@"
exit_code=$?
set -e
if [[ "$exit_code" -eq "$DOKKU_NOT_IMPLEMENTED_EXIT" ]]; then
continue
fi
implemented=1
if [[ "$exit_code" -ne "$DOKKU_VALID_EXIT" ]]; then
exit $exit_code
fi
done
fi
if [[ "$implemented" -eq 0 ]]; then
dokku_log_warn "\`$*\` is not a dokku command."
dokku_log_warn "See \`dokku help\` for a list of available commands."
exit 1
fi
}
case "$1" in
help | '')
export LC_ALL=C # so sort will respect non alpha characters
ALL_PLUGIN_COMMANDS=$(find -L "$PLUGIN_PATH/enabled" -name commands 2>/dev/null || true)
# build list of core plugin command files
for plugin_command in $ALL_PLUGIN_COMMANDS; do
if [[ "$(readlink -f "$plugin_command")" == *core-plugins* ]]; then
CORE_PLUGIN_COMMANDS+="$plugin_command "
fi
done
# build list of non-core plugin command files
for plugin_command in $ALL_PLUGIN_COMMANDS; do
if [[ "$(readlink -f "$plugin_command")" != *core-plugins* ]]; then
COMMUNITY_PLUGIN_COMMANDS+="$plugin_command "
fi
done
# New lines are blank echos for readability
dokku_log_quiet "Usage: dokku [--quiet|--trace|--force] COMMAND <app> [command-specific-options]"
dokku_log_quiet ""
dokku_log_quiet "Primary help options, type \"dokku COMMAND:help\" for more details, or dokku help --all to see all commands."
dokku_log_quiet ""
dokku_log_quiet "Commands:"
dokku_log_quiet ""
if [[ "$2" == "--all" ]]; then
for core_plugin_command in $CORE_PLUGIN_COMMANDS; do
$core_plugin_command help
done | sort | column -c2 -t -s,
dokku_log_quiet ""
dokku_log_quiet "Community plugin commands:"
dokku_log_quiet ""
for community_plugin_command in $COMMUNITY_PLUGIN_COMMANDS; do
$community_plugin_command help
done | sort | column -c2 -t -s,
else
for core_plugin_command in $CORE_PLUGIN_COMMANDS; do
$core_plugin_command help
# When done, sort, sed cuts arguments out of strings and colum make it pretty
done | sort | sed -e '/^.*:/d' -e 's/\s[\[\<\-\(].*,/,/' | column -c2 -t -s,
if [[ -n "$COMMUNITY_PLUGIN_COMMANDS" ]]; then
dokku_log_quiet ""
dokku_log_quiet "Community plugin commands:"
dokku_log_quiet ""
for community_plugin_command in $COMMUNITY_PLUGIN_COMMANDS; do
$community_plugin_command help
done | sort | column -c2 -t -s,
fi
fi
;;
version | -v | --version)
dokku_version
;;
*)
execute_dokku_cmd "$@"
;;
esac