Exposing a Local Pragma Engine to the outside world with ngrok

Last updated: April 15, 2026

When developing locally, your Pragma Engine runs on localhost, but external game servers (or game clients/players running elsewhere) need to reach it over the internet. https://ngrok.com/ creates public tunnels to your local ports.

This guide may be of help in a scenario where you want to keep your pragma-engine and game clients locally but spin up game servers with an external game server provider. This would speed up your development process by allowing you to validate configurations locally before deploying to a pragma shard.

Prerequisites

  • ngrok installed and authenticated (ngrok config add-authtoken <token>). Installation instructions here.

  • Pragma Engine running locally (Game Partner on port 10100, Social Partner on port 11100)

Step 1: Start ngrok Tunnels

You need two separate tunnels — one for each Pragma gateway:

# Terminal 1 - Game Partner Gateway
ngrok http 10100

# Terminal 2 - Social Partner Gateway
ngrok http 11100

ngrok will output public URLs like:

Game Partner:   https://<game-partner-ngrok-subdomain>.ngrok-free.app -> http://localhost:10100
Social Partner: https://<social-partner-ngrok-subdomain>.ngrok-free.app -> http://localhost:11100

Note: ngrok free tier URLs change every time you restart the tunnel. You will need to update your config each time.

Note: ngrok free tier can only open 3 tunnels at a time, so if you want to also run Social Player Gateway and Game Player Gateway alongside the Partner Gateways, you will need a paid ngrok tier.

Step 2: Configure your locally running pragma-engine

This section guides you through making changes to your local-dev.yml.

Note that your local-dev.yml is located at a path of this format in your repository: pragma-engine/platform/<game-project|or|5-ext>/config/local-dev.yml

Replace the ngrok hostnames below with your actual ngrok URLs:

game:
  serviceConfigs:
    GamePartnerGatewayConfig:
      # Protocols: ngrok terminates TLS, so clients must use https/wss 
      protocol: "https"
      webSocketProtocol: "wss"

      # Authentication backend (served by the social ngrok tunnel)
      authenticateHost: <social-partner-ngrok-subdomain>.ngrok-free.app
      authenticatePort: 443

      # Game backend (served by the game ngrok tunnel)
      gameHost: <game-partner-ngrok-subdomain>.ngrok-free.app
      gameBindPort: 10100   # local port Pragma actually listens on
      gamePort: 443          # port advertised to clients (ngrok's public port)

      # Social backend (served by the social ngrok tunnel)
      socialHost: <social-partner-ngrok-subdomain>.ngrok-free.app
      socialBindPort: 11100 # local port Pragma actually listens on
      socialPort: 443       # port advertised to clients (ngrok's public port)

social:
  serviceConfigs:
    SocialPartnerGatewayConfig:
      protocol: "https"
      webSocketProtocol: "wss"
      authenticateHost: <social-partner-ngrok-subdomain>.ngrok-free.app
      authenticatePort: 443
      socialHost: <social-partner-ngrok-subdomain>.ngrok-free.app
      socialBindPort: 11100
      socialPort: 443

Configuration if you intend to expose Player Gateways to the internet:

game:
  serviceConfigs:
    GamePlayerGatewayConfig:
      # Protocols: ngrok terminates TLS, so clients must use https/wss
      protocol: "https"
      webSocketProtocol: "wss"

      # Authentication backend (served by the social-player ngrok tunnel)
      authenticateHost: <social-player-ngrok-subdomain>.ngrok-free.app
      authenticatePort: 443

      # Game backend (served by the game-player ngrok tunnel)
      gameHost: <game-player-ngrok-subdomain>.ngrok-free.app
      gameBindPort: 10000   # local port Pragma actually listens on
      gamePort: 443         # port advertised to clients (ngrok's public port)

      # Social backend (served by the social-player ngrok tunnel)
      socialHost: <social-player-ngrok-subdomain>.ngrok-free.app
      socialBindPort: 11000 # local port Pragma actually listens on
      socialPort: 443       # port advertised to clients (ngrok's public port)


social:
  serviceConfigs:
    SocialPlayerGatewayConfig:
      protocol: "https"
      webSocketProtocol: "wss"
      authenticateHost: <social-player-ngrok-subdomain>.ngrok-free.app
      authenticatePort: 443
      socialHost: <social-player-ngrok-subdomain>.ngrok-free.app
      socialBindPort: 11000
      socialPort: 443

Understanding Port vs BindPort

This is the key concept for ngrok configuration:

Field

Purpose

Example

gamePort / socialPort / authenticatePort

Port advertised to clients in the /v1/info response. Clients (SDKs, game servers) connect to this port.

443 (ngrok's public HTTPS port)

gameBindPort / socialBindPort

Port Pragma actually listens on locally. ngrok forwards traffic from port 443 to this port.

10100 / 11100

When bindPort is not set (or set to 0), it falls back to the value of port. You only need to set bindPort explicitly when the advertised port differs from the local port — which is exactly the ngrok use case.

Step 3: Verify

After restarting Pragma, hit the info endpoint to confirm everything is correct:

curl https://<game-partner-ngrok-subdomain>.ngrok-free.app/v1/info

Expected response (all ports should be 443, protocols should be https/wss):

{
  "authenticateBackend": {
    "host": "<social-partner-ngrok-subdomain>.ngrok-free.app",
    "port": 443,
    "protocol": "https",
    "scheme": "https"
  },
  "socialBackend": {
    "host": "<social-partner-ngrok-subdomain>.ngrok-free.app",
    "port": 443,
    "protocol": "https",
    "webSocketProtocol": "wss"
  },
  "gameBackend": {
    "host": "<game-partner-ngrok-subdomain>.ngrok-free.app",
    "port": 443,
    "protocol": "https",
    "webSocketProtocol": "wss"
  }
}

Troubleshooting

This section should guide you through some of the common misconfigurations that may occur:

  1. /v1/info shows port 10100 or 11100

    • cause: gamePort / socialPort not set to 443

    • fix: Set the advertised port fields to 443

  2. /v1/info shows "protocol":"http"

    • cause: protocol not overridden

    • fix: Set protocol: "https" on the gateway configs

  3. WebSocket connection fails

    • cause: webSocketProtocol is ws instead of wss

    • fix: Set webSocketProtocol: "wss" (ngrok requires TLS)

  4. authenticateBackend shows wrong port

    • cause: authenticatePort not set to 443 in GamePartnerGatewayConfig

    • fix: Add authenticatePort: 443