fix: route compose db connections to postgres service
Meme Wrangler Bot
Telegram bot that accepts memes (photos, GIF animations, videos) from the owner's private messages and schedules them into a channel at the next available slot among 11:00, 16:00, 21:00.
Setup
Option 1: Run with Docker (Recommended)
The easiest way to run the bot is using Docker:
-
Set up environment variables:
cp .ENV.example .ENV nano .ENV # Edit with your bot credentialsThe compose file now looks for
.ENVby default so Portainer and other orchestrators can supply secrets without additional flags. Copy.ENV.exampleto.ENV, then populateTELEGRAM_BOT_TOKEN,OWNER_ID,CHANNEL_ID, and the Postgres settings. LeavePOSTGRES_HOST=postgres(andPOSTGRES_PORT=5432unless your database listens elsewhere) when you run inside Docker. The bot rewrites any localhost URLs with that host so the container connects to the bundled PostgreSQL service instead of looping back on itself. You can still point the stack at a different file by exportingCOMPOSE_ENV_FILE(e.g.COMPOSE_ENV_FILE=staging.env docker compose up -d). Backups are protected by a built-in SHA-256 hash; optionally defineMEMEBOT_BACKUP_PASSWORD_HASHto replace it. -
Run with Docker Compose:
docker-compose up -d -
View logs:
docker-compose logs -fDeploying via Portainer? Upload your
.ENVfile under Environment variables—Portainer stores it beside the stack so the compose file picks it up automatically. OverrideCOMPOSE_ENV_FILEonly when you use a differently named file. -
Stop the bot:
docker-compose down
For detailed Docker deployment instructions, including remote server deployment, see DOCKER_DEPLOY.md.
Option 2: Run Locally
- Create a virtualenv and install dependencies:
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
-
Provision a PostgreSQL database (local Docker container or managed instance) and note the connection string.
-
Set environment variables:
export TELEGRAM_BOT_TOKEN=123:ABC
export OWNER_ID=123456789
export CHANNEL_ID=@yourchannel # or -1001234567890
export DATABASE_URL=postgresql://meme:meme@localhost:5432/meme_wrangler
# Optional pieces that mirror the Docker variables
# export POSTGRES_HOST=localhost
# export POSTGRES_PORT=5432
# Optional: where JSON backups are written
# export MEMEBOT_BACKUP_DIR=/path/to/backups
# export MEMEBOT_BACKUP_PASSWORD_HASH=<sha256 hash of your backup secret>
- Run the bot:
python bot.py
How it works
- Owner sends a photo/video/animation in the bot's DM.
- Bot stores the Telegram file_id and schedules it for the next available slot: 11:00, 16:00, 21:00 IST (India Standard Time). If there's an existing scheduled meme, new ones are scheduled after the last one using the same cycle.
- A background task posts due memes into the configured channel at the scheduled IST times.
Docker Implementation
This project includes full Docker support for easy deployment:
- Dockerfile: Creates a lightweight Python container with all dependencies
- docker-compose.yml: Simplifies running the bot alongside PostgreSQL with coordinated configuration
- Persistent storage:
pgdatavolume keeps the database cluster while./backupsstores exported JSON backups - Auto-restart: Container automatically restarts if it crashes
- Logging: Configured with log rotation (10MB max, 3 files)
The Docker implementation ensures consistent behavior across different environments and simplifies deployment to production servers.
Notes
- All times are in IST (India Standard Time, UTC+5:30) regardless of the server's timezone.
- Stored timestamps are Unix timestamps (UTC).
- Make sure the bot is admin in the channel to post messages.
- When using Docker Compose, PostgreSQL data lives in the
pgdatavolume and JSON backups are written to./backups/. - Use
/backup <secret>to export the full meme catalog (scheduled + posted) and/restore <secret>(replying to a backup file) to import it again. Validation happens against a baked-in SHA-256 hash; overrideMEMEBOT_BACKUP_PASSWORD_HASHif you need to supply your own hash. - Every new meme DM automatically triggers a fresh JSON backup stored under
./backups/(Compose) or the directory pointed toMEMEBOT_BACKUP_DIR.