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
| Variable | Where | Notes |
|---|---|---|
JWT_SECRET | Core | Signs panel sessions. Core refuses to boot without it. |
CLUSTER_SECRET | Core, node | Shared trust anchor inside one cluster. Never give it to a machine you do not own. |
DB_PASSWORD | Core, database | |
PANEL_API_URL | Panel | The 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:
docker compose configTransport 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:
environment:
DB_PASSWORD_FILE: /run/secrets/db_password
secrets:
- db_passwordNever 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 fromPORT_RANGE(25600-25699) and players connect tonode-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.