This file is the practical self-hosting guide.
You need:
- Python
3.13 - PostgreSQL
14+ uvfor the local Python workflow
Optional:
- Docker and Docker Compose
- Open
@BotFatherin Telegram - Run
/newbot - Copy the bot token
- Put the token into
.env
If your token was exposed before, rotate it in @BotFather before launch.
cp .env.example .envSet at least:
TELEGRAM_BOT_TOKEN=your_bot_token_here
DATABASE_URL=postgresql+asyncpg://postgres:postgres@localhost:5432/collocation_coachCreate a database:
psql -U postgres -c "CREATE DATABASE collocation_coach;"If you also need a local user:
psql -U postgres -c "CREATE USER collocation WITH PASSWORD 'collocation';"
psql -U postgres -c "ALTER USER collocation CREATEDB;"
psql -U postgres -c "GRANT ALL PRIVILEGES ON DATABASE collocation_coach TO collocation;"Then update DATABASE_URL if you do not use the default postgres user.
uv sync
uv run python -m collocation_coach.mainWhat happens on startup:
- config is loaded from
.env - lesson files are validated
- database tables are created if missing
- lesson content is seeded into Postgres
- Telegram polling starts
docker compose up --buildThis is the easiest way to run the bot with Postgres if Docker is already installed.
After the bot starts:
- Open the bot in Telegram
- Send
/start - Choose level, timezone, and delivery time
- Send
/today - Finish one lesson
- Send
/review - Send
/progress - Optionally continue with
Extra practice - If you see a bad card, use
Report a problemfrom the study card
If these commands work, your instance is ready.
Lessons are stored as YAML files:
content/lessons/a2_b1content/lessons/b1_b2
Each lesson file contains:
- lesson metadata
3collocation items- Russian explanation
- correct example
- common mistake
- multiple-choice practice
Before editing lesson files, read docs/CONTENT_GUIDE.md. To validate content locally, run:
uv run python -m collocation_coach.validationAfter changing lesson files, restart the bot to reseed content.
Users can change pace in /settings:
Light: smaller main sessionStandard: defaultIntensive: more new items per session
The main session is finite. When it ends, the bot can offer optional extra practice. If a user returns after 3 or more missed local days, the bot starts with a smaller welcome-back session. Timezone selection now covers a wider set of common regions, and delivery-time selection offers hourly options across the day.
Bot does not start
- check
TELEGRAM_BOT_TOKEN - check
DATABASE_URL - make sure Postgres is running
Polling starts but bot does not answer
- make sure no other process is running the same bot token
Content fails to load
- run
uv run python -m collocation_coach.validation - run
uv run pytest - inspect the last edited YAML file for invalid structure
uv run pytest
uv run python -m compileall src
uv run python -m collocation_coach.validation
uv run python -m collocation_coach.reporting
uv run python -m collocation_coach.reporting content-issues --format csv
docker compose configAnyone should be able to fork this repository, set .env, and run their own copy of the bot.