Please ⭐ this repo if you find it useful
DockerBot is an easy-to-use Telegram bot, written in Python, that runs as a Docker container. It lets you manage the Docker containers on your server (list, start, stop and restart them) and check the state of the host (disk, memory, time, external IP and internet speed) straight from a Telegram chat. Only the Telegram users you allow can use it.
The current source uses python-telegram-bot
(v13) and the Docker SDK for Python. Older versions of the
code (including the image currently tagged latest on Docker Hub) were built on
Telepot.
Known issue: the current source does not start on Python 3.12 (the version used by the
Dockerfile). See Known issue: current source does not start.
- Features
- Screenshots
- How it works
- Requirements
- Installation
- Configuration
- Usage
- Security notes
- Troubleshooting
- Development
- Contributing
- Credits
- License
With DockerBot you can:
- List existing containers (running and stopped) with their status.
- Start, stop and restart containers.
- Run a Speedtest and get the shareable result image.
- Get memory status (used, free, etc.).
- Get disk status.
- Get the server time.
- Get the server's real (external) IP.
- Check that the bot is alive.
- Restrict access to a list of allowed Telegram user IDs. Anyone else gets a "No Trespassing" image.
dockerbot.pyconnects to Telegram with long polling (no webhook and no open inbound port is needed) using the bot token fromAPI_KEY.- Every command first checks the sender's Telegram user ID against
ALLOWED_IDS. - Container commands talk to the Docker daemon through the Docker SDK (
docker.from_env()), normally over the mounted/var/run/docker.sock. - Host commands run small programs inside the container:
speedtest-cli --share,curl ipinfo.io/ip,df -handcat /proc/meminfo.
- Docker (and optionally Docker Compose) on the host you want to manage.
- A Telegram bot token. If you don't have a bot yet, create one with @BotFather; see Bots: An introduction for developers.
- Your Telegram user ID (see Configuration).
- Outbound internet access (Telegram API,
ipinfo.ioand the Speedtest servers).
The image is published on Docker Hub as
techblog/dockerbot (linux/amd64,
linux/arm64, linux/arm/v7).
Note: the
latesttag on Docker Hub was built on 2021-07-21 by an older workflow, from the older Telepot-based code. Its commands and access rules differ from the current source:
- It has
/startand/?(no/help), and its/startcommand list works.- It checks the chat ID, not the user ID, and it does a substring match against the
ALLOWED_IDSstring. For example,12345is accepted when123456789is allowed. In a group, the group's chat ID is checked.- If
ALLOWED_IDSis not set, every message fails with an error instead of being rejected.Unless noted otherwise, the rest of this README describes the current source.
services:
dockerbot:
image: techblog/dockerbot
container_name: dockerbot
restart: always
environment:
- API_KEY= # Required: your bot token
- ALLOWED_IDS= # Required: comma-separated Telegram user IDs
volumes:
- /var/run/docker.sock:/var/run/docker.sockThe repository's docker-compose.yml also sets network_mode: host,
cap_add: NET_ADMIN and privileged: true. The bot's code does not need any of these; the Docker
socket mount is the only requirement. Leave them out unless you have a reason to keep them (see
Security notes).
docker compose up -ddocker run -d \
--name dockerbot \
--restart always \
-e API_KEY="<your bot token>" \
-e ALLOWED_IDS="<your user id>" \
-v /var/run/docker.sock:/var/run/docker.sock \
techblog/dockerbotThe current source cannot run as it stands, so building the image from source is not a working install method at the moment:
python-telegram-bot13.15 fails to import on Python 3.12 (its vendoredurllib3breaks, and its fallback needsurllib3<2, whilerequirements.txtrequiresurllib3>=2.2.2).- Its
APSchedulerdependency needspkg_resources, which recentsetuptoolsno longer provides.
The Dockerfile uses python:3.12-slim, so an image built from the current source is affected
too. Until this is fixed, the published Docker Hub image is the only runnable version.
DockerBot is configured only with environment variables:
| Variable | Required | Default | Description |
|---|---|---|---|
API_KEY |
Yes | (empty) | Telegram bot token. In the current source, the bot exits at startup with API_KEY environment variable is not set if it is missing. |
ALLOWED_IDS |
Yes | (empty) | Comma-separated list of allowed IDs, e.g. 123456789,987654321. In the current source these are Telegram user IDs, matched exactly, spaces around IDs are ignored, and an empty value means nobody can use the bot. The published image checks chat IDs by substring (see Docker image). |
The Docker SDK also honours the standard Docker client variables (DOCKER_HOST,
DOCKER_TLS_VERIFY, DOCKER_CERT_PATH), so you can point the bot at a remote daemon instead of
mounting the socket.
To get your ID, open @myidbot in Telegram and send the /getid command.
The result is your ID:
Open a chat with your bot and send one of these commands:
| Command | Description |
|---|---|
/start, /help |
Show the command list. |
/list_containers |
List all containers (running and stopped) with their status, each followed by its start/stop/restart commands. |
/<container>_start |
Start a container. |
/<container>_stop |
Stop a container. |
/<container>_restart |
Restart a container. |
/time |
Get the server's local time. |
/speed |
Run a Speedtest (speedtest-cli --share) and send the result image. This takes a while. |
/ip |
Get the server's external IP (from ipinfo.io). |
/disk |
Get disk usage (df -h). |
/mem |
Get memory info (/proc/meminfo). |
/stat |
Check that the bot is alive (replies "Number five is alive!"). |
For container commands, <container> is the exact container name, e.g. /nginx_restart. After
the action the bot waits two seconds and reports the container's new status. You can tap the
commands in the /list_containers output instead of typing them.
/disk and /mem run inside the DockerBot container: /mem shows the host's memory, while
/disk shows the file systems visible to the container.
These notes describe the current source unless stated otherwise.
- Mounting
/var/run/docker.sockgives the bot root-equivalent access to the host. Anyone who can control the bot can start, stop and restart any container. Keep your bot token secret and keepALLOWED_IDSshort. - Access is checked against the sender's Telegram user ID (exact match). If you add the bot to a group, allowed users can run commands there and every group member sees the replies.
- The published Docker Hub image instead does a substring match of the chat ID against
ALLOWED_IDS, so an unlisted ID that is part of an allowed ID is accepted. Use long, full IDs and don't add that image to groups. privileged: true,NET_ADMINand host networking from the sampledocker-compose.ymlare not used by the bot. Removing them reduces the container's privileges.- Unauthorized attempts are logged with the sender's user ID
(
Unauthorized access attempt from user ID: ...).
The messages below come from the current source; the published image's messages differ.
- The bot exits right away: check the container logs (
docker logs dockerbot). The messageAPI_KEY environment variable is not setmeans the token is missing. - The bot replies with a "No Trespassing" image: your user ID is not in
ALLOWED_IDS. Check the logs for the ID that was rejected and add it. /startor/helpshows an empty command list: the current source builds this list by scanning its own code, and that scan currently finds no commands. Use the table in Usage instead./list_containersfails withError listing containers: ..., or a start/stop/restart command fails withError starting container: ...(orstoping/restarting): the Docker socket is not mounted or not reachable. Mount/var/run/docker.sockas shown above.Container '<name>' not found: the name must match the container name exactly. Names with a dot (.) cannot be used as commands. Telegram does not make names with a hyphen (-) tappable, but you can still type them./diskrepliesError getting disk space: ...: a very longdf -houtput (for example on a host with many mounts) can exceed Telegram's message size limit.- "An error occurred while processing your request.": an unhandled error; the details are in the container logs.
Project layout:
dockerbot.py # the bot
requirements.txt # Python dependencies
Dockerfile # python:3.12-slim image (adds curl)
docker-compose.yml # sample Compose file
scripts/next-version.sh # computes the next YYYY.M.PATCH version
.github/workflows/ # manual Docker Hub and GHCR publishing workflows
Running the current source locally or building its image does not work at the moment; see Known issue: current source does not start.
To add a command, write a handler and register it with dp.add_handler(CommandHandler(...)) in
main(). The #[ description ]# marker comment on a handler's def line is meant to add it to
the /start list, but it currently has no effect (see the empty command list under
Troubleshooting).
The repository has two manually triggered GitHub Actions workflows for linux/amd64,
linux/arm64 and linux/arm/v7: Docker Build pushes <DOCKERHUB_USERNAME>/dockerbot (the
image name comes from a repository secret), and Publish to GHCR pushes ghcr.io/t0mer/dockerbot.
Neither has published anything yet: there are no version tags, Docker Hub has no image newer than
2021, and no GHCR image is publicly visible. The current Docker Hub latest was pushed by an older
workflow.
Issues and pull requests are welcome. Please keep changes focused and describe how you tested them.
- Adam Russak for working with me on this project.
This project is licensed under the Apache License 2.0.