● Deploy · Environment
Configuration
every variable, explained.
All apps read one file: the repository-root .env. The API validates its variables at start-up and stops with a list of problems if one is invalid. The Mini App and admin read only VITE_* variables, and only at build time.
01API: required secrets
| Variable | Rule | Purpose / how to get it |
|---|---|---|
ENCRYPTION_KEY | 64 hex characters | Encrypts each campaign's bot token at rest (AES-256-GCM). openssl rand -hex 32. Never change it once tokens are saved; if you must, paste every bot token again. |
ADMIN_JWT_SECRET | ≥ 32 characters | Signs admin sessions (12 hours). openssl rand -hex 32. Changing it signs every admin out. |
ABUSE_HASH_SALT | ≥ 16 characters | Salt for hashed IPs and user agents used by anti-bot, and for daily puzzle answer hashes. openssl rand -hex 16. Changing it breaks cluster matching with older data and invalidates every stored puzzle answer. |
02API: URLs, network and behaviour
| Variable | Default | Purpose |
|---|---|---|
PUBLIC_API_URL | http://localhost:8787 | Public URL of the API, e.g. https://api.example.com. Used for the Telegram webhook (registered only when it is https), the Adsgram Reward URL and the curl example of dev:initdata. |
CORS_ORIGINS | http://localhost:5173,http://localhost:5174 | Comma-separated exact origins of the Mini App and the admin (scheme + host, no trailing slash). Admin changes from any other Origin are refused with forbidden_origin. Every host listed here is also accepted as a TON Connect proof domain. |
ADMIN_PUBLIC_URL | http://localhost:5174 in .env.example | Public https URL of the hosted admin. Client report links are built as <ADMIN_PUBLIC_URL>/r/<token>. Optional, but when set it must be a full URL: the API refuses to start otherwise. If it is not set, the API falls back to the first entry of CORS_ORIGINS, which is usually the Mini App, and the links would be wrong, so always set it in production. |
BROADCAST_WORKER | on (true) | Runs the bot broadcast worker inside the API process (ticks every second, at most 25 messages per second per bot). Allowed values: true or false (anything else stops the API at start-up); unset means on. Keep it on in exactly one API process. |
TON_NETWORK | testnet | testnet or mainnet. Network for anti-bot wallet checks and the default for distributor deploy messages. Keep testnet until you have run a full airdrop there. |
TONCENTER_API_KEY | empty | Your own toncenter key. Turns on the wallet_fresh and wallet_shared_funder anti-bot signals. Empty: those checks are skipped and the report says so, never guessed. |
TON_PROOF_DOMAINS | empty | Extra hosts (host[:port], comma-separated) accepted as the TON Connect ton_proof domain. The campaign's Mini App host and every CORS_ORIGINS host are always accepted, so most installs leave this empty. |
TRUST_PROXY | false | true (or 1) uses X-Forwarded-For as the client IP. Docker Compose sets it to true. Leave false when clients connect directly, otherwise they could fake their IP. |
PORT | 8787 | API port. |
DATABASE_URL | postgres://localhost:5432/campaign_kit | PostgreSQL URL. Docker Compose sets it for you. |
03Deployment extras
| Variable | Purpose |
|---|---|
POSTGRES_PASSWORD | Password of the Compose PostgreSQL. openssl rand -hex 24. Required by docker-compose.yml. |
NODE_ENV | Do not set it in .env. The runtime sets it (production in Docker). The web apps share .env, and putting it there breaks their builds. In production it also makes the admin cookie Secure. |
MIGRATIONS_DIR | Set inside the Docker image. Do not touch. |
TEST_DATABASE_URL | Tests only. Default postgres://localhost:5432/campaign_kit_test. |
E2E_DATABASE_URL | E2E test only. Must end in /campaign_kit_e2e. |
MINIAPP_DEV_URL | Development only: base URL printed by pnpm dev:initdata (default http://localhost:5173). |
04Mini App (build time)
| Variable | Purpose |
|---|---|
VITE_API_URL | API origin, e.g. https://api.example.com. Empty = same origin. |
VITE_PUBLIC_URL | Public https origin of the Mini App, e.g. https://play.example.com. Required for TON Connect (manifest) in production. |
VITE_APP_NAME, VITE_APP_ICON_URL | Optional. Name and icon wallets show in the connect dialog. Defaults: Campaign and <VITE_PUBLIC_URL>/icon.png. |
VITE_TERMS_URL, VITE_PRIVACY_URL | Optional links added to the TON Connect manifest. |
VITE_DEFAULT_CAMPAIGN | Optional slug used when the URL has no ?c= and no c_<slug> start parameter. |
VITE_TWA_RETURN_URL | Optional https://t.me/<bot>/<app> that wallets return to after signing. Default https://t.me/<bot>. |
VITE_DEV_INIT_DATA | Development only (output of pnpm dev:initdata). Ignored in production builds. Leave empty. |
05Admin (build time)
| Variable | Purpose |
|---|---|
VITE_ADMIN_API_URL | API origin, e.g. https://api.example.com. |
VITE_ADMIN_PUBLIC_URL | Public https origin of the admin, e.g. https://admin.example.com. Used for the admin's TON Connect manifest (deploying and funding the distributor). |
Two variables, same value
ADMIN_PUBLIC_URL (read by the API for client report links) and VITE_ADMIN_PUBLIC_URL (baked into the admin build) are separate. In production both are the admin's https origin.06What is not in .env
Everything per campaign lives in the database and is edited in the admin: bot token (encrypted), Mini App URL, branding, token and jetton master, economy, quests, shop, seasons, events, puzzles, fairness rules, ads settings and the Adsgram Reward URL secret (only its SHA-256 is stored). See Running a campaign.