From a288179954503d53771d286dfde907158a868868 Mon Sep 17 00:00:00 2001 From: Marco Sadjadi Date: Thu, 21 May 2026 18:07:01 +0200 Subject: [PATCH] fix(docker): healthcheck must hit 127.0.0.1, not localhost The servers bind IPv4 (0.0.0.0) only. busybox wget resolves `localhost` to ::1 first and does not fall back to IPv4, so the healthcheck failed with "connection refused" and the container showed as unhealthy while serving fine. Verified on the production api container. Co-Authored-By: Claude Opus 4.7 (1M context) --- apps/api/Dockerfile | 4 +++- apps/runner-template/Dockerfile | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/apps/api/Dockerfile b/apps/api/Dockerfile index d55f9d9..18985d9 100644 --- a/apps/api/Dockerfile +++ b/apps/api/Dockerfile @@ -28,6 +28,8 @@ ENV NODE_ENV=production COPY . . WORKDIR /app/apps/api EXPOSE 4000 +# Use 127.0.0.1, not localhost: the server binds IPv4 only, and busybox wget +# resolves localhost to ::1 first — which would refuse and fail the check. HEALTHCHECK --interval=20s --timeout=4s --start-period=20s --retries=3 \ - CMD wget -qO- http://localhost:4000/health || exit 1 + CMD wget -qO- http://127.0.0.1:4000/health || exit 1 CMD ["pnpm", "start"] diff --git a/apps/runner-template/Dockerfile b/apps/runner-template/Dockerfile index ee9d823..cf40407 100644 --- a/apps/runner-template/Dockerfile +++ b/apps/runner-template/Dockerfile @@ -10,6 +10,8 @@ COPY --from=deps /app/node_modules ./node_modules COPY package.json tsconfig.json ./ COPY src ./src EXPOSE 3000 +# 127.0.0.1, not localhost: busybox wget resolves localhost to ::1 first and +# the server binds IPv4 only, so a localhost check would wrongly fail. HEALTHCHECK --interval=15s --timeout=3s --start-period=10s --retries=3 \ - CMD wget -qO- http://localhost:3000/health || exit 1 + CMD wget -qO- http://127.0.0.1:3000/health || exit 1 CMD ["npx", "tsx", "src/server.ts"]