Skip to content
Documentation

Configuration

Everything is environment variables. The complete reference lives in the repository README; this page covers what you actually touch and the two traps that cost people an evening.

The ones you must set

VariableWhereNotes
JWT_SECRETCoreSigns panel sessions. Core refuses to boot without it.
CLUSTER_SECRETCore, nodeShared trust anchor inside one cluster. Never give it to a machine you do not own.
DB_PASSWORDCore, database
PANEL_API_URLPanelThe public Core API URL as the browser sees it, ending in /api.

Trap 1: an empty variable beats the default

A variable that is set but empty overrides the code default. Writing SOME_VAR: "${SOME_VAR:-}" in a compose file does not leave the default in place. It sets the variable to an empty string, and an empty string wins.

If you want the default, leave the variable out of the environment: block entirely.

Trap 2: a .env entry alone does nothing

A new variable must appear in the environment: block of the compose file. A .env file only expands ${VAR} where the compose file references it. Add it in one place and not the other, and the setting silently has no effect.

Check what actually reaches the container:

shell
docker compose config

Transport security

GRPC_TLS_ENABLED controls whether the node-to-Core control channel is encrypted and certificate-pinned. It defaults to on. Set it to false only to switch it off, and then on both Core and every node: a TLS listener refuses a plaintext connection, and a TLS client refuses a plaintext server.

In-cluster nodes derive the certificate pin from CLUSTER_SECRET. A node you do not own gets GRPC_TLS_FINGERPRINT instead, which the panel writes into the deploy snippet for you. That is what lets such a node verify the connection without ever holding a cluster secret.

Secrets from files

Anything sensitive can come from a file instead of the environment, using the *_FILE convention, which is how Docker and Portainer secrets work:

shell
environment:
  DB_PASSWORD_FILE: /run/secrets/db_password
secrets:
  - db_password

Never commit real values. The repository ships a .env.example; your .env is git-ignored.

Routing mode

Decides how players reach a server:

  • ip_port - the node binds a host port from PORT_RANGE (25600-25699) and players connect to node-ip:port. The default, and it needs no gateway.
  • gateway - the node binds no host port at all; player traffic arrives through the managed edge. Required for machines behind NAT.
  • both - direct ports and a routed address at the same time.