FAQ | This is a LIVE service | Changelog

Docker api-gateway-emulator container unhealthy when localhost resolves to ::1

Description

While trying to spin up a project that is using the Web Application Boilerplate the webapp container fails to start as it depends on the api-gateway-emulator container to be healthy. The HEALTHCHECK specified in the docker-compose.yml file is:

    healthcheck:
      test: ["CMD", "wget", "--spider", "http://localhost:9001/proxy/status"]
      interval: 10s

Which is actually the same as the HEALTHCHECK specified in the container itself (https://gitlab.developers.cam.ac.uk/uis/devops/api/api-gateway-emulator/-/blob/main/Dockerfile?ref_type=heads#L27).

Running the command of the HEALTHCHECK myself while being in the container shows:

/usr/src/app # wget --spider http://localhost:9001/proxy/status
Connecting to localhost:9001 ([::1]:9001)
wget: can't connect to remote host: Connection refused

Same happens in the base container of the api-gateway-emulator:

% docker run registry.gitlab.developers.cam.ac.uk/uis/devops/infra/dockerimages/django:4.2-py3.11-alpine wget http://localhost 
Connecting to localhost ([::1]:80)
wget: can't connect to remote host: Connection refused

What looks like happens is that localhost resolves to ::1 instead of 127.0.0.1. Explicitly querying 127.0.0.1 does work:

/usr/src/app # wget --spider http://127.0.0.1:9001/proxy/status
Connecting to 127.0.0.1:9001 (127.0.0.1:9001)
remote file exists

The api-gateway-emulator explicitly binds to all IPV4 interfaces (0.0.0.0):

https://gitlab.developers.cam.ac.uk/uis/devops/api/api-gateway-emulator/-/blob/main/api_gateway_emulator/init.py?ref_type=heads#L29

Solution

I think there are multiple ways to solve this issue:

  1. Doing the healthcheck against 127.0.0.1 or 0.0.0.0 instead of localhost
  2. Disabling ipv6 in the container (--sysctl=net.ipv6.conf.all.disable_ipv6=1)
  3. Bind uvicorn to :: instead of 0.0.0.0 in api-gateway-emulator

If we would go for option 1, then this also needs to be applied to the Dockerfile in the api-gateway-emulator. We could then also argue we would remove the HEALTHCHECK from the docker-compose.yml file in this repository as it will be the same as in the Dockerfile.

Extra information

I am running Docker Desktop 4.32.0 on macOS Sonoma 14.5. I found a GitHub issue that reports this happens since a certain version of Docker Desktop on macOS:

https://github.com/docker/for-mac/issues/7269