Don’t want to read all this?
Just drop a link to https://xedant.com/agents/telegram/install.md or to https://xedant.com/llms.txt into any AI chat (Claude, ChatGPT, etc.) and ask it to generate the config files and commands. It will read the docs, ask you a few questions about your setup, and hand you a ready-to-use configuration. Save time — let the model do the reading for you.
You can also reach me on Telegram — I’m always glad to help. And that’s not just politeness — I genuinely enjoy talking to like-minded people, especially if you love coding as much as I do.
Telegram Agent is a program for managing your Telegram marketing that you run on your own server. It deploys as a single Docker container, with all data stored in the permanent /data volume. No separate database server is needed: the built-in SQLite works out of the box, and PostgreSQL connects optionally.
Minimum requirements
Any Linux host with Docker is enough (an inexpensive VPS, for example). Everything else is already built into the image:
- the application web server (ASP.NET Core 9 runtime);
- an SQLite database — works without any setup;
- for the chat with the agent you will need the address and API key of your Xedant Agent — but that is optional: without them everything works except the agent chat.
Docker Compose
Create a compose.yml file and run docker compose up -d:
services:
telegram-agent:
image: xedant/telegram-agent:latest
container_name: telegram-agent
ports:
- "3997:80"
volumes:
- telegram-agent-data:/data
environment:
- ASPNETCORE_ENVIRONMENT=Production
- ASPNETCORE_URLS=http://+:80
- TELEGRAM_AGENT_DATA=/data
# Optional "Call Agent" integration (leave unset to hide all Agent chat surfaces):
# - AGENT_API_URL=https://your-agent-host
# - AGENT_API_KEY=your-agent-API-key
# Serve from a first-level subfolder (see ../subfolder-hosting.md):
# - TELEGRAM_AGENT_BASE_PATH=/telegram
restart: unless-stopped
sysctls:
fs.inotify.max_user_watches: "524288"
fs.inotify.max_user_instances: "512"
volumes:
telegram-agent-data:
After startup the interface is available on port 3997: http://localhost:3997.
The two sysctls lines raise the system file-watching limits — they are needed so new messages from sources and new posts are picked up instantly, in real time. Without them, some updates may not reach the interface when the flow is large.
Environment variables
Application settings are passed through environment variables — a convenient way to set them once in compose.yml and change them without touching the code:
| Variable | Purpose | Default |
TELEGRAM_AGENT_BRAND | brand and interface language: xedant (English) or pastukhov (Russian) | xedant |
TELEGRAM_AGENT_DATA | data folder (inside the container — /data) | /data |
TELEGRAM_AGENT_LOGIN | login of the first user (the password is a SHA-256 hash in TELEGRAM_AGENT_PASSWORD) | — (self-registration) |
TELEGRAM_AGENT_PASSWORD | SHA-256 hash of the password, not the password itself: echo -n "your-password" | sha256sum | — |
AGENT_LICENSE | license key (or a path to a file with it) — the same variable Xedant Agent reads | — (no agent chat) |
AGENT_API_URL | address of Xedant Agent for the agent chat | — (Call Agent buttons hidden) |
AGENT_API_KEY | API key of Xedant Agent | — |
TELEGRAM_AGENT_BASE_PATH | serve from a first-level subfolder (for example, /telegram) | — |
TELEGRAM_AGENT_DATABASE | PostgreSQL connection string; empty value — the built-in SQLite | SQLite (/data/data.db) |
TELEGRAM_AGENT_CLICKHOUSE_URL | ClickHouse address — a separate database for long-term channel statistics storage; empty — upload disabled | — |
Note: TELEGRAM_AGENT_PASSWORD contains not the password but its SHA-256 hash — a “fingerprint” from which the password cannot be recovered. The hash is computed with echo -n "your-password" | sha256sum. On sign-in the application hashes the entered password and compares it with the configured value.
First-time setup happens right in the interface: self-registration is open while no user exists — the first person to register becomes the administrator. If there are no users yet and the login and password are not set with variables, the application creates a one-time password itself (login code) and prints it to the container console. A sign-in session lasts 90 days.
Data storage
All permanent data lives in the /data volume and survives container recreation:
/data/data.db— the SQLite database (when PostgreSQL is not used);/data/sessions/— sessions of the connected Telegram accounts;/data/media/— uploaded media files;/data/keys/— the sign-in signing key (JWT);/data/.xedant/license.txt— the activated license key (for the pastukhov brand — the.pastukhovfolder);/data/auth/— data protection keys.
The volume is mandatory: without it you lose the connected accounts, channels and settings on the very first docker compose down.
First sign-in
Open the interface in a browser and register the first user — you become the administrator. Or sign in with the login set through environment variables (the variable holds the hash; at sign-in you enter the password itself) or the one printed to the container console. Right after signing in you can change the interface language and theme.
Setup after launch
Connect the bots first — tokens are created in @BotFather in a minute and verified automatically — and (optionally) personal Telegram accounts by phone number and code. Then connect channels: through a bot, a name and a token are enough; through an account, pick from the list of your channels. Details in the Channels section.
The agent chat is enabled with the AGENT_API_URL and AGENT_API_KEY variables: the Call Agent buttons appear on the channel page and in the queue, plus the chat panel. Details in the Agent section.
License
The license key is activated in the license dialog (the footer of the main screen) or passed with the AGENT_LICENSE variable at startup — the same variable Xedant Agent reads, so one key can license several products of this family at once. No ready license ships in the image: a fresh container starts without one. The important advantage: everything works without a license — channels, publishing, the schedule, the queue, sources, comments and analytics. The license is needed only for sending messages to the agent chat. Details on the Licensing page.
Docker CLI with a .env file
You can run Telegram Agent without compose too — with a docker run command, keeping the environment variables in a .env file:
# .env
ASPNETCORE_ENVIRONMENT=Production
ASPNETCORE_URLS=http://+:80
TELEGRAM_AGENT_DATA=/data
TELEGRAM_AGENT_LOGIN=admin
TELEGRAM_AGENT_PASSWORD=sha256-password-hash
# optional: agent chat through Xedant Agent
# AGENT_API_URL=
# AGENT_API_KEY=
# optional: license key (no license ships in the image)
# AGENT_LICENSE=
docker run -d \
--name telegram-agent \
--env-file .env \
-p 3997:80 \
-v telegram-agent-data:/data \
--sysctl fs.inotify.max_user_watches=524288 \
--sysctl fs.inotify.max_user_instances=512 \
--restart unless-stopped \
xedant/telegram-agent:latest
The --env-file flag reads all the variables from the file. Individual values can be overridden with additional -e flags after it, for example -e TELEGRAM_AGENT_BRAND=pastukhov.