Colyseus and Node.js hosting

Host Colyseus and Node.js game servers on Gameye

Colyseus rooms, .io games and other browser multiplayer games on dedicated servers, one session per match.

Colyseus Node.js and ws No SDK

How do I host a Colyseus or Node.js game server on Gameye?

  1. Write an authoritative server with Colyseus or plain Node.js and ws that serves HTTP and the WebSocket upgrade on one TCP port.
  2. Package it as a Linux container and push it to Docker Hub or GitHub Container Registry.
  3. Create a Gameye application for the image with that port registered as TCP.
  4. When your matchmaker forms a match, start a Gameye session through the Session API and send the players its address.
  5. Exit the process when the match ends. That ends the session.

Browser pages served over https need a secure WebSocket, so plan for TLS early (see below).


Colyseus on Gameye

Colyseus gives you rooms, matchmaking hooks and schema-based state sync. Its dedicated-process deployment maps directly onto Gameye: each match is one Colyseus process in its own Gameye session, on a dedicated server in the region you choose. On Gameye, run one Colyseus process per match in its own session, and exit the process when the room is disposed. The port, container and TLS rules on this page apply unchanged.


A plain Node.js server: one match per process

Each Gameye session runs one container, and each container runs one match. The server is the authority: clients send inputs, the server simulates on a fixed tick and broadcasts the state. Bind 0.0.0.0, authenticate each join with a token your backend minted, and exit with code 0 when the match ends or when Gameye sends SIGTERM.

JavaScript
// server.js: one match per process
import { WebSocketServer } from "ws";
import { createServer } from "http";

const PORT = Number(process.env.GAME_PORT ?? 8080);
const TICK_HZ = 30;

const httpd = createServer((req, res) => { res.writeHead(200); res.end("ok"); });
const wss = new WebSocketServer({ server: httpd });

wss.on("connection", (ws) => {
  const playerId = authenticate(ws);   // check a join token your backend minted
  if (!playerId) return ws.close(4001);
  ws.on("message", (m) => onInput(playerId, m));   // inputs only, never outcomes
  ws.on("close", () => onLeave(playerId));
});

setInterval(() => {                    // the server simulates and broadcasts
  simulate(1 / TICK_HZ);
  broadcast(wss, snapshot());
  if (matchOver()) endMatch();
}, 1000 / TICK_HZ);

async function endMatch() {
  await reportResults();
  process.exit(0);                     // ends the Gameye session
}
process.on("SIGTERM", endMatch);       // a stop request: drain and exit

httpd.listen(PORT, "0.0.0.0");

Never give the game server your Gameye API token. Report joins and leaves to your own backend, and let the backend call Gameye.


TLS for browser clients

A page served over https can't open ws:// to a raw IP and port, and a Gameye session gives you exactly that. Pick one of these:

  • Per-session DNS and a wildcard certificate. When a session starts, your backend creates a record such as s-<session>.play.yourgame.example pointing at the session's IP. The server terminates TLS with a wildcard certificate it fetches from your backend at boot. Never bake the key into the image or pass it in session env.
  • A WebSocket relay at the edge. The page connects over wss:// to a small relay, such as a Cloudflare Worker, that holds TLS and forwards to the session. Your backend signs a short-lived token naming the session's address, and the relay connects only to that address.

The container

Start node directly as the entrypoint. Under npm start, npm swallows SIGTERM and your drain code never runs. Build for linux/amd64.

Dockerfile
FROM node:22-slim AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev

FROM node:22-slim
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY server/ ./server/
USER node
EXPOSE 8080/tcp
ENTRYPOINT ["node", "server/server.js"]

See it running: Scrapyard

Scrapyard is a browser car-combat game whose authoritative game server is Node.js and WebSocket. Nakama's matchmaker forms each quick-play match, and the Gameye Fleet Manager for Nakama starts a Gameye session for it. Browsers reach the session through a Cloudflare Worker relay. The code is open source at Gameye/scrapyard-nakama; GAMEYE.md walks through it, and scripts/gameye-up.sh runs it on your own Gameye account.


Let your coding agent do it

Claude Code, Cursor, Copilot and other coding agents can build your Node.js dedicated server, containerize it and start it on Gameye for you. Two open-source tools teach them how: gameye-skills and the gameye-mcp server.

  1. Sign up at trial.gameye.com, then create an API token in the Admin Panel under Users > API tokens.
  2. Install the skills in your project:
    npx skills add gameye/gameye-skills --skill "gameye" --skill "gameye-web-server"
  3. Give your agent the MCP server, so it can start sessions, read logs and manage applications:
    claude mcp add gameye --env GAMEYE_API_TOKEN=<your-token> -- npx -y gameye-mcp
    In Claude Code, /plugin marketplace add gameye/gameye-skills then /plugin install gameye@gameye installs both.

Setup for Cursor, Claude Desktop and other clients is in the AI agents guide.


Frequently asked questions

Can I host Colyseus on Gameye?

Yes. A Colyseus server runs on Gameye like any other Node.js server: run one Colyseus process per match in its own Gameye session, and exit the process when the room is disposed so the session ends.

Can I host a Node.js WebSocket game server on Gameye?

Yes. Package the Node.js server as a Linux container that listens on one TCP port for HTTP and the WebSocket upgrade, register the port as TCP in your Gameye application, and start one Gameye session per match through the Session API. No Gameye SDK is needed.

How do browser clients connect securely to a game server on Gameye?

A page served over https cannot open ws:// to a raw IP and port. Use per-session DNS records with a wildcard certificate on the game server, or a WebSocket relay at the edge that holds TLS and forwards to the session. Gameye's Scrapyard demo uses the relay pattern.

How do I try it?

Sign up at trial.gameye.com, create an API token in the Admin Panel under Users > API tokens, push your server image, and start a session. Coding agents can do this with the gameye-skills web server skill and the gameye-mcp server.

Get started

Start your free trial today.

120 minutes of server time, up to 2 servers at once. No sales call.