#!/usr/bin/env bash source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$PLUGIN_AVAILABLE_PATH/proxy/functions" source "$PLUGIN_AVAILABLE_PATH/traefik-vhosts/internal-functions" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x trigger-traefik-vhosts-docker-args-process-deploy() { declare desc="nginx-vhosts core-post-deploy plugin trigger" declare trigger="docker-args-process-deploy" declare APP="$1" IMAGE_SOURCE_TYPE="$2" IMAGE_TAG="$3" PROC_TYPE="$4" CONTAINER_INDEX="$5" local app_domains is_app_listening letsencrypt_email output proxy_container_port proxy_host_port port_map proxy_scheme proxy_schemes traefik_domains local proxy_container_http_port proxy_container_http_port_candidate proxy_host_http_port_candidate local proxy_container_https_port proxy_container_https_port_candidate proxy_host_https_port_candidate local STDIN=$(cat) if [[ "$PROC_TYPE" != "web" ]]; then return fi if [[ "$(plugn trigger proxy-type "$APP")" != "traefik" ]]; then return fi if [[ "$(plugn trigger proxy-is-enabled "$APP")" != "true" ]]; then return fi if ! plugn trigger domains-vhost-enabled "$APP" 2>/dev/null; then return fi # ensure we have a port mapping plugn trigger ports-configure "$APP" # gather port mapping information # we only support proxying a single port for http and https listeners # so this block parses the port mappings and tries to find the correct # mapping to expose is_app_listening="false" while read -r port_map; do proxy_scheme="$(awk -F ':' '{ print $1 }' <<<"$port_map")" proxy_host_port="$(awk -F ':' '{ print $2 }' <<<"$port_map")" proxy_container_port="$(awk -F ':' '{ print $3 }' <<<"$port_map")" if [[ "$proxy_scheme" == "http" ]]; then is_app_listening="true" if [[ -z "$proxy_container_http_port_candidate" ]]; then proxy_container_http_port_candidate="$proxy_container_port" proxy_host_http_port_candidate="$proxy_host_port" fi if [[ "$proxy_host_port" == "80" ]] && [[ -z "$proxy_container_http_port" ]]; then proxy_container_http_port="$proxy_container_port" fi fi if [[ "$proxy_scheme" == "https" ]]; then is_app_listening="true" if [[ -z "$proxy_container_https_port_candidate" ]]; then proxy_container_https_port_candidate="$proxy_container_port" proxy_host_https_port_candidate="$proxy_host_port" fi if [[ "$proxy_host_port" == "443" ]] && [[ -z "$proxy_container_https_port" ]]; then proxy_container_https_port="$proxy_container_port" fi fi done < <(plugn trigger ports-get "$APP") letsencrypt_email="$(fn-traefik-computed-letsencrypt-email)" if [[ -n "$letsencrypt_email" ]] && [[ -z "$proxy_container_https_port" ]]; then proxy_container_https_port_candidate="$proxy_container_http_port_candidate" proxy_host_https_port_candidate="$proxy_host_http_port_candidate" if [[ -n "$proxy_container_http_port" ]]; then proxy_container_https_port_candidate="$proxy_container_http_port" proxy_host_http_port_candidate=443 fi fi # add the labels for traefik here # any `http:80` port mapping is treated as a `http` traefik entrypoint # any `https:443` port mapping is treated as a `https` traefik entrypoint if [[ -n "$is_app_listening" ]]; then app_domains="$(plugn trigger domains-list "$APP")" if [[ -n "$app_domains" ]]; then # get length of domains if [[ "$(echo "$traefik_domains" | wc -w)" -eq 1 ]]; then traefik_domains="Host(\`$traefik_domains\`)" else for domain in $(echo "$app_domains" | xargs); do if [[ -z "$traefik_domains" ]]; then traefik_domains="Host(\`$domain\`)" continue fi traefik_domains="$traefik_domains || Host(\`$domain\`)" done fi fi output="--label traefik.enable=true" if [[ -n "$proxy_container_http_port" ]] || [[ -n "$proxy_container_http_port_candidate" ]]; then if [[ -z "$proxy_container_http_port" ]]; then dokku_log_warn "Warning: http:80 port mapping not found" dokku_log_warn "Utilizing first http port mapping, http:$proxy_host_http_port_candidate:$proxy_container_http_port_candidate" proxy_container_http_port="$proxy_container_http_port_candidate" fi output="$output --label traefik.http.services.$APP-$PROC_TYPE-http.loadbalancer.server.port=$proxy_container_http_port" output="$output --label traefik.http.routers.$APP-$PROC_TYPE-http.entrypoints=$(fn-traefik-computed-http-entry-point)" output="$output --label traefik.http.routers.$APP-$PROC_TYPE-http.service=$APP-$PROC_TYPE-http" if [[ -n "$traefik_domains" ]]; then output="$output --label \"traefik.http.routers.$APP-$PROC_TYPE-http.rule=$traefik_domains\"" fi fi if [[ -n "$proxy_container_https_port" ]] || [[ -n "$proxy_container_https_port_candidate" ]]; then if [[ -z "$proxy_container_https_port" ]]; then dokku_log_warn "Warning: https:443 port mapping not found" dokku_log_warn "Utilizing first https port mapping, http:$proxy_host_https_port_candidate:$proxy_container_https_port_candidate" proxy_container_https_port="$proxy_container_https_port_candidate" fi output="$output --label traefik.http.services.$APP-$PROC_TYPE-https.loadbalancer.server.port=$proxy_container_https_port" output="$output --label traefik.http.routers.$APP-$PROC_TYPE-https.entrypoints=$(fn-traefik-computed-https-entry-point)" output="$output --label traefik.http.routers.$APP-$PROC_TYPE-https.service=$APP-$PROC_TYPE-https" output="$output --label traefik.http.routers.$APP-$PROC_TYPE-https.tls.certresolver=leresolver" if [[ -n "$traefik_domains" ]]; then output="$output --label \"traefik.http.routers.$APP-$PROC_TYPE-https.rule=$traefik_domains\"" fi fi local app_json hc_path hc_scheme hc_port hc_timeout hc_interval hc_filter app_json="$(plugn trigger app-json-get-content "$APP" 2>/dev/null || echo "{}")" hc_filter='.healthchecks.web // [] | map(select(.type == "readiness" and .path != null and .path != "")) | .[0]' hc_path=$(echo "$app_json" | jq -r "$hc_filter | .path // empty") if [[ -n "$hc_path" ]]; then hc_scheme=$(echo "$app_json" | jq -r "$hc_filter | .scheme // empty") hc_port=$(echo "$app_json" | jq -r "$hc_filter | .port // empty") hc_timeout=$(echo "$app_json" | jq -r "$hc_filter | .timeout // empty") hc_interval=$(echo "$app_json" | jq -r "$hc_filter | .wait // empty") if [[ -n "$proxy_container_http_port" ]]; then output="$output --label traefik.http.services.$APP-$PROC_TYPE-http.loadbalancer.healthcheck.path=$hc_path" [[ -n "$hc_scheme" ]] && output="$output --label traefik.http.services.$APP-$PROC_TYPE-http.loadbalancer.healthcheck.scheme=$hc_scheme" [[ -n "$hc_port" ]] && output="$output --label traefik.http.services.$APP-$PROC_TYPE-http.loadbalancer.healthcheck.port=$hc_port" [[ -n "$hc_timeout" ]] && output="$output --label traefik.http.services.$APP-$PROC_TYPE-http.loadbalancer.healthcheck.timeout=${hc_timeout}s" [[ -n "$hc_interval" ]] && output="$output --label traefik.http.services.$APP-$PROC_TYPE-http.loadbalancer.healthcheck.interval=${hc_interval}s" fi if [[ -n "$proxy_container_https_port" ]]; then output="$output --label traefik.http.services.$APP-$PROC_TYPE-https.loadbalancer.healthcheck.path=$hc_path" [[ -n "$hc_scheme" ]] && output="$output --label traefik.http.services.$APP-$PROC_TYPE-https.loadbalancer.healthcheck.scheme=$hc_scheme" [[ -n "$hc_port" ]] && output="$output --label traefik.http.services.$APP-$PROC_TYPE-https.loadbalancer.healthcheck.port=$hc_port" [[ -n "$hc_timeout" ]] && output="$output --label traefik.http.services.$APP-$PROC_TYPE-https.loadbalancer.healthcheck.timeout=${hc_timeout}s" [[ -n "$hc_interval" ]] && output="$output --label traefik.http.services.$APP-$PROC_TYPE-https.loadbalancer.healthcheck.interval=${hc_interval}s" fi fi fi local proxy_labels_file_path=$(fn-proxy-get-labels-file-path "traefik" "$APP") if [[ -f "$proxy_labels_file_path" ]]; then while read -r line; do [[ -z "$line" ]] && continue output="$output --label '$line'" done <"$proxy_labels_file_path" fi echo -n "$STDIN $output" } trigger-traefik-vhosts-docker-args-process-deploy "$@"