Skip to content

Configuration

MEMOxiiii edited this page Sep 17, 2026 · 2 revisions

Configuration

On first run, Portal generates a config.json file. Here's the full reference.

Full example

{
  "network": {
    "address": ":19132",
    "transport": "nethernet",
    "nethernet": {
      "tls": {
        "cert_file": "",
        "key_file": ""
      },
      "ice_servers": [],
      "udp_ports": "19133"
    },
    "flush_rate_ms": 20,
    "communication": {
      "address": ":19131",
      "secret": "",
      "tls": {
        "enabled": false,
        "cert_file": "",
        "key_file": ""
      }
    },
    "reader_limits": true
  },
  "logger": {
    "file": "proxy.log",
    "level": "info"
  },
  "player_latency": {
    "report": true,
    "update_interval": 5
  },
  "cluster": {
    "enabled": false,
    "proxy_id": "",
    "ttl_seconds": 300,
    "redis": {
      "address": "localhost:6379",
      "password": "",
      "db": 0
    }
  },
  "metrics": {
    "enabled": false,
    "address": ":9131"
  },
  "security": {
    "banned_ips": [],
    "rate_limit": {
      "enabled": true,
      "window_seconds": 10,
      "max_attempts": 5
    }
  },
  "health_check": {
    "enabled": true,
    "interval_seconds": 10,
    "timeout_seconds": 3,
    "failure_threshold": 3
  },
  "routing": {
    "default_group": "",
    "fallback_groups": []
  },
  "whitelist": {
    "enabled": false,
    "players": []
  },
  "resource_packs": {
    "required": false,
    "directory": "resource_packs",
    "encryption_keys": {},
    "hot_reload": {
      "enabled": false,
      "interval": 30
    }
  },
  "motd": "Portal",
  "sub_motd": "Transfer Proxy"
}

Reference

Key Description Default
network.address Address players connect to. Meaning depends on network.transport — see NetherNet Transport :19132
network.transport Player-facing transport: nethernet (default, official) or raknet (legacy UDP). See NetherNet Transport for what changes between the two nethernet
network.nethernet.tls.cert_file / network.nethernet.tls.key_file Optional PEM cert/key to serve the NetherNet signaling endpoint over HTTPS instead of plain HTTP. Only used when network.transport is nethernet "" / ""
network.nethernet.ice_servers STUN/TURN servers offered to players for WebRTC NAT traversal, as [{"urls": [...], "username": "", "password": ""}]. Only used when network.transport is nethernet — see NetherNet Transport []
network.nethernet.udp_ports UDP port, or "min-max" range, used for the actual WebRTC game connection. Must be unique on the host — it can't be shared with RakNet's port, Portal's own default, or any backend server's own NetherNet listener running on the same machine. See NetherNet Transport "19133"
network.flush_rate_ms Maximum client-bound packet buffering delay. Lower values reduce relay latency but increase CPU and network writes; 0 uses gophertunnel's default. 20
network.communication.address Socket API address for backend servers — see Socket Protocol :19131
network.communication.secret Authentication secret (must match backend configs) ""
network.communication.tls.enabled Serve the communication socket over TLS (backends must dial with TLS too) false
network.communication.tls.cert_file Path to the PEM encoded TLS certificate ""
network.communication.tls.key_file Path to the PEM encoded TLS private key ""
network.reader_limits Enable protocol reader limits true
logger.file Log file path (empty = no file logging) proxy.log
logger.level Minimum log level (debug, info, warn, error) info
player_latency.report Send player latency to backend servers true
player_latency.update_interval Latency report interval in seconds 5
metrics.enabled Serve Prometheus-style metrics at http://<metrics.address>/metrics false
metrics.address Address the metrics HTTP endpoint listens on :9131
cluster.enabled Share player presence with other Portal instances over Redis — see Clustering false
cluster.proxy_id ID this proxy reports itself as in the cluster. Empty = the machine's hostname ""
cluster.ttl_seconds How long a player's presence record survives without a refresh before expiring (crash safety net) 300
cluster.redis.address Redis server address (host:port) localhost:6379
cluster.redis.password Redis auth password, if required ""
cluster.redis.db Redis logical database index 0
security.banned_ips IP addresses that are always rejected at the player listener []
security.rate_limit.enabled Reject an IP once it connects too frequently true
security.rate_limit.window_seconds Size of the sliding window connection attempts are counted over 10
security.rate_limit.max_attempts Max connection attempts allowed per IP within the window 5
health_check.enabled Periodically ping registered servers (RakNet unconnected ping, or an HTTP /v1/join request for a NetherNet backend — see Backend Transports) and skip unreachable ones in load balancing true
health_check.interval_seconds How often, in seconds, every registered server is pinged 10
health_check.timeout_seconds How long to wait for a ping response before counting it as failed 3
health_check.failure_threshold Consecutive failed pings before a server is marked unhealthy 3
routing.default_group Server group new players are load balanced into on join. Empty = balance across every registered server, ignoring groups ""
routing.fallback_groups Ordered list of groups to try if default_group has no available (non-draining) servers []
whitelist.enabled Enable username whitelist false
whitelist.players Array of whitelisted usernames []
resource_packs.required Require resource pack download false
resource_packs.directory Directory for resource packs (.zip, .mcpack, or folders) resource_packs
resource_packs.encryption_keys Map of pack UUID → encryption key {}
resource_packs.hot_reload.enabled Reload changed resource packs without restarting Portal. New connections receive the latest successful snapshot. false
resource_packs.hot_reload.interval Resource pack change check interval in seconds 30
motd Main server list MOTD line Portal
sub_motd Secondary server list MOTD line Transfer Proxy

Notes

  • NetherNet setup (firewall/port-forwarding, STUN/TURN, TLS for the signaling endpoint) is its own page — see NetherNet Transport before deploying network.transport: "nethernet" (the default) anywhere reachable from outside its own host.
  • Server groups & weight aren't configured here — they're set per-server when a backend registers itself over the socket API (RegisterServer's Group and Weight fields). routing.default_group/routing.fallback_groups only control which group(s) new, ungrouped players are routed into. See Socket Protocol for details.
  • Draining a server is also done at runtime, either via the socket API (SetServerDraining) or the Admin Console (drain <server> [on|off]) — there's no static config for it.
  • Enabling cluster.enabled requires a reachable Redis instance; see Clustering for what clustering does and doesn't cover.

Clone this wiki locally