a month ago
Flask/Gunicorn container builds and boots successfully, and logs confirm:
>>> Booting Gunicorn
MODULE=app:app PORT=8080 WORKERS=2 THREADS=4
[INFO] Listening at: http://0.0.0.0:8080
However, the public domain (https://novetra-api-1-production.up.railway.app) always returns 502 Bad Gateway.
/healthzendpoint returns{"status":"ok"}when tested inside the container (curl localhost:$PORT/healthz), but the external URL 502s.Healthcheck path in settings:
/healthz.Dockerfile uses
CMD ["bash", "/app/start.sh"].Custom Start Command:
bash /app/start.sh.Domain + Public Networking attached and verified.
Gunicorn 21.2.0 shows as healthy and listening before the edge fails.
Seems like the internal service is healthy but not reachable by Railway’s edge proxy.
Could you please verify routing and domain attachment for this service?
7 Replies
a month ago
Hey there! We've found the following might help you get unblocked faster:
If you find the answer from one of these, please let us know by solving the thread!
a month ago
This thread has been marked as public for community involvement, as it does not contain any sensitive or personal information. Any further activity in this thread will be visible to everyone.
Status changed to Open brody • about 1 month ago
a month ago
Is your start.sh binding to Railway's dynamic port? i.e. --bind "0.0.0.0:${PORT}" or is it hardcoded to 8080?
a month ago
Reply with this:
Yes —
start.shbinds to Railway’s dynamic port.
Here’s the exact line:PORT="${PORT:-8000}" exec gunicorn -k gthread -w "$WORKERS" --threads "$THREADS" \ -b "0.0.0.0:${PORT}" "$MODULE" --timeout 120Deploy logs show it picking up
$PORTcorrectly:MODULE=app:app PORT=8080 … [INFO] Listening at: http://0.0.0.0:8080The Flask fallback for local runs also uses
int(os.environ.get("PORT", 8000)).From inside the container:
curl localhost:$PORT/healthz -> {"status":"ok"}But the public domain still returns 502. Since the app is listening on the dynamic port and
/healthzis 200 internally, it looks like an edge/domain routing issue. Could you check the domain attachment/routing to the active replica fornovetra-api-1(production)? I can provide recent request IDs from HTTP logs if helpful.
novetra
Reply with this:Yes — start.sh binds to Railway’s dynamic port.Here’s the exact line:PORT="${PORT:-8000}" exec gunicorn -k gthread -w "$WORKERS" --threads "$THREADS" \ -b "0.0.0.0:${PORT}" "$MODULE" --timeout 120Deploy logs show it picking up $PORT correctly:MODULE=app:app PORT=8080 … [INFO] Listening at: http://0.0.0.0:8080The Flask fallback for local runs also uses int(os.environ.get("PORT", 8000)).From inside the container:curl localhost:$PORT/healthz -> {"status":"ok"}But the public domain still returns 502. Since the app is listening on the dynamic port and /healthz is 200 internally, it looks like an edge/domain routing issue. Could you check the domain attachment/routing to the active replica for novetra-api-1 (production)? I can provide recent request IDs from HTTP logs if helpful.
a month ago
For your domain, in the Service -> Settings -> Public Networking, is it showing 8080?
Attachments
a month ago
Not 8080 — in Settings → Public Networking the domain card shows Port 8010 (Metal Edge).
But my container picks up Railway’s $PORT=8080 (see logs):
MODULE=app:app PORT=8080 …
[INFO] Listening at: http://0.0.0.0:8080
So the edge is targeting 8010 while the app is listening on 8080. I’ve already:
set start command to
bash /app/start.shcleared pre-deploy command
redeployed the service
removed & re-added the Railway domain
novetra
Not 8080 — in Settings → Public Networking the domain card shows Port 8010 (Metal Edge).But my container picks up Railway’s $PORT=8080 (see logs):MODULE=app:app PORT=8080 … [INFO] Listening at: http://0.0.0.0:8080So the edge is targeting 8010 while the app is listening on 8080. I’ve already:set start command to bash /app/start.shcleared pre-deploy commandredeployed the serviceremoved & re-added the Railway domain
a month ago
Status changed to Solved brody • about 1 month ago


