chore(deploy): group compose env vars and list optional ones without defaults

Each service's environment is grouped into required, optional, and
stack-fixed values. Optional variables are referenced without a default,
so Coolify lists them as settings that can be filled in or left empty;
an empty value falls back to the code's default.
This commit is contained in:
tiennm99 committed 2026-10-03 12:24:16 +07:00
1 parent 9457baf81a
commit be7ad347bd
3 files changed
+44 -34

No files matched your search

+37 -25
View File
@@ -7,32 +7,41 @@ services:
restart: unless-stopped restart: unless-stopped
environment: environment:
# --- Required --- # --- Required ---
TELEGRAM_BOT_TOKEN: ${TELEGRAM_BOT_TOKEN} TELEGRAM_BOT_TOKEN: ${TELEGRAM_BOT_TOKEN} # from @BotFather — SECRET
MONGO_URL: ${MONGO_URL} # Atlas SRV string incl. credentials — SECRET MONGO_URL: ${MONGO_URL} # Atlas SRV string incl. credentials — SECRET
MONGO_DATABASE: ${MONGO_DATABASE} MONGO_DATABASE: ${MONGO_DATABASE} # e.g. miti99bot
# --- Operational ---
MODULES: ${MODULES} # CSV; empty = all modules # --- Access control (optional; empty = default) ---
OWNER_ID: ${OWNER_ID} # Telegram user id for owner-only commands MODULES: ${MODULES} # CSV of modules; empty = all modules
ADMIN_IDS: ${ADMIN_IDS} # CSV of admin Telegram user ids OWNER_ID: ${OWNER_ID} # Telegram user id for owner-only commands
# --- Optional --- ADMIN_IDS: ${ADMIN_IDS} # CSV of admin Telegram user ids
LOL_PANDASCORE_TOKEN: ${LOL_PANDASCORE_TOKEN:-} # PandaScore token — SECRET; unset = /lol* fetches fail
# --- Module settings (optional; empty = default) ---
LOL_PANDASCORE_TOKEN: ${LOL_PANDASCORE_TOKEN} # PandaScore token — SECRET; empty = /lol* fetches fail
GOLD_VNAPP_API_KEY: ${GOLD_VNAPP_API_KEY} # VNAppMob key — SECRET; empty = fetched and cached in Mongo
STICKER_PACK_NAME: ${STICKER_PACK_NAME} # /addsticker set; empty = miti99_by_miti99bot
# --- Runtime (optional; empty = default) ---
LOG_LEVEL: ${LOG_LEVEL} # debug|info|warn|error; empty = info
# --- Fixed by this stack (not Coolify settings) ---
# The bundled renderer service below draws /wheelofnames, /gacha and # The bundled renderer service below draws /wheelofnames, /gacha and
# /genshin. Its base URL is fixed to the in-network address so a stale # /genshin. Its base URL is fixed to the in-network address so a stale
# platform-level value cannot point the bot elsewhere; the bot appends # platform-level value cannot point the bot elsewhere; the bot appends
# each /api/<name> route itself. # each /api/<name> route itself.
RENDERER_URL: http://renderer:3000 RENDERER_URL: http://renderer:3000
# SOURCE_COMMIT is intentionally not declared here. Coolify provides it
# at runtime via its generated env file; declaring it here with Compose # --- Deliberately not declared ---
# interpolation can override the runtime value with an empty string. # SOURCE_COMMIT: Coolify provides it at runtime via its generated env
# Storage auto-selects mongodb because MONGO_URL is set — no KV_PROVIDER. # file; declaring it here with Compose interpolation can override the
# The in-process cron scheduler runs by default — no CRON_MODE. # runtime value with an empty string.
# PORT defaults to 8080 (internal health server) — omit unless overriding. # PORT: the health server defaults to 8080, which the healthcheck uses.
# KV_PROVIDER: storage auto-selects mongodb because MONGO_URL is set.
# Long polling = no TELEGRAM_WEBHOOK_SECRET, no /webhook, no public domain. # Long polling = no TELEGRAM_WEBHOOK_SECRET, no /webhook, no public domain.
# Cron is in-process only — there is no /cron HTTP route and no secret. # Cron is in-process only — no CRON_MODE, no /cron route, no secret.
# No stock/coin/gold URL env overrides — modules use their coded default # No stock/coin/gold URL overrides — modules use their coded default
# providers (stock: SSI/VCI/KBS; coin: Binance->Coinbase->CoinGecko; # providers (stock: SSI/VCI/KBS; coin: Binance->Coinbase->CoinGecko;
# gold: VNAppMob). If GOLD_VNAPP_API_KEY is unset, the bot auto-fetches # gold: VNAppMob).
# and caches a key to Mongo.
# Long polling is outbound-only: nothing inbound to route, so no published # Long polling is outbound-only: nothing inbound to route, so no published
# ports and no public domain. `expose` only documents the health server's # ports and no public domain. `expose` only documents the health server's
# port; it publishes nothing on the host. # port; it publishes nothing on the host.
@@ -58,16 +67,19 @@ services:
context: ./renderer context: ./renderer
restart: unless-stopped restart: unless-stopped
environment: environment:
NODE_ENV: production
# Every renderer setting carries the RENDERER_ prefix so it reads as a # Every renderer setting carries the RENDERER_ prefix so it reads as a
# renderer setting and cannot clash with the bot's variables. # renderer setting and cannot clash with the bot's variables.
# --- Tuning (optional; empty = default) ---
RENDERER_MAX_CONCURRENT_RENDERS: ${RENDERER_MAX_CONCURRENT_RENDERS} # empty = 1
RENDERER_RENDER_TIMEOUT_MS: ${RENDERER_RENDER_TIMEOUT_MS} # empty = 15000 (floor 7000)
RENDERER_MAX_OPTIONS: ${RENDERER_MAX_OPTIONS} # empty = 32 wheel options
RENDERER_MAX_OPTION_CHARS: ${RENDERER_MAX_OPTION_CHARS} # empty = 40 chars per option/label
# --- Fixed by this stack (not Coolify settings) ---
NODE_ENV: production
RENDERER_HOST: 0.0.0.0 RENDERER_HOST: 0.0.0.0
RENDERER_PORT: "3000" # keep in sync with the bot's RENDERER_URL and the healthcheck RENDERER_PORT: "3000" # keep in sync with the bot's RENDERER_URL and the healthcheck
# Tuning is left out on purpose: the renderer's own defaults apply
# (RENDERER_MAX_CONCURRENT_RENDERS=1, RENDERER_RENDER_TIMEOUT_MS=15000,
# RENDERER_MAX_OPTIONS=32, RENDERER_MAX_OPTION_CHARS=40). Coolify lists
# every interpolated variable here as a setting, so to override one, add it
# here as a literal, e.g. RENDERER_MAX_OPTIONS: "48".
expose: expose:
- "3000" - "3000"
healthcheck: healthcheck:
+5 -7
View File
@@ -38,7 +38,7 @@ Copy [`.env.example`](../.env.example) → `.env` (gitignored) and fill in.
| `LOL_PANDASCORE_TOKEN` | optional | PandaScore API token for the lol module (free tier) — secret, never logged; without it every `/lol*` fetch fails (stale cache may still serve briefly) | | `LOL_PANDASCORE_TOKEN` | optional | PandaScore API token for the lol module (free tier) — secret, never logged; without it every `/lol*` fetch fails (stale cache may still serve briefly) |
| `RENDERER_URL` | leave unset | base URL of the animation renderer; fixed by `compose.yml` to the bundled renderer (`http://renderer:3000`), so a Coolify value is ignored | | `RENDERER_URL` | leave unset | base URL of the animation renderer; fixed by `compose.yml` to the bundled renderer (`http://renderer:3000`), so a Coolify value is ignored |
| `LOG_LEVEL` | optional | `debug`, `info` (default), `warn`, or `error`; logs are JSON on stdout | | `LOG_LEVEL` | optional | `debug`, `info` (default), `warn`, or `error`; logs are JSON on stdout |
| `GOLD_VNAPP_API_KEY` | leave unset | VNAppMob key; unset = the gold module fetches one and caches it in MongoDB | | `GOLD_VNAPP_API_KEY` | optional | VNAppMob key — secret; empty = the gold module fetches one and caches it in MongoDB |
| `KV_PROVIDER` | leave unset | `memory` or `mongodb`; unset = `mongodb` when `MONGO_URL` is set, otherwise `memory` | | `KV_PROVIDER` | leave unset | `memory` or `mongodb`; unset = `mongodb` when `MONGO_URL` is set, otherwise `memory` |
| `PORT` | leave unset | health server port; default `8080` | | `PORT` | leave unset | health server port; default `8080` |
| `SOURCE_COMMIT` | never set | provided by Coolify at runtime for the deploy DM (see step 5 below) | | `SOURCE_COMMIT` | never set | provided by Coolify at runtime for the deploy DM (see step 5 below) |
@@ -62,12 +62,10 @@ to it.
Renderer tuning (`RENDERER_MAX_CONCURRENT_RENDERS`, Renderer tuning (`RENDERER_MAX_CONCURRENT_RENDERS`,
`RENDERER_RENDER_TIMEOUT_MS`, `RENDERER_MAX_OPTIONS`, `RENDERER_RENDER_TIMEOUT_MS`, `RENDERER_MAX_OPTIONS`,
`RENDERER_MAX_OPTION_CHARS`) is optional and needs nothing in Coolify: the `RENDERER_MAX_OPTION_CHARS`) is optional. `compose.yml` references each one
renderer's defaults apply, listed in without a default, so Coolify lists it as a setting you can fill in or leave
[`renderer/docs/deployment.md`](../renderer/docs/deployment.md). Coolify lists empty; an empty value uses the renderer's default, listed in
every `${VAR}` that `compose.yml` references as a setting, so the tuning values [`renderer/docs/deployment.md`](../renderer/docs/deployment.md). Give the host
are deliberately not referenced there; to override one, add it to the
`renderer` service's `environment:` in `compose.yml` as a literal value. Give the host
1-2 GB of headroom for the renderer's Chrome. 1-2 GB of headroom for the renderer's Chrome.
Outside compose, set `RENDERER_URL` to the base URL of any service that Outside compose, set `RENDERER_URL` to the base URL of any service that
+2 -2
View File
@@ -40,8 +40,8 @@ RENDERER_MAX_OPTION_CHARS=40
``` ```
An unset or empty variable uses the default above. The root `compose.yml` An unset or empty variable uses the default above. The root `compose.yml`
sets only `RENDERER_HOST` and `RENDERER_PORT`, so the tuning values use these fixes `RENDERER_HOST` and `RENDERER_PORT` and passes the tuning values through
defaults unless added there. without defaults, so leaving them empty in Coolify uses these defaults.
Start with 1-2 vCPU and 1-2 GB RAM. Increase only after render benchmarks show Start with 1-2 vCPU and 1-2 GB RAM. Increase only after render benchmarks show
the service is CPU-bound or concurrency-limited. the service is CPU-bound or concurrency-limited.