[GH-ISSUE #180] [Docs ] - API 502 Bad Gateway - Podman Compatibility - Windows #2543

Open
opened 2026-06-07 15:03:03 -05:00 by GiteaMirror · 0 comments
Owner

Originally created by @nidorx on GitHub (Jun 6, 2026).
Original GitHub issue: https://github.com/reconurge/flowsint/issues/180

Problem

When running docker-compose.prod.yml with Podman Compose, the frontend nginx fails to resolve the api service hostname, resulting in 502 Bad Gateway on all /api/ requests.

Root cause

The nginx config inside flowsint-app uses Docker's embedded DNS resolver:

resolver 127.0.0.11 valid=10s;

127.0.0.11 is Docker Engine specific - it's a hardcoded IP where Docker runs its internal DNS server inside each container. Podman does not use this address. Instead, Podman's DNS resolver runs on the network gateway (typically 10.89.0.1), which is written into the container's /etc/resolv.conf.

Because 127.0.0.11:53 has nothing listening in a Podman container, DNS resolution fails:

send() failed (111: Connection refused) while resolving, resolver: 127.0.0.11:53
api could not be resolved (110: Operation timed out)

Fix

1. Remove the Docker-specific resolver from nginx.conf

In flowsint-app/nginx.conf, replace the resolver + variable pattern with a direct proxy_pass:

  location /api/ {
-     resolver 127.0.0.11 valid=10s;
-     set $api_upstream http://api:5001;
-     proxy_pass $api_upstream;
+     proxy_pass http://api:5001;
      proxy_http_version 1.1;
      proxy_set_header Host $host;
      ...
  }

This makes nginx resolve api using the system's DNS configuration (/etc/resolv.conf), which Podman sets up correctly.

2. Mount the local nginx.conf into the container

The production compose file pulls a pre-built image from GHCR:

app:
  image: ghcr.io/reconurge/flowsint-app:${FLOWSINT_VERSION:-latest}

Since there is no build: section, the container runs the baked-in nginx.conf from the registry image (which still has 127.0.0.11). Mount the corrected local config as a volume:

app:
  image: ghcr.io/reconurge/flowsint-app:${FLOWSINT_VERSION:-latest}
  volumes:
    - ./flowsint-app/nginx.conf:/etc/nginx/nginx.conf:ro

Then

podman compose -f docker-compose.prod.yml up -d --build --force-recreate

Docker vs Podman DNS comparison

Runtime Resolver IP Source
Docker Engine 127.0.0.11 Hardcoded in Docker daemon
Podman Gateway IP (e.g. 10.89.0.1) Written to /etc/resolv.conf

By removing the hardcoded 127.0.0.11 and letting nginx use the system resolver, the config works on both runtimes.

Trade-off

Using proxy_pass http://api:5001 directly (without resolver + set) means nginx resolves the api hostname once at startup. If the api container is recreated with a different IP, the nginx container must be restarted to pick up the new address. For typical compose deployments this is acceptable.

Originally created by @nidorx on GitHub (Jun 6, 2026). Original GitHub issue: https://github.com/reconurge/flowsint/issues/180 ## Problem When running `docker-compose.prod.yml` with [**Podman Compose**](https://podman.io/), the frontend nginx fails to resolve the `api` service hostname, resulting in `502 Bad Gateway` on all `/api/` requests. ### Root cause The nginx config inside `flowsint-app` uses Docker's embedded DNS resolver: ```nginx resolver 127.0.0.11 valid=10s; ``` `127.0.0.11` is **Docker Engine specific** - it's a hardcoded IP where Docker runs its internal DNS server inside each container. Podman does not use this address. Instead, Podman's DNS resolver runs on the network gateway (typically `10.89.0.1`), which is written into the container's `/etc/resolv.conf`. Because `127.0.0.11:53` has nothing listening in a Podman container, DNS resolution fails: ``` send() failed (111: Connection refused) while resolving, resolver: 127.0.0.11:53 api could not be resolved (110: Operation timed out) ``` ## Fix ### 1. Remove the Docker-specific resolver from `nginx.conf` In `flowsint-app/nginx.conf`, replace the resolver + variable pattern with a direct `proxy_pass`: ```diff location /api/ { - resolver 127.0.0.11 valid=10s; - set $api_upstream http://api:5001; - proxy_pass $api_upstream; + proxy_pass http://api:5001; proxy_http_version 1.1; proxy_set_header Host $host; ... } ``` This makes nginx resolve `api` using the system's DNS configuration (`/etc/resolv.conf`), which Podman sets up correctly. ### 2. Mount the local `nginx.conf` into the container The production compose file pulls a pre-built image from GHCR: ```yaml app: image: ghcr.io/reconurge/flowsint-app:${FLOWSINT_VERSION:-latest} ``` Since there is no `build:` section, the container runs the baked-in `nginx.conf` from the registry image (which still has `127.0.0.11`). Mount the corrected local config as a volume: ```yaml app: image: ghcr.io/reconurge/flowsint-app:${FLOWSINT_VERSION:-latest} volumes: - ./flowsint-app/nginx.conf:/etc/nginx/nginx.conf:ro ``` Then ``` podman compose -f docker-compose.prod.yml up -d --build --force-recreate ``` ### Docker vs Podman DNS comparison | Runtime | Resolver IP | Source | |----------------|-----------------|----------------------------------| | Docker Engine | `127.0.0.11` | Hardcoded in Docker daemon | | Podman | Gateway IP (e.g. `10.89.0.1`) | Written to `/etc/resolv.conf` | By removing the hardcoded `127.0.0.11` and letting nginx use the system resolver, the config works on both runtimes. ### Trade-off Using `proxy_pass http://api:5001` directly (without `resolver` + `set`) means nginx resolves the `api` hostname once at startup. If the `api` container is recreated with a different IP, the nginx container must be restarted to pick up the new address. For typical compose deployments this is acceptable.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/flowsint#2543