#!/bin/bash # Per-port Traefik subdomain/host writer. # # Companion to traefik_port_middlewares.sh. Where that stamps a per-port # MIDDLEWARE_TAG_, this stamps a per-port DOMAINSUBNAME_TAG_ holding the # fully-qualified host for that port's Traefik router, derived from the port's # `subdomain` column (the 11th field of the 12-col PORT format). # # A single container can expose any number of hosts — one per Traefik-managed port. # # subdomain "" | "@" | "root" -> (apex / root of domain) # subdomain "vault" -> vault. (single label) # subdomain "admin.headscale" -> admin.headscale. (multi-level allowed) # # Index scheme matches traefik_port_middlewares.sh exactly: i walks every # parsed port (0-based), idx = i+1 is the 1-based position used in the tag # suffix, and only Traefik-managed ports (traefik=true) are stamped — so a # port's MIDDLEWARE_TAG_ and DOMAINSUBNAME_TAG_ always line up on the # same router. tagsProcessorPortSubdomains() { local file="$1" local app_name="$2" if [[ -z "$file" || -z "$app_name" ]]; then return 0 fi local count=${#port_service_names[@]} local i=0 while [[ $i -lt $count ]]; do local idx=$((i + 1)) local p_traefik="${port_traefik_managed[$i]}" local p_sub="${port_subdomains[$i]}" if [[ "$p_traefik" == "true" ]]; then local host if [[ "$p_sub" == "@" || "$p_sub" == "root" ]]; then host="${domain_full}" # apex / root of the domain (explicit only) elif [[ -n "$p_sub" ]]; then host="${p_sub}.${domain_full}" # subdomain (single or multi-level) else host="${app_name}.${domain_full}" # no subdomain set -> app-name default fi tagsManagerUpdateUniversalTag "$file" "DOMAINSUBNAME_TAG_${idx}" "$host" fi i=$((i + 1)) done } # Comments out the Traefik router block for any port that is NOT Traefik-managed # (non-public, metrics-only, or a slot with no router at all), so an unfilled # DOMAINSUBNAME_DATA_ placeholder can never reach a live compose. Each router # is wrapped in # TRAEFIK_PORT__BEGIN ... # TRAEFIK_PORT__END markers; # this mirrors the GLUETUN_OFF region-commenting in tags_processor_network_mode.sh. tagsProcessorPortRouterBlocks() { local file="$1" local app_name="$2" if [[ -z "$file" || ! -f "$file" ]]; then return 0 fi # Space-padded list of 1-based indices of Traefik-managed ports, e.g. " 1 3 ". local active=" " local count=${#port_service_names[@]} local i=0 while [[ $i -lt $count ]]; do [[ "${port_traefik_managed[$i]}" == "true" ]] && active+="$((i + 1)) " i=$((i + 1)) done local tmp="${file}.routers.$$" runFileOp awk -v active="$active" ' BEGIN { off = 0 } /#[[:space:]]*TRAEFIK_PORT_[0-9]+_BEGIN/ { match($0, /TRAEFIK_PORT_[0-9]+/); key = substr($0, RSTART, RLENGTH) sub(/TRAEFIK_PORT_/, "", key) off = (index(active, " " key " ") > 0) ? 0 : 1 # off=1 -> comment the block print; next } /#[[:space:]]*TRAEFIK_PORT_[0-9]+_END/ { off = 0; print; next } { if (off == 1 && $0 !~ /^[[:space:]]*#/) { match($0, /^[[:space:]]*/) indent = substr($0, RSTART, RLENGTH) rest = substr($0, RLENGTH + 1) print indent "# " rest next } print } ' "$file" | runFileWrite "$tmp" >/dev/null runFileOp mv "$tmp" "$file" }