The cutsolver-frontend container gets marked as unhealthy by Docker, even though the application is running normally and serves traffic successfully.
Why this happens:
-
The Dockerfile currently defines the health check using localhost:
HEALTHCHECK --interval=1m --timeout=5s CMD wget -q --spider http://localhost:80/ || exit 1
-
Inside the Alpine/Nginx container, the /etc/hosts file maps localhost to both IPv4 127.0.0.1 and IPv6 ::1.
-
Alpine's wget resolves localhost to ::1 (IPv6) first and attempts to connect to [::1]:80.
-
Since the default Nginx configuration inside the container only listens on IPv4 (0.0.0.0:80) and does not listen on IPv6 ([::]:80), the connection is refused, resulting in:
Connecting to localhost:80 ([::1]:80)
wget: can't connect to remote host: Connection refused
Solution:
Change the health check target in the Dockerfile to explicitly use the IPv4 loopback address (127.0.0.1), where Nginx is listening.
-HEALTHCHECK --interval=1m --timeout=5s CMD wget -q --spider http://localhost:80/ || exit 1
+HEALTHCHECK --interval=1m --timeout=5s CMD wget -q --spider http://127.0.0.1:80/ || exit 1
The
cutsolver-frontendcontainer gets marked asunhealthyby Docker, even though the application is running normally and serves traffic successfully.Why this happens:
The
Dockerfilecurrently defines the health check usinglocalhost:HEALTHCHECK --interval=1m --timeout=5s CMD wget -q --spider http://localhost:80/ || exit 1Inside the Alpine/Nginx container, the
/etc/hostsfile mapslocalhostto both IPv4127.0.0.1and IPv6::1.Alpine's
wgetresolveslocalhostto::1(IPv6) first and attempts to connect to[::1]:80.Since the default Nginx configuration inside the container only listens on IPv4 (
0.0.0.0:80) and does not listen on IPv6 ([::]:80), the connection is refused, resulting in:Connecting to localhost:80 ([::1]:80)wget: can't connect to remote host: Connection refusedSolution:
Change the health check target in the
Dockerfileto explicitly use the IPv4 loopback address (127.0.0.1), where Nginx is listening.