How Coolify maps public ports to the app container and common misconfiguration symptoms.
This project’s app listens on port 3000 inside the container (you can see it in logs as 0.0.0.0:3000).
When you browse the site, your browser does not connect to the container directly. It connects to Coolify’s proxy (Traefik/Caddy), and the proxy forwards to the container.
https://... (or 80 for http://...)flowchart LR U[Your Browser<br/>https://omnidev.example.com] -->|HTTPS :443| P[Coolify Proxy<br/>Traefik / Caddy<br/>listens on :443] P -->|HTTP :3000 (internal Docker network)| A[app container<br/>Next.js server<br/>listens on :3000] A --> P P --> U
502 Bad Gateway means the proxy could not connect to the upstream app.
Typical reasons:
80, but your app is on 3000)From the Coolify host, you tested:
http://<container>:3000/api/health workshttp://<container>:80/api/health is refusedThat strongly indicates the proxy was trying port 80 instead of 3000.
When Coolify lets you set a domain like:
https://omnidev.example.com:3000
it means:
“When proxy receives requests for this domain, forward them to port 3000 inside the container.”
It does NOT mean your users should type :3000 in their browser.
flowchart LR
U[Browser] -->|HTTPS :443| P[Proxy]
P -->|needs correct upstream port| D{Which container port<br/>should proxy use?}
D -->|wrong guess| W[:80] -->|connection refused| E[502 Bad Gateway]
D -->|explicit in Coolify domain<br/>:3000| OK[:3000] --> A[app :3000 OK]
https://omnidev.example.com:3000
https://omnidev.example.com
:3000 here (this is what users see in the browser)expose: ['3000']
ports: ['3000:3000']
This project’s recommended setup is to use remote MCP servers (outbound HTTPS).