Websockets support for OpenAI Realtime Twilio streams

Can the hobby/pay as you go level support the websockets needed for OpenAI Realtime Twilio streams? If so, What are the ideal port settings for fly.io?

I’m using Node with fastify on an implementation built from this base:

It works splendidly on my PC. It works ‘mostly’ on Railway with some occasional drops. , but I suspect there are some restrictions there for websockets. I’ve seen good things about websockets support at fly.io, but the same code here doesn’t seem to use the websockets with the setup that I’ve tried. (below). Advice?


[build]
  dockerfile = "Dockerfile"

[http_service]
  internal_port = 8080
  force_https = true
  auto_stop_machines = true
  auto_start_machines = true
  min_machines_running = 1
  processes = ["app"]
  protocol = "tcp"
  
  [[http_service.checks]]
    grace_period = "10s"
    interval = "30s"
    method = "GET"
    path = "/"
    timeout = "5s"

  [http_service.concurrency]
    type = "connections"
    hard_limit = 550
    soft_limit = 500

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

###########And Docker:

# Use a base image with a newer GLIBC version, like Debian Bullseye
FROM node:22-bullseye-slim

# Set working directory
WORKDIR /app

# Copy package files
COPY package.json package-lock.json ./

# Install dependencies with npm 10.9.2 (already included in node:22)
RUN npm ci

# Copy the rest of the app
COPY . .

# Set environment to production
ENV NODE_ENV=production

# Expose the port Fly.io typically uses (8080), though the app will use PORT env variable
EXPOSE 8080

# Start the app
CMD ["npm", "start"]

Hi… Pay as You Go isn’t actually a hobby plan or inferior level of any kind; all creaturescustomers use it, great or small.†

This syntax is invalid, :taruggiz_spiral:, although that’s not necessarily the cause of your problem. I’d suggest removing it and retrying, nevertheless.

(The http_service stanza gives you HTTP on port 80 and HTTPS on port 443 inherently.)


†Except for some accounts created before October 2024.

@Michael7S - if you can, format your config files in this forum using code Markdown, like so:

```
Code goes here
```

Three backticks in a line are a “code gate” that makes this sort of text much more readable.

1 Like

Thank you. Done. Yeah it was definitely shouting there. :smiley:

If it helps others, this configuration seemed to help and got the streams running .

[env]
  NODE_ENV = "production"
  PORT = "8080"  # Ensure server.js binds to this port
  HOST = "0.0.0.0"  # Bind to all interfaces
  REDIS_URL = "redis://default:blablabla.upstash.io:6379"

[build]
  dockerfile = "Dockerfile"


# HTTP and WebSocket service configuration
[http_service]
  internal_port = 8080  # Port  app listens on (matches config.PORT)
  force_https = true  # Enforce HTTPS/WSS for Twilio
  auto_stop_machines = false  # Keep machines running for WebSocket persistence
  auto_start_machines = true  # Start machines on demand
  processes = ["app"]

  # Handlers for HTTP and WebSocket
  [[http_service.handlers]]
    handlers = ["http", "websocket"]

  # Health checks for HTTP endpoints (corrected to array format)
  [[http_service.checks]]
    interval = "10s"
    timeout = "2s"
    grace_period = "5s"
    method = "GET"
    path = "/"  # Changed to root endpoint, as /health may not exist
    protocol = "http"


# Outbound connections  
[[services]]
  protocol = "tcp"
  internal_port = 8080
  processes = ["app"]

  [[services.ports]]
    port = 443
    handlers = ["tls", "http"]  # HTTPS/WSS for Twilio

  [[services.ports]]
    port = 80
    handlers = ["http"]  # Redirect to HTTPS

    # Machine configuration
    [[vm]]
      memory = "512mb"   
      cpu_kind = "shared"
      cpus = 1
      scale = 1  # Single machine

I’ve more work to do since a two-machine setup isn’t handled well by assumptions made in my script. But at least I’m running now!

1 Like

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