# Game node operations Game nodes run Docker workloads for Minecraft servers and connect to the control plane through the node-agent. ## Capacity Each node exposes: - `maxServers`, `maxRamMb`, `platformRamMb` - Host port pool: `portRangeStart`–`portRangeEnd` (default `25565`–`25664`) The scheduler places new servers on the least-loaded eligible node. ## Enrollment 1. Create a `GameNode` row in the control plane database. 2. Generate an enrollment token and distribute it securely to the node host. 3. Start `node-agent` with matching `NODE_ID` and `NODE_TOKEN`. 4. Confirm node status becomes `ONLINE` in the admin API. ## Port allocation Host ports are unique per node (`@@unique([nodeId, hostPort])`). Do not manually assign ports outside the configured range. ## Draining Before maintenance: 1. Set node status to `DRAINING` via admin API. 2. Wait for running servers to stop or migrate. 3. Perform maintenance. 4. Return node to `ONLINE` or decommission. ## Firewall Allow: - Outbound WebSocket to control plane API - Inbound TCP on allocated Minecraft host port range - Docker bridge traffic locally Deny: - Public access to Docker API - Unrestricted inbound on management ports ## Ansible Bootstrap with: ```bash ansible-playbook -i inventories/production deploy/ansible/game-node.yml ``` Copy the `hgc-node-agent` binary to `/usr/local/bin/hgc-node-agent` and provide TLS materials via `NODE_TLS_CERT` / `NODE_TLS_KEY` or CA enrollment. ## Failure scenarios | Scenario | Action | |----------|--------| | Node offline | Servers marked `UNKNOWN`; reschedule starts when node returns | | Port exhaustion | Provisioning fails with `NO_NODE_AVAILABLE`; add node or expand port range | | Disk full | Stop new provisions; prune unused images; expand volume |