app + sockets.io server configuration

Hi there,

I’m trying to set up a react app running on 8080 and a sockets.io server on 3000 on one machine. Locally it works but not on fly. Here is the docker setup (I can ssh into the machine, both app & servers are running).

FROM node:current-alpine
ENV PORT=8080
RUN npm install -g pnpm

WORKDIR /app

COPY . .

RUN pnpm install
RUN pnpm build

WORKDIR /app/server
RUN pnpm install

CMD ["sh", "-c", "cd /app/server && pnpm start & cd /app && pnpm start"]

And here’s fly.toml:


app = 'exit'

[[services]]
protocol = "tcp"
internal_port = 8080
processes = ["app"]

[services.concurrency]
hard_limit = 25
soft_limit = 20

[[services.ports]]
port = 80
handlers = ['http']
force_https = true

[[services.ports]]
port = 443
handlers = ['tls', 'http']

# SERVER
[[services]]
protocol = "tcp"
internal_port = 3000
processes = ["app"]

[[services.ports]]
port = 3000

[[services.http_options.response_headers]]
path = "/socket.io*"
destination_port = 3000

[[vm]]
memory = '1gb'
cpu_kind = 'shared'
cpus = 1

[processes]
app = "sh -c \"cd /app/server && pnpm start & cd /app && pnpm start\""

When I go to the url, it loads the app.
When I go to /socket.io, it gives me a blank screen (good, because it means the server is handling it rather than the app)
But when the app is trying to access socket.io, I get this:

index-DZLjYw8l.js:1 WebSocket connection to 'wss://___.fly.dev/socket.io/?EIO=4&transport=websocket' failed: 

Which I take to mean that “wss” is not supported by my setup. In the fly logs, I get this:

2025-03-31T18:03:48.607 app[9185571a732028] ord [info] HTTP 3/31/2025 6:03:48 PM 172.16.27.66 GET /socket.io/?EIO=4&transport=websocket

2025-03-31T18:03:48.607 app[9185571a732028] ord [info] HTTP 3/31/2025 6:03:48 PM 172.16.27.66 Returned 200 in 1 ms

Any ideas on what I have misconfigured?
Thanks :folded_hands:

Have a look at the Network tab in your developer tools; I wonder if you are getting a CORS error because the ports are different. Your browser might be more forgiving of this on localhost because it realises that’s local work in progress.

No CORS errors, but I found something out. In case A, “/” works but it tries to render “/socket.io/", and in case B "/socket.io/” works, but it also tries to render “/” which gives error.

Case A:

[processes]
app = "sh -c \"cd /app && pnpm start\""
server = "sh -c \"cd /app/server && pnpm start\""

[[vm]]
memory = '1gb'
cpu_kind = 'shared'
cpus = 1

[[services]]
http_checks = []
internal_port = 8080
protocol = "tcp"
processes = ["app"]

[[services.ports]]
port = 80
handlers = ["http"]
force_https = true

[[services.ports]]
port = 443
handlers = ["tls", "http"]

[[services.http_options.routes]]
path = "/*"
protocol = "http"
match = "path"
exclude = ["/socket.io/*"]

[[services.http_options.routes]]
path = "/socket.io/*"
protocol = "http"
internal_port = 3000
processes = ["server"]
websocket = true

Case B:

[processes]
app = "sh -c \"cd /app && pnpm start\""
server = "sh -c \"cd /app/server && pnpm start\""

[[vm]]
memory = '1gb'
cpu_kind = 'shared'
cpus = 1

# APP ##########################################
[[services]]
http_checks = []
internal_port = 8080
protocol = "tcp"
processes = ["app"]

[services.concurrency]
hard_limit = 100
soft_limit = 80

[[services.ports]]
port = 80
handlers = ["http"]
force_https = true

[[services.ports]]
port = 443
handlers = ["tls", "http"]

[[services.http_options.routes]]
path = "/*"
protocol = "http"
match = "path"
exclude = ["/socket.io/*"]

# SERVER ##########################################
[[services]]
internal_port = 3000
protocol = "tcp"
processes = ["server"]

[[services.ports]]
port = 80
handlers = ["http"]
force_https = true

[[services.ports]]
port = 443
handlers = ["tls", "http"]

[[services.http_options.routes]]
path = "/socket.io/*"
protocol = "http"
websocket = true

Any ideas on how I can get the app to handle /* and server /socket.io/*?
Thanks!

1 Like

I am not familiar with that syntax. Are you trying to route to one or another machine based on URL path, such that one machine handles HTTP and one handles websockets?

If so, I wonder if your app would only work on Fly, and not on your local machine. I’d guess you’d then find it harder to work on it. Thus, I would be inclined to suggest that you put a load balancer container in your dev stack, so you can accept all traffic on one port (e.g. 8080) and it routes intelligently to your React or Sockets apps. Traefik can do this, and I would guess that it would be very well suited to running on Fly.

Thanks for your suggestion. I played around with traefik for a bit, but then took a step back and ended going with deploying two separate machines. It’ll scale better that way, and all the trouble of setting things up on one machine was a temporary measure anyhow. Thanks again!

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.