feat: add phase 8.5 Nginx to Caddy migration wrapper and enhance post-check script for direct access handling
This commit is contained in:
@@ -42,6 +42,72 @@ PHASE8_STATE_FILE="${PHASE8_STATE_DIR}/phase8_github_repo_state.json"
|
||||
UNRAID_DOCKER_NETWORK_NAME="br0"
|
||||
# Compose files live in a centralized project directory.
|
||||
CADDY_COMPOSE_DIR="${UNRAID_COMPOSE_DIR}/caddy"
|
||||
PHASE8_GITEA_ROUTE_BEGIN="# BEGIN_PHASE8_GITEA_ROUTE"
|
||||
PHASE8_GITEA_ROUTE_END="# END_PHASE8_GITEA_ROUTE"
|
||||
|
||||
wait_for_https_public() {
|
||||
local host="$1" max_secs="${2:-30}"
|
||||
local elapsed=0
|
||||
while [[ $elapsed -lt $max_secs ]]; do
|
||||
if curl -sf -o /dev/null "https://${host}/api/v1/version" 2>/dev/null; then
|
||||
return 0
|
||||
fi
|
||||
sleep 2
|
||||
elapsed=$((elapsed + 2))
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
wait_for_https_via_resolve() {
|
||||
local host="$1" ip="$2" max_secs="${3:-300}"
|
||||
local elapsed=0
|
||||
log_info "Waiting for HTTPS via direct Caddy path (--resolve ${host}:443:${ip})..."
|
||||
while [[ $elapsed -lt $max_secs ]]; do
|
||||
if curl -skf --resolve "${host}:443:${ip}" "https://${host}/api/v1/version" >/dev/null 2>&1; then
|
||||
log_success "HTTPS reachable via Caddy IP (after ${elapsed}s)"
|
||||
return 0
|
||||
fi
|
||||
sleep 2
|
||||
elapsed=$((elapsed + 2))
|
||||
done
|
||||
log_error "Timeout waiting for HTTPS via --resolve (${host} -> ${ip}) after ${max_secs}s"
|
||||
if ssh_exec UNRAID "docker ps --format '{{.Names}}' | grep -qx 'caddy'" >/dev/null 2>&1; then
|
||||
log_warn "Recent Caddy logs (tail 80):"
|
||||
ssh_exec UNRAID "docker logs --tail 80 caddy 2>&1" || true
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
caddyfile_has_domain_block() {
|
||||
local file="$1" domain="$2"
|
||||
awk -v domain="$domain" '
|
||||
function trim(s) {
|
||||
sub(/^[[:space:]]+/, "", s)
|
||||
sub(/[[:space:]]+$/, "", s)
|
||||
return s
|
||||
}
|
||||
{
|
||||
line = $0
|
||||
if (line ~ /^[[:space:]]*#/) next
|
||||
pos = index(line, "{")
|
||||
if (pos <= 0) next
|
||||
|
||||
labels = trim(substr(line, 1, pos - 1))
|
||||
if (labels == "" || labels ~ /^\(/) next
|
||||
|
||||
gsub(/[[:space:]]+/, "", labels)
|
||||
n = split(labels, parts, ",")
|
||||
for (i = 1; i <= n; i++) {
|
||||
if (parts[i] == domain) {
|
||||
found = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
END {
|
||||
exit(found ? 0 : 1)
|
||||
}
|
||||
' "$file"
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Helper: persist original GitHub repo settings for teardown symmetry
|
||||
@@ -145,28 +211,62 @@ fi
|
||||
# Step 2: Render + deploy Caddyfile
|
||||
# ---------------------------------------------------------------------------
|
||||
log_step 2 "Deploying Caddyfile..."
|
||||
if ssh_exec UNRAID "test -f '${CADDY_DATA_PATH}/Caddyfile'" 2>/dev/null; then
|
||||
log_info "Caddyfile already exists — skipping"
|
||||
else
|
||||
TMPFILE=$(mktemp)
|
||||
GITEA_CONTAINER_IP="${UNRAID_GITEA_IP}"
|
||||
export GITEA_CONTAINER_IP GITEA_DOMAIN CADDY_DOMAIN
|
||||
GITEA_CONTAINER_IP="${UNRAID_GITEA_IP}"
|
||||
export GITEA_CONTAINER_IP GITEA_DOMAIN CADDY_DOMAIN
|
||||
CADDYFILE_UPDATED=0
|
||||
|
||||
# Build TLS block based on TLS_MODE
|
||||
if [[ "$TLS_MODE" == "cloudflare" ]]; then
|
||||
TLS_BLOCK=" tls {
|
||||
# Build TLS block based on TLS_MODE
|
||||
if [[ "$TLS_MODE" == "cloudflare" ]]; then
|
||||
TLS_BLOCK=" tls {
|
||||
dns cloudflare {env.CF_API_TOKEN}
|
||||
}"
|
||||
else
|
||||
TLS_BLOCK=" tls ${SSL_CERT_PATH} ${SSL_KEY_PATH}"
|
||||
fi
|
||||
export TLS_BLOCK
|
||||
|
||||
if ssh_exec UNRAID "test -f '${CADDY_DATA_PATH}/Caddyfile'" 2>/dev/null; then
|
||||
TMP_EXISTING=$(mktemp)
|
||||
TMP_UPDATED=$(mktemp)
|
||||
TMP_ROUTE_BLOCK=$(mktemp)
|
||||
|
||||
ssh_exec UNRAID "cat '${CADDY_DATA_PATH}/Caddyfile'" > "$TMP_EXISTING"
|
||||
|
||||
if caddyfile_has_domain_block "$TMP_EXISTING" "$GITEA_DOMAIN"; then
|
||||
log_info "Caddyfile already has a route for ${GITEA_DOMAIN} — preserving existing file"
|
||||
else
|
||||
TLS_BLOCK=" tls ${SSL_CERT_PATH} ${SSL_KEY_PATH}"
|
||||
log_warn "Caddyfile exists but has no explicit route for ${GITEA_DOMAIN}"
|
||||
log_info "Appending managed Gitea route block"
|
||||
{
|
||||
echo
|
||||
echo "${PHASE8_GITEA_ROUTE_BEGIN}"
|
||||
echo "${GITEA_DOMAIN} {"
|
||||
printf '%s\n' "$TLS_BLOCK"
|
||||
echo
|
||||
echo " reverse_proxy ${GITEA_CONTAINER_IP}:3000"
|
||||
echo "}"
|
||||
echo "${PHASE8_GITEA_ROUTE_END}"
|
||||
echo
|
||||
} > "$TMP_ROUTE_BLOCK"
|
||||
|
||||
# Remove a stale managed block (if present), then append refreshed block.
|
||||
sed "/^${PHASE8_GITEA_ROUTE_BEGIN}\$/,/^${PHASE8_GITEA_ROUTE_END}\$/d" "$TMP_EXISTING" > "$TMP_UPDATED"
|
||||
cat "$TMP_UPDATED" "$TMP_ROUTE_BLOCK" > "${TMP_UPDATED}.final"
|
||||
scp_to UNRAID "${TMP_UPDATED}.final" "${CADDY_DATA_PATH}/Caddyfile"
|
||||
log_success "Appended managed Gitea route to existing Caddyfile"
|
||||
CADDYFILE_UPDATED=1
|
||||
fi
|
||||
export TLS_BLOCK
|
||||
|
||||
rm -f "$TMP_EXISTING" "$TMP_UPDATED" "$TMP_ROUTE_BLOCK" "${TMP_UPDATED}.final"
|
||||
else
|
||||
TMPFILE=$(mktemp)
|
||||
|
||||
render_template "${SCRIPT_DIR}/templates/Caddyfile.tpl" "$TMPFILE" \
|
||||
"\${CADDY_DOMAIN} \${GITEA_DOMAIN} \${TLS_BLOCK} \${GITEA_CONTAINER_IP}"
|
||||
scp_to UNRAID "$TMPFILE" "${CADDY_DATA_PATH}/Caddyfile"
|
||||
rm -f "$TMPFILE"
|
||||
log_success "Caddyfile deployed"
|
||||
CADDYFILE_UPDATED=1
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -221,7 +321,14 @@ fi
|
||||
log_step 4 "Starting Caddy container..."
|
||||
CONTAINER_STATUS=$(ssh_exec UNRAID "docker ps --filter name=caddy --format '{{.Status}}'" 2>/dev/null || true)
|
||||
if [[ "$CONTAINER_STATUS" == *"Up"* ]]; then
|
||||
log_info "Caddy container already running — skipping"
|
||||
log_info "Caddy container already running"
|
||||
if [[ "$CADDYFILE_UPDATED" -eq 1 ]]; then
|
||||
log_info "Caddyfile changed — restarting caddy to apply updated config"
|
||||
ssh_exec UNRAID "docker restart caddy >/dev/null"
|
||||
log_success "Caddy container restarted with new config"
|
||||
else
|
||||
log_info "Caddyfile unchanged — restart not required"
|
||||
fi
|
||||
else
|
||||
ssh_exec UNRAID "cd '${CADDY_COMPOSE_DIR}' && docker compose up -d 2>/dev/null || docker-compose up -d"
|
||||
log_success "Caddy container started"
|
||||
@@ -232,9 +339,13 @@ fi
|
||||
# Caddy auto-obtains certs — poll until HTTPS responds.
|
||||
# ---------------------------------------------------------------------------
|
||||
log_step 5 "Waiting for HTTPS (Caddy auto-provisions cert)..."
|
||||
wait_for_http "https://${GITEA_DOMAIN}/api/v1/version" 120
|
||||
|
||||
log_success "HTTPS verified — https://${GITEA_DOMAIN} works"
|
||||
if wait_for_https_public "${GITEA_DOMAIN}" 30; then
|
||||
log_success "HTTPS verified through current domain routing — https://${GITEA_DOMAIN} works"
|
||||
else
|
||||
log_warn "Public-domain routing to Caddy is not ready yet"
|
||||
wait_for_https_via_resolve "${GITEA_DOMAIN}" "${UNRAID_CADDY_IP}" 300
|
||||
log_success "HTTPS verified via direct Caddy path; public routing can be completed later"
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Step 6: Mark GitHub repos as offsite backup only
|
||||
|
||||
Reference in New Issue
Block a user