example.env
Rama main · réplica de lectura del repositorio original.
############################################################
# Auto Tournament – Example .env
#
# Copy this file to `.env` at the repo root and adjust values.
# The API reads `.env` via dotenv on startup.
#
# Docker Compose: The docker-compose.yml files use env_file to load
# all variables from .env into the container automatically.
############################################################
##############################
# ---- Core server settings --
##############################
# Environment: development or production (optional; defaults to development)
# NODE_ENV=development
# API port (behind Caddy/Docker this is usually 3000)
PORT=3000
# Signs sessions and sign-in cookies. Leave it empty and the API makes a
# random one and keeps it in the data folder. To set your own:
# openssl rand -base64 32
SESSION_SECRET=
##############################
# ---- License terms ---------
##############################
# Auto Tournament is free for non-commercial use under the PolyForm
# Noncommercial License 1.0.0. Commercial use needs a license
# (https://autotournament.gg/pricing); every game server counts.
#
# The first admin to sign in accepts the terms once in the browser: they pick
# non-commercial or commercial use and type I AGREE. The admin pages open
# after that. Players, public pages and running matches are never affected.
#
# For an install nobody clicks through (automation, CI), accept here instead.
# Setting this means you have read the license and accept it, on behalf of
# whoever runs this instance. It also accepts later versions of the terms,
# so remove it if you want to review a change in the browser.
# noncommercial — personal use, hobby, learning, events nobody earns from
# commercial — you need a license; add the key below or in
# Settings > License
# AT_ACCEPT_LICENSE=noncommercial
# Optional: your Auto Tournament license key (starts with ATL1.). Saved at
# startup when it differs from the saved key, so this wins over a key pasted
# in Settings > License. A missing or invalid key never blocks anything.
# With a key, this server checks in with autotournament.gg once a day: the
# key's id, a random instance id, the server count, the version and match
# counts. Nothing is sent without a key. See Settings > License.
# LICENSE_KEY=
########################
# ---- Database --------
########################
# Option A: Single DATABASE_URL (preferred in Docker)
# DATABASE_URL=postgresql://postgres:postgres@postgres:5432/auto_tournament
# Option B: Individual DB settings (for local dev without DATABASE_URL)
DB_HOST=127.0.0.1
DB_PORT=5432
DB_USER=postgres
DB_PASSWORD=postgres
DB_NAME=auto_tournament
###############################################
# ---- Machine access (bots, scripts, CI) -----
###############################################
# API tokens let a machine call the admin API without a browser session — a
# Discord bot, a cron job, a deploy script. Human admins keep using Steam/SSO;
# these are only for integrations.
#
# Present a token as either header:
# Authorization: Bearer <token>
# X-API-Token: <token>
#
# Three variables decide scope:
# API_TOKENS — full admin. Anything an admin can do, including
# creating matches, starting tournaments and RCON.
# API_TOKENS_READONLY — GET/HEAD/OPTIONS only. Enough for scoreboards,
# brackets and match state. Prefer this one: most bots
# never need to write.
# API_TOKENS_INTEGRATOR — the integrations API only (/api/integrations/*),
# e.g. an event website pushing its teams. The label
# is the integrator's "source": its team externalIds
# live under it, so keep it stable. docs/WEBHOOKS.md
#
# Format: comma- or space-separated entries, each `label:secret` or a bare
# `secret`. The label only appears in logs, so you can tell which integration
# made a call. Secrets are never logged.
#
# Generate one with:
# openssl rand -hex 32
#
# Minimum secret length is 16 characters; shorter entries are ignored with a
# warning at startup.
#
# LEAVE THESE UNSET unless you actually have an integration. A token in
# API_TOKENS is a full admin credential for your instance.
#
# Full guide, including a worked Discord bot: docs/API.md
#
# API_TOKENS=discord-bot:replace-with-openssl-rand-hex-32
# API_TOKENS_READONLY=scoreboard:replace-with-openssl-rand-hex-32
# API_TOKENS_INTEGRATOR=ntlan:replace-with-openssl-rand-hex-32
##############################
# ---- Game catalog -----------
##############################
# A fresh install has no games. The admin installs them from the catalog
# (Modules page, or /welcome/games): game packs and signed code modules such
# as CS2, from our GitHub or from the offline copy inside the image.
# Where the catalog feed lives – optional (default: catalog.json in
# Auto-Tournament/packs on GitHub)
# CATALOG_URL=https://raw.githubusercontent.com/Auto-Tournament/packs/main/catalog.json
# Never fetch the feed; offer only what the image carries (air-gapped LANs).
# The CS2 module then also uses its bundled map list instead of maps.json – optional
# CATALOG_OFFLINE=false
# Install the image's game packs on first boot: "all" or a comma-separated
# list of slugs – optional (default: none)
# PREINSTALL_PACKS=
# Extra Ed25519 public keys (base64, comma-separated) that may sign code
# modules, for your own module builds – optional. Anyone who can set this can
# already put code in DATA_DIR/modules, so it grants nothing new.
# MODULE_TRUSTED_KEYS=
# At boot, update modules installed from the catalog to the newer release the
# image carries, within their major version – optional (default: true)
# MODULE_AUTO_UPDATE=true
# Whether something brings the app back when it exits (Docker's restart
# policy), so the Modules page can offer "Restart now" – optional (default:
# true inside the Docker image, false elsewhere)
# AT_RESTART_SUPERVISED=true
###############################
# ---- CS2 server integration -
###############################
# Token used by CS2 servers to authenticate webhooks and match load requests.
# This must match the token configured in MatchZy Enhanced on your game servers.
# Example (simple random token):
# SERVER_TOKEN=$(openssl rand -base64 24 | tr -d '=+/')
SERVER_TOKEN=your-server-token-here
# Accept game events that arrive with NO X-Auto-Tournament-Token — a migration shim.
#
# Event ingest (POST /api/events) used to be unauthenticated. Servers
# that MAT configured send the token already, because the webhook config sets
# `at_remote_log_header_key`/`_value` alongside the URL. A server set up by
# hand, or by a much older MAT, may not — and the symptom is a match whose score
# stops moving, which is a horrible thing to diagnose mid-tournament.
#
# Set this to true to buy time, reconnect your servers so they re-fetch
# /api/servers/:id/bootstrap, then unset it. It only accepts a *missing* token,
# never a wrong one — but while it is on, anyone who can reach this API can
# forge match events. MAT warns about it on every boot.
#
# ALLOW_UNAUTHENTICATED_EVENTS=false
# Webhook base URL for MatchZy Enhanced to send events to the API.
# This should point to your API server (NOT the frontend dev server).
# Examples:
# - Local dev: http://localhost:3000
# - Production: http://your-server-ip:3069 or https://your-domain.com
# If not set, auto-detects as http://localhost:{PORT}
# API_BASE_URL=http://localhost:3000
# Days to keep the round backups Ready Up servers send (one per round, 10-60 KB
# each, used for "restore to round N" and failover) after a match ends.
# Live and recent matches keep every backup. 0 keeps them forever.
# FLEET_BACKUP_RETENTION_DAYS=14
# Demos Ready Up servers stream over the fleet link while they record.
# Largest demo accepted (bytes), stream rate per server (bytes/minute; the
# socket budget of a demo-streaming server is raised by this much), and days
# after which an unfinished stream is deleted.
# FLEET_DEMO_MAX_BYTES=2147483648
# FLEET_DEMO_BYTES_PER_MINUTE=67108864
# FLEET_DEMO_STREAM_EXPIRE_DAYS=7
# Every fleet server's socket budget (bytes/minute).
# FLEET_BYTES_PER_MINUTE=8388608
# How often the automatic scaler checks the Ready Up servers on csm machines
# (milliseconds). 0 turns its timer off (the test suite does this; passes then
# run only through POST /api/fleet/autoscale/run). Turn scaling itself on or
# off on the Servers page.
# FLEET_AUTOSCALE_INTERVAL_MS=15000
######################################
# ---- Ready Up compatibility page ----
######################################
# A public page at /compatibility showing whether the Ready Up plugin suite
# works on the latest CS2 build, fed by the Ready Up CI. Off unless one of
# these is set; almost every instance leaves both unset. docs/API.md has the
# endpoints and the document format.
# Token the Ready Up CI sends as `Authorization: Bearer <token>` to
# POST /api/compat/events – optional. At least 16 characters; it grants that
# one endpoint and nothing else. Generate one with: openssl rand -hex 32
# COMPAT_INGEST_TOKEN=
# URL of a compat.json to poll every 5 minutes as a fallback to the push –
# optional. A failed or invalid fetch keeps the last good result.
# COMPAT_FEED_URL=
#############################
# ---- Auth providers (SSO) -
#############################
## Shared auth settings
# Public base URL of MAT frontend, used for OAuth redirects (Steam, Discord, etc.).
# Required when you enable any auth provider.
# IMPORTANT:
# - Use http:// for local development (e.g., http://localhost:5173 for Vite dev, or :3069 for Docker)
# - Use https:// for production (e.g., https://your-domain.com)
# The secure cookie flag is automatically set based on this URL (https:// = secure cookies)
FRONTEND_BASE_URL=http://localhost:3069
#
# It is also the address handed to other machines: `csm link <url>` commands,
# and the ws_url Ready Up servers and csm hosts connect to after enrolling
# (https:// here -> wss://). A localhost value is ignored for that, and the
# request's own address is used instead. A machine that reaches the platform on
# a LAN address (192.168.x, 10.x, a .lan name...) is handed that address back,
# so `csm link http://<lan-ip>:3069 ...` keeps csm and its game servers on the
# LAN while browsers use the public URL.
# Behind your own reverse proxy (TLS terminator, Cloudflare Tunnel, NPM...),
# the container's Caddy passes the proxy's X-Forwarded-Proto/-Host/-For on to
# the API only when the proxy's address is trusted. Private ranges (Docker
# networks, LAN) are trusted by default. If your proxy connects from a public
# address, list it here (Caddy trusted_proxies syntax); otherwise the API sees
# plain http and hands out ws:// fleet URLs, which csm refuses.
# TRUSTED_PROXIES=private_ranges 203.0.113.10/32
## First admin and sign-in
#
# Nothing here is needed to sign in. On a fresh install the server logs a
# one-time setup code:
#
# [SETUP] Open https://your-domain/setup and enter this code: XXXX-XXXX-...
#
# (docker logs auto-tournament). /setup creates a local admin account
# (username + password, optional two-step verification), then takes you to
# Settings -> Sign-in, where you set up how players sign in: Steam, Discord,
# Google, GitHub, Twitch. The code works once and expires after 24 hours;
# restart the container for a new one while no admin exists.
#
# Locked out? docker exec auto-tournament reset-admin prints a code (1 hour)
# that sets a new password for a local admin or creates one.
#
# Secrets saved in the UI are stored encrypted (AES-256-GCM) with a key derived
# from SECRETS_KEY, or from SESSION_SECRET when SECRETS_KEY is unset. Changing
# that value makes the saved secrets unreadable; enter them again afterwards.
# SECRETS_KEY=a-long-random-string
#
# Upgrading from an install that set providers here? The variables below are
# still read, once: at start-up each one fills its setting in the database if
# that setting is empty, and the log says "[SETUP] imported X from
# environment; you can remove it from .env". After that Settings -> Sign-in is
# the source of truth and the variable is ignored (even if you clear the
# setting in the UI). New installs do not need any of them.
#
# AUTH_STEAM_ENABLED, STEAM_API_KEY
# AUTH_DISCORD_ENABLED, DISCORD_CLIENT_ID, DISCORD_CLIENT_SECRET
# AUTH_GOOGLE_ENABLED, GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET
# AUTH_GITHUB_ENABLED, GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET
# AUTH_TWITCH_ENABLED, TWITCH_CLIENT_ID, TWITCH_CLIENT_SECRET
# ADMIN_STEAM_IDS -> Settings -> Sign-in -> Admin Steam IDs (made admin at
# every start; may also run raw console commands on
# Ready Up servers)
# ADMIN_EMAILS -> Settings -> Sign-in -> Admin emails (admin at sign-in
# with a provider-verified address)
## OpenID Connect – optional
# Any OpenID Connect server (Keycloak, Authentik, Authelia, Zitadel, Microsoft
# Entra ID, Okta, ...). Set it up on Settings -> Sign-in -> OpenID Connect; these
# are imported once at the first start, like the other providers:
# AUTH_OIDC_ENABLED=true
# OIDC_ISSUER_URL=https://sso.example.com/realms/auto-tournament
# OIDC_CLIENT_ID=auto-tournament
# OIDC_CLIENT_SECRET=your-client-secret
# OIDC_LABEL=NTLAN # the button reads "Sign in with NTLAN"
# # Redirect URI to register: FRONTEND_BASE_URL + /api/auth/oidc/callback
# Sign-in providers do not grant admin on their own (except through the admin
# emails). Someone new gets an account of their own when registration is open
# (Settings -> Players & Access); admin access follows that account's admin flag.
############################
# ---- Logging & debug ----
############################
# Log level: trace | debug | info | warn | error | fatal
# When LOG_LEVEL=debug, DB verbose and DB values logging are enabled automatically.
LOG_LEVEL=info
# Set to false to disable per-request HTTP logs (still logs 4xx/5xx) – optional
# LOG_HTTP_REQUESTS=true
# Per-query DB logs (SQL, params, row counts). Auto-enabled when LOG_LEVEL=debug.
# LOG_DB_VERBOSE=true
# When DB verbose is on, also log result rows (redacted). Auto-enabled when LOG_LEVEL=debug.
# Set LOG_DB_VALUES=false to disable even in debug.
# LOG_DB_VALUES=false
# Enable verbose RCON success logs – optional
# LOG_RCON_VERBOSE=false
################################
# ---- CORS / WebSockets -------
################################
# Allowed CORS origin(s) for Socket.IO and API (comma-separated) – optional
# In Docker with Caddy, this is usually handled at the proxy layer.
# CORS_ORIGIN=*
#####################################
# ---- Optional: simulation mode ----
#####################################
# Allow enabling "simulation" features in production (advanced) – optional
# AT_ENABLE_SIMULATION_IN_PROD=false
###########################
# ---- Misc / tooling ----
###########################
# Playwright base URL for E2E tests – optional (defaults to http://localhost:3069 in tests)
# PLAYWRIGHT_BASE_URL=http://localhost:3069
# Steam ID to use for the test admin in Playwright/tests/scripts – optional
# TEST_STEAM_ID=76561198000000001