Monitor your Docker containers for image updates and manage them directly via Telegram.
- Automatic update detection — compares local and remote image digests on a configurable cron schedule
- Telegram notifications — get notified when updates are available, with inline action buttons
- Per-container or bulk updates — update individual containers or all at once
- Per-container auto-update — selected containers update automatically without confirmation (
/autoupdate) - Pin/Freeze containers — exclude containers from updates via Telegram (
/pin,/unpin) - Partial name matching — type just the beginning of a container name (e.g.
/pin ngi→nginx) - Update history — persistent log of all updates, viewable via
/historyor the Web UI - Health check after update — verifies the container is running (and healthy) after recreation
- Auto-rollback — failed updates or health checks automatically restore the previous container
- Self-update — the bot can update itself via
/selfupdateor automatically withAUTO_SELFUPDATE=true - Cleanup — remove old unused images via
/cleanup - Debug mode — toggle detailed diagnostics via
/debug - Multi-language — 16 languages included, switch via
/langor add your own - Optional Web UI — dashboard with status, history, and settings, password-protected
- Works with and without Docker Hub login — credentials are optional
- Docker Compose support — detects Compose stacks and uses native
docker compose pull/upfor updates - Lightweight — Python standard library only, no extra dependencies
- Docker-native — runs as a container, manages containers via Docker socket
- Message @BotFather on Telegram
- Send
/newbotand follow the instructions - Copy the bot token
Send a message to your bot, then open:
https://api.telegram.org/bot<YOUR_TOKEN>/getUpdates
Look for "chat":{"id":YOUR_CHAT_ID} in the response.
docker run -d \
--name docker-telegram-updater \
--restart unless-stopped \
-e BOT_TOKEN=your-bot-token \
-e CHAT_ID=your-chat-id \
-v /var/run/docker.sock:/var/run/docker.sock \
amayer1983/docker-telegram-updater:latestThat's it — the bot will check for updates daily at 18:00 and notify you via Telegram.
services:
docker-telegram-updater:
image: amayer1983/docker-telegram-updater:latest
container_name: docker-telegram-updater
restart: unless-stopped
environment:
- BOT_TOKEN=your-bot-token
- CHAT_ID=your-chat-id
- CRON_SCHEDULE=0 18 * * *
- TZ=Europe/Berlin
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- updater_data:/data
security_opt:
- no-new-privileges:true
volumes:
updater_data:Run docker login on your host first, then add this volume:
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- updater_data:/data
- /root/.docker/config.json:/.docker/config.json:ro| Command | Description |
|---|---|
/check |
Manually trigger an update check |
/status |
Show all running containers and their status |
/updates |
Show pending updates |
/history |
Show update history (last 10 entries) |
| Command | Description |
|---|---|
/pin <name> |
Pin a container — excluded from updates. Without name: show pinned list |
/unpin <name> |
Unpin a container — included in updates again |
/autoupdate <name> |
Toggle auto-update for a container — updates without confirmation. Without name: show list |
/cleanup |
Remove old unused Docker images |
| Command | Description |
|---|---|
/selfupdate |
Update the bot itself to the latest version |
/debug |
Toggle debug mode for detailed diagnostics |
/lang <code> |
Switch language (e.g. /lang en, /lang de) |
/settings |
Show current configuration |
/help |
Show available commands and version |
Partial name matching: You don't need to type the full container name.
/pin ngiwill matchnginxif it's the only container starting with "ngi". If multiple containers match, the bot shows all options.
When updates are found, you receive a Telegram message with image sizes, dates, and action buttons:
🔄 Docker Updates Available
• nginx (nginx:latest)
📦 141 MB | 📅 Current: 2026-03-15
• redis (redis:7)
📦 117 MB | 📅 Current: 2026-03-20
[🔄 nginx (141 MB)]
[🔄 redis (117 MB)]
[🚀 Update all] [✋ Manual]
- Individual buttons — update a single container, button changes to ✅ when done
- 🚀 Update all — pull and restart all containers at once
- ✋ Manual — dismiss and handle updates yourself
- The bot pulls the new image
- Stops the old container and renames it as backup
- Recreates the container with the same configuration (ports, volumes, environment, labels, networks)
- Runs a health check — waits up to 30 seconds, verifying the container is running (and healthy, if a Docker HEALTHCHECK is defined)
- On success: removes the backup and logs the update to history
- On failure: automatically rolls back to the previous container
Containers set to auto-update (/autoupdate nginx) are updated automatically during scheduled checks — no button press needed. The bot sends a summary after completion. All other containers still show the usual notification with buttons.
Pinned containers (/pin nginx) are completely excluded from update checks. Use this for containers you want to keep on a specific version. Unpin anytime with /unpin nginx.
| Variable | Default | Description |
|---|---|---|
BOT_TOKEN |
required | Telegram Bot API token |
CHAT_ID |
required | Your Telegram chat ID |
CRON_SCHEDULE |
0 18 * * * |
Cron expression for scheduled checks |
EXCLUDE_CONTAINERS |
Comma-separated container names to permanently exclude | |
AUTO_SELFUPDATE |
false |
Automatically update the bot on each scheduled check |
LANGUAGE |
en |
Bot language (see Multi-Language) |
WEB_UI |
false |
Enable optional web dashboard |
WEB_PORT |
8080 |
Web UI port (inside container) |
WEB_PASSWORD |
Password for Web UI (Basic Auth). Leave empty for no protection | |
TZ |
Europe/Berlin |
Timezone for scheduling |
| Schedule | Description |
|---|---|
0 18 * * * |
Daily at 18:00 |
0 9,18 * * * |
Twice daily at 9:00 and 18:00 |
0 18 * * 1-5 |
Weekdays at 18:00 |
*/30 * * * * |
Every 30 minutes |
There are two ways to exclude containers from updates:
| Method | How | Persistent | Use case |
|---|---|---|---|
EXCLUDE_CONTAINERS env var |
Set at container start | Across restarts | Permanently exclude containers |
/pin command in Telegram |
Send /pin <name> |
Saved to data volume | Temporarily freeze a container version |
Enable a lightweight web dashboard for status overview, update history, and settings:
docker run -d \
--name docker-telegram-updater \
-e BOT_TOKEN=your-bot-token \
-e CHAT_ID=your-chat-id \
-e WEB_UI=true \
-e WEB_PASSWORD=your-secret \
-p 8080:8080 \
-v /var/run/docker.sock:/var/run/docker.sock \
amayer1983/docker-telegram-updater:latestThe Web UI is disabled by default to keep the container minimal. When enabled, it provides:
- Status page — live container overview with health badges and pending update count
- History page — full update log with timestamps, results, and details
- Settings page — change language, debug mode, and auto-selfupdate via browser
- Update check — trigger a check from the dashboard
The Web UI is fully translated — it follows the configured language.
Access it at http://your-server:8080 with the configured password.
16 languages are included out of the box:
🇬🇧 English · 🇩🇪 Deutsch · 🇫🇷 Français · 🇪🇸 Español · 🇮🇹 Italiano · 🇳🇱 Nederlands · 🇧🇷 Português · 🇵🇱 Polski · 🇹🇷 Türkçe · 🇷🇺 Русский · 🇺🇦 Українська · 🇸🇦 العربية · 🇮🇳 हिन्दी · 🇯🇵 日本語 · 🇰🇷 한국어 · 🇨🇳 中文
Switch language:
- Via Telegram:
/lang de,/lang fr, etc. - Via Web UI: Settings page
- Via environment variable:
LANGUAGE=de
Missing your language or found a translation error? Open an issue or submit a pull request — contributions are welcome!
Add your own language:
Create a JSON file in the lang/ directory (e.g. sv.json for Swedish) with all translation keys. Use en.json as a template. The bot picks up new files automatically — no code changes needed. You can also mount a custom lang directory:
volumes:
- ./my-languages:/app/langThe bot automatically detects containers managed by Docker Compose via container labels. When updating a Compose-managed container, the bot uses the native Compose workflow:
docker compose pull <service>— pulls the new imagedocker compose up -d --no-deps <service>— recreates only the updated service- Health check and automatic rollback on failure
This preserves all Compose-specific configuration (depends_on, networks, deploy settings) that would be lost with a plain docker run recreation.
Requirements: The Compose file must be accessible from inside the bot container. Mount the directory containing your docker-compose.yml:
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- updater_data:/data
- /path/to/your/stacks:/stacks:roIf the Compose file is not accessible (e.g. Portainer-managed stacks stored in a database), the bot automatically falls back to the standard docker run recreation method.
Compose-managed containers are marked with a 🐳 icon in update notifications.
- On the configured schedule, the bot compares local image digests with remote registry digests via the Docker Registry HTTP API
- Pinned containers and containers in
EXCLUDE_CONTAINERSare skipped - If updates are found, containers on the auto-update list are updated immediately
- Remaining updates are sent as a Telegram notification with inline action buttons
- When you press update, the bot uses Docker Compose (if detected) or docker run to recreate the container, then runs a health check
- If recreation or health check fails, the old container is automatically restored (rollback)
- All updates (success and failure) are logged to the update history
- The bot's own container (use
/selfupdateinstead) - Containers running with image IDs instead of tags (locally built images)
- Containers in the
EXCLUDE_CONTAINERSlist - Pinned containers (
/pin)
| Update checks | Image pulls | |
|---|---|---|
| Without login | Unlimited (uses registry API) | 100 per 6 hours |
| With login | Unlimited | Unlimited |
Update checks use the registry API and do not count against pull limits. For most setups without login, the rate limit is not an issue.
If the credentials file doesn't exist, simply leave out the volume mount — the bot works fine without it.
- The Docker socket is required for container management
- Only the configured
CHAT_IDcan interact with the bot no-new-privilegessecurity option is recommended- No external dependencies beyond Python standard library and Docker CLI
- Docker credentials are mounted read-only
- Web UI password is hashed (SHA-256), never stored in plain text
MIT License - see LICENSE







