Getting started
Requirements
- Docker with Compose v2.
- A Telegram application API ID and hash from my.telegram.org.
- For the Bash migration helper: Bash, curl and jq.
The application API ID/hash identify your Telegram application. They are different from a bot token issued by BotFather.
Prepare
git clone https://github.com/ichinya/tg-selfhost-botapi.git
cd tg-selfhost-botapi
cp .env.example .env
Fill in API_ID and API_HASH in .env. Keep that file private.
The gateway binds to 127.0.0.1 by default and does not expose the state directory.
If remote clients, including a webhook receiver, must reach the Bot API, set
GATEWAY_BIND=0.0.0.0 in .env and provide HTTPS and network access controls.
Start
Before the first GHCR publication, build locally:
docker compose -f docker-compose.yml -f docker-compose.build.yml up -d --build
Once a published image is available:
docker compose pull
docker compose up -d
For a private GHCR package, authenticate with an account that has package access; for anonymous pulls, the repository owner must make the package public. Local compilation can take a long time. The default build uses one compilation job.
Verify
docker compose ps
docker compose logs --tail=100 botapi gateway
curl --connect-timeout 5 --max-time 10 -i http://127.0.0.1:18080/
A response from the Bot API path confirms HTTP reachability, even if it reports a missing method or token. It does not confirm a bot session or webhook delivery.
The application endpoint is:
http://127.0.0.1:18080/bot<TOKEN>/<METHOD>
Use token-bearing calls only on the chosen server at the appropriate migration stage. To check a bot already assigned to this server:
read -rsp 'Bot token: ' BOT_TOKEN; printf '\n'
curl --connect-timeout 5 --max-time 15 \
"http://127.0.0.1:18080/bot$BOT_TOKEN/getMe"
unset BOT_TOKEN
These command examples use Bash. A token expanded into curl’s URL can be visible in process arguments and access logs; run diagnostics in a trusted environment.