Dokploy / Dokploy/dokploy

Title: Next.js standalone on Compose + domain: Docker-injected HOSTNAME makes the app bind only ONE of the two attached networks, chosen at random → intermittent, non-self-healing 502 after deploy

Open
#5,074 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug needs-triage🔍
Dominant language
TypeScript
Stars
37.4k
Forks
3k
Avg merge
1d 3h
Merged PRs (30d)
73

Description

To Reproduce

Human Slop

I would like to say I am loving your product and this is my first issue I do for any open source system; I have used it to solve a problem in my company and it is going well.

Second of all, I apologize for the AI slop coming after you, so I will explain it in human words; though the slop isn't bad at all. Basically, there is an app used by one of the team that basically continuously failed in a weird way. It was a compose application and the containers would build, Traefik dashboard says it's connected, everything looks dandy, but I always get Bad Gateway. This was very frustrating, since the application doesn't deterministically fail, but it fails sometimes and sometimes it doesn't, so I was super confused.

The issue was related to you guys' decision to keep both the dokploy network and the default compose network. What happened was, one of the applications was using NextJS, NextJS was asking for process.env.HOSTNAME. Docker would resolve that to the container name. After that, Node would go and try to find an IP address for the container in /etc/hosts and find both addresses, the one from dokploy network and the default compose network and it would choose one of them, and therefore, non-deterministic failure.

AI SLOP:

To Reproduce

  1. Any Next.js app built with output: "standalone", in a Dockerfile that does not set ENV HOSTNAME (many guides omit
    it), deployed as a Docker Compose service.
  2. Attach a domain to the service. Dokploy attaches the service to both dokploy-network and the project's default
    network (addDokployNetworkToService, the #3562 fix), and routes Traefik to the dokploy-network IP.
  3. Deploy repeatedly. Some deploys serve 200; others return 502 permanently (never self-heals) until the next deploy
    re-rolls it.

Mechanism (each step independently verified)

  1. Docker injects HOSTNAME= as a real env var: docker run --rm node:22-slim printenv HOSTNAME → prints the id.
  2. Next's generated standalone server.js binds it: const hostname = process.env.HOSTNAME || '0.0.0.0'
    (next/dist/build/utils.js). So in Docker it calls listen(PORT, "") — not 0.0.0.0.
  3. On a dual-network container, /etc/hosts contains two entries for the container's own hostname (one per network). Node's dns.lookup returns one address:

172.20.0.2 a9ee63ee8c33
172.21.0.2 a9ee63ee8c33
dns.lookup(HOSTNAME, {all:true}) → both; plain lookup → one

  1. So each new container binds exactly one interface, effectively at random. If the pick is the dokploy-network IP → site works. If it's the default-network IP → Traefik dials the dokploy-network IP and gets connection refused → 502 forever. Traefik's API meanwhile shows router enabled and the server UP, and the deployment is done — nothing looks wrong anywhere.

Live-incident evidence

  • Traefik service backend IP exactly matched the container's dokploy-network IP — still 502.
  • From a neighbor container on dokploy-network: </dev/tcp//3001 → connection refused (an RST, so packets were
    delivered — not an overlay/dataplane fault).
  • Inside the failing container: </dev/tcp/127.0.0.1/3001 → also refused, while the process was healthy and serving on
    the other network's interface.
  • Redeploying "fixes" it only by re-rolling the bind; we measured one incident of 1 real build + 8 blind redeploys
    before it landed.

Current vs. Expected behavior

Current: silent, intermittent, permanent 502 with all dashboards green. Expected: at minimum a docs note; ideally a post-deploy reachability probe of the domain target (:) surfacing "domain target unreachable" instead of a silent 502.

Current vs. Expected behavior

Current vs. Expected behavior

Current: silent, intermittent, permanent 502 with all dashboards green.
Expected: at minimum a docs note; ideally a post-deploy reachability probe of the domain target (:) surfacing "domain target unreachable" instead of a silent 502.

Environment: Dokploy v0.29.13, Docker Compose (git provider), same server as Dokploy, Traefik v3, Next.js 16 standalone, node:22-slim base on a Ubuntu Box.

Workaround: ENV HOSTNAME="0.0.0.0" in the Dockerfile runner stage (the official Next.js example Dockerfile sets this). Fixed it deterministically for us.

Related: #4807 (same dual-network attachment from #3562, complementary Traefik-side failure mode), #3945 (same symptom, mechanism unidentified — some reports there may be this), #3562 (origin of the dual attach).

Provide environment information
Environment: Dokploy v0.29.13, Docker Compose (git provider), same server as Dokploy, Traefik v3, Next.js 16 standalone, node:22-slim base on a Ubuntu Box.
Which area(s) are affected? (Select all that apply)

Docker Compose, Traefik

Are you deploying the applications where Dokploy is installed or on a remote server?

Same server where Dokploy is installed

Additional context

I never looked at your guys' code, but I am down to try to fix it.

Will you send a PR to fix it?

Maybe, need help

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the Compose network attachment entry point named addDokployNetworkToService and trace how deployed services are exposed through Traefik. Reproduce the dual-network Next.js standalone case, then determine whether the change should be documentation or a post-deploy domain-target reachability check. Done means the failure is surfaced clearly rather than remaining a silent 502.

Written by the indexing model from the issue text.

Assessment

Tech stack
docker, docker-compose, nextjs, typescript
Domain
devops, infrastructure
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.