Hey everyone,
I’ve deployed a NestJS monorepo microservice architecture on Fly.io — the setup includes an API Gateway (public app, HTTPS) and several private services (users, products, etc.) communicating over TCP.
Each private service uses Flycast for internal networking, and everything appears reachable:
- I can ping the private apps from the API Gateway container.
- DNS resolution works (
<service>.internalresolves correctly). - Logs confirm the gateway connects to the right internal addresses.
However, when I trigger routes (like /products/all) that should call the products service via TCP, I get:
2025-10-22T13:37:08.051 app[78432e7b401e48] jnb [info] [Nest] 642 - 10/22/2025, 1:37:08 PM LOG [API] App listening on port: 4000
2025-10-22T13:37:08.535 proxy[78432e7b401e48] jnb [info] machine became reachable in 4.184513031s
2025-10-22T13:37:11.761 app[78432e7b401e48] jnb [info] [Nest] 642 - 10/22/2025, 1:37:11 PM ERROR [ClientTCP] Error: read ECONNRESET
2025-10-22T13:37:38.572 app[78432e7b401e48] jnb [info] [Nest] 642 - 10/22/2025, 1:37:38 PM LOG [PRODUCT's controller] TimeoutError: Timeout has occurred
2025-10-22T13:37:38.578 app[78432e7b401e48] jnb [info] [Nest] 642 - 10/22/2025, 1:37:38 PM ERROR [ExceptionsHandler] Timeout has occurred
2025-10-22T13:37:38.579 app[78432e7b401e48] jnb [info] Error
2025-10-22T13:37:38.579 app[78432e7b401e48] jnb [info] at _super (/usr/src/app/node_modules/rxjs/dist/cjs/internal/util/createErrorClass.js:7:26)
2025-10-22T13:37:38.579 app[78432e7b401e48] jnb [info] at new TimeoutErrorImpl (/usr/src/app/node_modules/rxjs/dist/cjs/internal/operators/timeout.js:14:9)
2025-10-22T13:37:38.579 app[78432e7b401e48] jnb [info] at timeoutErrorFactory (/usr/src/app/node_modules/rxjs/dist/cjs/internal/operators/timeout.js:61:11)
2025-10-22T13:37:38.579 app[78432e7b401e48] jnb [info] at /usr/src/app/node_modules/rxjs/dist/cjs/internal/operators/timeout.js:34:43
It’s strange because the services seem reachable but not responding over TCP at runtime.
Here’s my setup summary:
- Monorepo using
@nestjs/microserviceswithTransport.TCP - Each service runs in its own Fly.io app
hostfor TCP clients is set to the Flycast address (users.internal)- Ports are open in
fly.toml - Works perfectly in local Docker Compose
Has anyone run into this behavior on Fly.io?
Is there something specific about Flycast or Fly’s internal networking that prevents stable TCP connections between apps? Any config tweaks, port mapping tricks, or deployment strategies that worked for you?
Would really appreciate some guidance or shared configs if you’ve solved something similar!