This guide covers production deployment options for your Telegram support bot, including systemd service setup, Docker deployment, monitoring, and backup strategies.
Prerequisites
Before deploying to production, ensure you have:
A Linux server with Python 3.8+ installed
Your bot token from @BotFather
A Telegram supergroup with topics enabled
Required permissions configured for your bot
Systemd service deployment
Install dependencies
First, set up a virtual environment and install the required packages:
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
Your bot requires these dependencies:
aiogram==3.13.1
aiosqlite==0.20.0
python-dotenv==1.0.1
Create a .env file with your bot configuration:
BOT_TOKEN = 123456:ABCDEF_your_token_here
# Supergroup chat id (usually starts with -100...)
OPERATOR_GROUP_ID = -1001234567890
# Path to SQLite DB file
DB_PATH = ./support_bot.sqlite3
LOG_LEVEL = INFO
# Store messages history in SQLite (set to 0 to disable)
LOG_MESSAGES = 1
The OPERATOR_GROUP_ID must be a supergroup ID (starts with -100). Regular groups and channels are not supported.
Create systemd service
Create a systemd service file to manage your bot as a system service:
/etc/systemd/system/telegram-support-bot.service
[Unit]
Description =Telegram Support Bot
After =network.target
[Service]
Type =simple
User =telegram-bot
WorkingDirectory =/opt/telegram-support-bot
EnvironmentFile =/opt/telegram-support-bot/.env
ExecStart =/opt/telegram-support-bot/venv/bin/python -m support_bot.main
Restart =always
RestartSec =10
# Security hardening
NoNewPrivileges =true
PrivateTmp =true
ProtectSystem =strict
ProtectHome =true
ReadWritePaths =/opt/telegram-support-bot
[Install]
WantedBy =multi-user.target
Create service user
Create a dedicated user for running the bot: sudo useradd -r -s /bin/ false telegram-bot
sudo mkdir -p /opt/telegram-support-bot
sudo chown telegram-bot:telegram-bot /opt/telegram-support-bot
Copy files
Copy your bot files to the deployment directory: sudo cp -r support_bot /opt/telegram-support-bot/
sudo cp .env /opt/telegram-support-bot/
sudo cp requirements.txt /opt/telegram-support-bot/
sudo chown -R telegram-bot:telegram-bot /opt/telegram-support-bot
Enable and start service
Enable the service to start on boot and start it: sudo systemctl daemon-reload
sudo systemctl enable telegram-support-bot
sudo systemctl start telegram-support-bot
Verify status
Check that the service is running: sudo systemctl status telegram-support-bot
Docker deployment
For containerized deployment, create a Dockerfile based on the bot’s requirements:
FROM python:3.11-slim
WORKDIR /app
# Install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy application code
COPY support_bot /app/support_bot
# Create volume mount point for database
VOLUME /app/data
# Run as non-root user
RUN useradd -m -u 1000 botuser && chown -R botuser:botuser /app
USER botuser
CMD [ "python" , "-m" , "support_bot.main" ]
Build and run with Docker
Build the image
docker build -t telegram-support-bot .
Run the container
docker run -d \
--name support-bot \
--restart unless-stopped \
-v $( pwd ) /data:/app/data \
-e BOT_TOKEN="123456:ABCDEF_your_token_here" \
-e OPERATOR_GROUP_ID="-1001234567890" \
-e DB_PATH="/app/data/support_bot.sqlite3" \
-e LOG_LEVEL="INFO" \
-e LOG_MESSAGES="1" \
telegram-support-bot
Docker Compose
Alternatively, use Docker Compose for easier management:
version : '3.8'
services :
support-bot :
build : .
container_name : telegram-support-bot
restart : unless-stopped
volumes :
- ./data:/app/data
env_file :
- .env
environment :
- DB_PATH=/app/data/support_bot.sqlite3
Start with:
Process management
Service management commands
Start sudo systemctl start telegram-support-bot
Stop sudo systemctl stop telegram-support-bot
Restart sudo systemctl restart telegram-support-bot
Status sudo systemctl status telegram-support-bot
Docker management commands
View logs docker logs -f support-bot
Restart docker restart support-bot
Monitoring and logs
View logs with systemd
The bot logs important events using Python’s logging module:
# View real-time logs
sudo journalctl -u telegram-support-bot -f
# View recent logs
sudo journalctl -u telegram-support-bot -n 100
# View logs from today
sudo journalctl -u telegram-support-bot --since today
Log levels
Configure the log level in your .env file:
support_bot/main.py (lines 23-24)
logging.basicConfig( level = getattr (logging, config.log_level.upper(), logging. INFO ))
log = logging.getLogger( "support_bot" )
Available log levels:
DEBUG - Detailed information for diagnosing problems
INFO - Confirmation that things are working as expected (default)
WARNING - Indication of unexpected events
ERROR - Serious problems that prevent functionality
Startup log message
When the bot starts successfully, you’ll see:
support_bot/main.py (lines 50-51)
me = await bot.get_me()
log.info( "Started as @ %s (id= %s )" , me.username, me.id)
Set LOG_MESSAGES=1 in your .env file to store all messages in the SQLite database for auditing and analytics.
Database backup
Your bot uses SQLite with WAL mode enabled for better concurrency:
support_bot/db.py (lines 30-32)
self ._conn = await aiosqlite.connect( self ._path)
await self ._conn.execute( "PRAGMA journal_mode=WAL;" )
await self ._conn.execute( "PRAGMA foreign_keys=ON;" )
Backup strategies
Create a backup of your database file: # For systemd deployment
sudo cp /opt/telegram-support-bot/support_bot.sqlite3 \
/opt/telegram-support-bot/backups/support_bot_ $( date +%Y%m%d ) .sqlite3
# For Docker deployment
docker exec support-bot cp /app/data/support_bot.sqlite3 \
/app/data/support_bot_backup.sqlite3
Automated backup with cron
Create a daily backup using cron: # Add to crontab (crontab -e)
0 2 * * * cp /opt/telegram-support-bot/support_bot.sqlite3 \
/opt/telegram-support-bot/backups/support_bot_ $( date + \% Y \% m \% d ) .sqlite3
# Clean up old backups (keep last 30 days)
0 3 * * * find /opt/telegram-support-bot/backups -name "*.sqlite3" -mtime +30 -delete
SQLite WAL mode creates additional files. Backup all three: cp support_bot.sqlite3 backup/
cp support_bot.sqlite3-wal backup/
cp support_bot.sqlite3-shm backup/
Or use SQLite’s built-in backup: sqlite3 support_bot.sqlite3 ".backup backup/support_bot_$( date +%Y%m%d).sqlite3"
Always test your backups by restoring them to a test environment to ensure they’re valid.
Security considerations
Protect your bot token
Use environment variables
Never hardcode your bot token in source code. The bot uses python-dotenv to load configuration: support_bot/main.py (lines 20-21)
load_dotenv()
config = load_config()
Set file permissions
Restrict access to your .env file: chmod 600 .env
sudo chown telegram-bot:telegram-bot /opt/telegram-support-bot/.env
Use secrets management
For production, consider using a secrets management service like:
HashiCorp Vault
AWS Secrets Manager
Azure Key Vault
Environment variables from your orchestration platform
Database security
The bot enables foreign key constraints for data integrity:
support_bot/db.py (lines 31-32)
await self ._conn.execute( "PRAGMA journal_mode=WAL;" )
await self ._conn.execute( "PRAGMA foreign_keys=ON;" )
Additional security measures:
Set restrictive file permissions: chmod 600 support_bot.sqlite3
Regular backups with encryption
Monitor database file size for unusual growth
Use read-only database replicas for analytics
Network security
HTTPS only The aiogram library uses HTTPS by default for all Telegram API requests.
Firewall rules No inbound ports needed. The bot uses long polling to receive updates.
Rate limiting Telegram enforces rate limits. The bot handles errors gracefully.
Updates Keep dependencies updated to patch security vulnerabilities.
User privacy
The bot stores user data in compliance with privacy best practices:
support_bot/db.py (lines 62-69)
CREATE TABLE IF NOT EXISTS users (
user_id INTEGER PRIMARY KEY ,
username TEXT ,
first_name TEXT ,
last_name TEXT ,
created_at TEXT NOT NULL ,
updated_at TEXT NOT NULL
) ;
Ensure your use of this bot complies with:
GDPR (if serving EU users)
Your local data protection regulations
Telegram’s Terms of Service and Privacy Policy
Health checks
The database includes a health check method:
support_bot/db.py (lines 338-342)
async def healthcheck ( self ) -> dict[ str , Any]:
cur = await self .conn.execute( "SELECT 1;" )
row = await cur.fetchone()
await cur.close()
return { "ok" : row == ( 1 ,)}
You can extend this to create a health check endpoint for monitoring tools.
Troubleshooting deployment
Check the logs for errors: sudo journalctl -u telegram-support-bot -n 50
Common issues:
Invalid bot token
Missing environment variables
Database file permissions
Python version mismatch
The bot uses a transaction lock to prevent conflicts: support_bot/db.py (lines 48-57)
@asynccontextmanager
async def transaction ( self ) -> Any:
async with self ._tx_lock:
await self .conn.execute( "BEGIN;" )
try :
yield
except BaseException :
await self .conn.rollback()
raise
else :
await self .conn.commit()
If you still see errors, ensure only one bot instance is running.
Monitor the bot’s memory usage: # For systemd
systemctl status telegram-support-bot
# For Docker
docker stats support-bot
Consider setting memory limits in your systemd service or Docker container.
Next steps
Customize your bot Learn how to customize greetings, topic names, and add custom handlers
Troubleshooting Solutions for common issues and error messages