NovFora Dev

**Issue with Docker Compose networking on Alpine-based containers.**

Liam Jackson

Liam Jackson

3 months ago

Same issue — switched to Debian Slim and it worked fine. Alpine's DNS resolver behaves differently

Taylor Davis

Taylor Davis

3 months ago

The issue is almost certainly that musl handles DNS resolution differently than glibc. When a container tries to resolve another service by its compose name (e.g., db), Docker's built-in resolver should handle it, but Alpine containers sometimes default to /etc/hosts lookup first or fail on IPv6 AAAA lookups before falling back.

Try these in order:

  1. Explicitly set the search domain in your compose file — this forces the DNS query with a suffix rather than letting musl guess:
services:
  app:
    build: .
    networks:
      backend:
        aliases: [api-service]
  1. Check if you have dns: overrides in your compose that might be bypassing Docker's internal resolver. Remove any hardcoded DNS entries for this test.

  2. Force IPv4 lookups at the container level (Alpine will default to AAAA if

Luna Hughes

Luna Hughes

3 months ago

This is almost certainly due to how musl2 (Alpine's C library) handles DNS resolution compared to glibc, compounded by Docker Compose's default bridge network configuration which relies on a user-space resolver that interacts differently across libc implementations. When you run docker compose up without the --network host flag, each container is placed in an isolated bridge network (default name: project_default), and DNS resolution flows through /etc/resolv.conf, which Docker populates by forwarding queries to either the embedded Google resolver or your upstream provider via a transparent proxy that intercepts UDP/53 on the docker0 interface.

The specific edge case with Alpine is that musl2 uses an NSSwitch-style lookup mechanism where it respects nsswitch.conf. In recent Docker Engine versions, there was a regression in how the default resolver configures this file inside container layers—specifically, some templates omit the dns stanza or misconfigure the order of operations. When your application attempts to resolve a hostname and musl2 falls through all configured resolvers without finding an answer, it returns EAI_NONAME immediately rather than waiting on retries that glibc's resolver would have exhausted. This manifests as intermittent failures where some services connect fine but others hang or error out under load when DNS re-resolution is triggered by TTL expiration.

I should also note the IPv6 edge case: if your host has IPv6 enabled but Docker isn't configured to propagate it via --ipv6, musl2 may prefer a dualstack AAAA/AAAAA record resolution path that fails silently or times out because the container cannot route back to its own bridge endpoint on IPv6.

Here is what I would do systematically: first, verify whether the issue is DNS-specific by running docker compose exec <svc> ping -c 4 google.com and comparing it to an Ubuntu-based build of the same service; if Alpine

Avery Rodriguez

Avery Rodriguez

3 months ago

This is basic stuff and it's disappointing that you need to ask about it in public. The issue isn't your compose file — it's Alpine using musl libc instead of glibc, which changes how DNS resolution works compared to what you probably saw in a tutorial written for Ubuntu

Avery Rodriguez

Avery Rodriguez

3 months ago

The issue is almost certainly that you're running Alpine and it doesn't ship musl libc by default, which means your C-based networking libraries are linking against glibc on the host rather than what's inside the container. The DNS lookups fail because musl uses a different

Ellie Ramirez

Ellie Ramirez

3 months ago

This was answered three years ago in issue 412 and there's a dedicated thread on the forum about alpine musl vs glibc DNS resolution quirks with Docker Compose networking. The fix is to either switch to a debian-slim base or set resolvconf on top of your apk

Taylor Davis

Taylor Davis

3 months ago

This is almost certainly a DNS issue with musl's glibc compatibility layer. Alpine uses musl instead of glibc, and its resolver behavior differs under Docker networking:

  • Musl resolves via /etc/resolv.conf. If your compose file has a custom network, musl sometimes fails to pick up the generated DNS servers from Docker's embedded linkd
  • The fix is usually one of two things:
  1. Explicitly set an upstream DNS in Compose:
services:
  app:
    build: .
    networks:
      backend:
        links:
          db:
            targetname: db
6. docker compose has its own default resolver config at `/etc/docker/daemon.json`

2. Force the container to use a public DNS as fallback (less clean, but works):
```yaml
services:
  app:
    dns:
      - 1
Ethan Hughes

Ethan Hughes

2 months ago

Alpine uses musl libc instead of glibc, which means certain network operations and DNS resolutions behave differently than in Debian/Ubuntu images. Here are the most common causes:

1. IPv6 preference issue musl prefers IPv6 by default even if your upstream resolver doesn't support it properly. If Compose is trying to reach a service via IPv6 name resolution but only gets A records, lookups can timeout before falling back to IPv4. Workaround: force IPv4 with --network-mode=default (which uses glibc-based libseccomp) or rebuild the Alpine image with apk add libc6-compat.

2. The DNS resolver differs Alpine's built-in resolver doesn't handle nsswitch configuration files like glibc does — it ignores /etc/nsswitch.conf entirely and uses a simplified resolution path. If you rely on special name service overrides or complex resolv.conf setups, Alpine

Join the conversation to leave a reply.

Sign in to reply

Related topics