Docker: socat-Bridge auf richtige Loopback-Familie (IPv4/IPv6) ausrichten
.NET-HttpListener bindet den Prefix "localhost" im Container auf IPv6 ::1, socat verband aber auf 127.0.0.1 -> "Connection refused". Entrypoint startet die App jetzt zuerst, erkennt ob IPv4 oder IPv6 antwortet und richtet socat darauf aus. Kein Eingriff in den App-Code. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,14 +1,36 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Startet die App unveraendert (bindet auf 127.0.0.1:APP_PORT) und leitet externe
|
# Startet die App unveraendert (bindet auf localhost:APP_PORT) und leitet externe
|
||||||
# Verbindungen per socat-Bridge dorthin - so bleibt der App-Code unangetastet.
|
# Verbindungen per socat-Bridge dorthin - so bleibt der App-Code unangetastet.
|
||||||
|
#
|
||||||
|
# HINWEIS: .NET-HttpListener bindet den Prefix "localhost" je nach System auf IPv4
|
||||||
|
# ODER IPv6. Deshalb ermitteln wir zur Laufzeit, welche Loopback-Familie antwortet,
|
||||||
|
# und richten socat darauf aus (sonst "Connection refused").
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
: "${APP_PORT:=8077}"
|
: "${APP_PORT:=8077}"
|
||||||
: "${BRIDGE_PORT:=8080}"
|
: "${BRIDGE_PORT:=8080}"
|
||||||
|
|
||||||
# Bridge im Hintergrund: 0.0.0.0:BRIDGE_PORT -> 127.0.0.1:APP_PORT
|
# App im Hintergrund starten. -NoBrowser: im Container kein Desktop/open.
|
||||||
# (fork = pro Verbindung ein Prozess; reuseaddr = schneller Neustart).
|
pwsh -NoProfile -File /app/Start.ps1 -NoBrowser -Port "${APP_PORT}" &
|
||||||
socat "TCP-LISTEN:${BRIDGE_PORT},fork,reuseaddr" "TCP:127.0.0.1:${APP_PORT}" &
|
APP_PID=$!
|
||||||
|
|
||||||
# App im Vordergrund (Logs -> stdout). -NoBrowser: im Container kein Desktop/open.
|
# Warten bis der Listener antwortet und dabei IPv4 vs. IPv6 erkennen.
|
||||||
exec pwsh -NoProfile -File /app/Start.ps1 -NoBrowser -Port "${APP_PORT}"
|
# Default = IPv6 (haeufigster Fall im Container); IPv4 wird bevorzugt, wenn erreichbar.
|
||||||
|
SOCAT_TARGET="TCP6:[::1]:${APP_PORT}"
|
||||||
|
for i in $(seq 1 30); do
|
||||||
|
if (exec 3<>"/dev/tcp/127.0.0.1/${APP_PORT}") 2>/dev/null; then
|
||||||
|
exec 3>&-; SOCAT_TARGET="TCP4:127.0.0.1:${APP_PORT}"; break
|
||||||
|
fi
|
||||||
|
if (exec 3<>"/dev/tcp/::1/${APP_PORT}") 2>/dev/null; then
|
||||||
|
exec 3>&-; SOCAT_TARGET="TCP6:[::1]:${APP_PORT}"; break
|
||||||
|
fi
|
||||||
|
# App unerwartet beendet? Dann mit deren Exit-Code aussteigen.
|
||||||
|
kill -0 "$APP_PID" 2>/dev/null || { echo "[entrypoint] App-Prozess beendet - Abbruch."; wait "$APP_PID"; exit $?; }
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "[entrypoint] Bridge: 0.0.0.0:${BRIDGE_PORT} -> ${SOCAT_TARGET}"
|
||||||
|
socat "TCP-LISTEN:${BRIDGE_PORT},fork,reuseaddr" "${SOCAT_TARGET}" &
|
||||||
|
|
||||||
|
# Am Leben des App-Prozesses haengen (Container endet, wenn die App endet).
|
||||||
|
wait "$APP_PID"
|
||||||
|
|||||||
Reference in New Issue
Block a user