Helios
Operations

Deployment

Two supported deployment shapes:

Two supported deployment shapes:

  • Docker Compose — single host, fine up to ~hundreds of clients.
  • Kubernetes — horizontally scaled (planned; manifests not yet shipped).

This page documents the compose path. Kubernetes lands in a future phase once the hosting target decision is finalised.

Prerequisites

  • Docker Engine 24+ and Docker Compose v2.
  • A registered Telegram bot (BotFather → token).
  • (Optional) Telegram api_id / api_hash from my.telegram.org if you intend to run the userbot pool.
  • ~5 GB of disk for Postgres + Redis + MinIO data volumes.

Environment

Create .env in the repo root (the .env.sample lists every variable):

# Bot
BOT_TOKEN=123456:ABC-DEF…
OWNER_TG_USER_ID=12345678
 
# Telegram API (userbot pool — optional in dev)
TELEGRAM_API_ID=
TELEGRAM_API_HASH=
 
# Crypto
KMS_PROVIDER=env
AES_MASTER_KEY=<64 hex chars>
 
# Postgres / Redis come from the compose stack; only override for remote DBs.

For production, set KMS_PROVIDER=aws_kms (or gcp_kms) and supply KMS_REGION / KMS_KEY_ID. The dev default keeps the master key in env so you can iterate locally; never use that in production.

Bring-up

# 1. Start the data + observability stack
docker compose up -d postgres redis minio meilisearch \
                    prometheus loki grafana
 
# 2. Apply migrations (runs as the superuser).
make migrate
 
# 3. Seed the parameters registry.
make seed-params
 
# 4. Bring up application processes (one at a time, or all via profile).
docker compose --profile workers up -d

The bot, API and userbot processes run outside of compose by default during local development:

make run-api        # FastAPI on :8000
make run-bot        # aiogram long-poll bot
make run-userbot    # one or more pyrotgfork pool members

In production each of these runs as its own container/pod with the SERVICE= env var dispatched by the Dockerfile entrypoint.

Verifying

After make migrate && make run-api, check:

EndpointExpectedNotes
GET /healthz{"status": "ok"}Bypasses auth + rate limit
GET /metricsPrometheus textSame
GET /v1/me401 without X-Telegram-Init-DataSanity check the auth chain

Grafana lives on http://localhost:3000 with admin / helios_dev (change this immediately on any non-local deploy). The Helios overview dashboard is provisioned automatically from infra/grafana/provisioning/dashboards/.

Backups

  • pg_dump hourly to S3 — wire via cron + WAL-G in production.
  • Redis is intentionally treated as ephemeral; the data tier is Postgres.
  • The AES master key MUST be backed up outside the database. If it's lost, every encrypted session blob is unrecoverable.

Upgrade

git pull
docker compose pull
make migrate           # alembic upgrade head
docker compose up -d   # rolling restart of running services

Migrations are append-only — Phase 33 removed the automatic downgrade rehearsal from CI because the TimescaleDB hypertable's downgrade isn't clean. Reversing a migration on a prod-sized database is a manual, rehearsed operation; see the runbook for the drill.

On this page