A Telegram bot for managing Docker containers via docker.sock.
Designed for individual use - Perfect for managing personal home servers, remote development environments, or homelab setups. While it can technically be used in enterprise contexts, managing company service stacks through Telegram is not recommended for production environments.
- 🐳 Manage Docker containers through Telegram
- 🔧 Configurable command prefix (default:
/dg) - 🔐 User authentication via Telegram user IDs
- 🔌 Direct access to Docker daemon via socket
- 📊 Real-time container resource monitoring (CPU, memory, network, disk I/O)
- 📝 View container logs with configurable line count
- 📎 Automatic file attachment for large outputs (>4096 chars)
- 📦 Docker Compose project grouping
- 💾 Volume management with detailed inspection and pruning
- 🖼️ Image management (list, history, prune, remove)
▶️ Start/stop containers and projects with dependency handling- 🔄 Smart container restart with network dependency detection
- 🎯 Dependency-aware compose project operations (topological sort)
- 🛡️ Self-container protection (prevents accidental bot disconnection)
- 🤖 No command conflicts with other bots
- ✅ Comprehensive test suite
All commands require a prefix to avoid conflicts with other bots. The default prefix is /dg, but you can customize it via the COMMAND_PREFIX environment variable.
Information:
/<prefix> help- Show help message with available commands/<prefix> ps- List running containers/<prefix> all- List all containers (including stopped)/<prefix> status <name|id>- Get detailed container status (includes CPU/memory for running containers)/<prefix> log <name|id> [lines]- Get container logs (default: 50 lines)/<prefix> exec <name|id> <command> [args...]- Execute command in running container/<prefix> stats- Show resource stats for all running containers (grouped by project)/<prefix> stats <name|id> [<name|id> ...]- Show stats for specific container(s)/<prefix> stats -p <project> [<project> ...]- Show stats for compose project(s)/<prefix> stats --full|-f- Include network and block I/O stats
Container Control:
/<prefix> start <name|id> [<name|id> ...]- Start one or more containers/<prefix> start --with-deps|-w <name|id>- Start container and its network dependents (if stopped)/<prefix> start --restart-deps|-r <name|id>- Start container and restart its network dependents/<prefix> stop <name|id> [<name|id> ...]- Stop one or more containers/<prefix> stop --with-deps|-w <name|id>- Stop container and its network dependents/<prefix> restart <name|id>- Smart restart of a container (with network dependents)
Project Control:
/<prefix> start-project <project> [<project> ...]- Start compose project(s) in dependency order/<prefix> stop-project <project> [<project> ...]- Stop compose project(s) in reverse dependency order (with self-container protection)/<prefix> stop-project --force|-f <project>- Force stop including the bot itself/<prefix> restart-project <project>- Restart entire Docker Compose project (dependency-aware, with self-container protection)/<prefix> restart-project --force|-f <project>- Force restart including the bot itself
Volume Management:
/<prefix> volume ls [--detailed|-d]- List all Docker volumes (with optional container usage)/<prefix> volume <name>- Inspect a specific volume with container details/<prefix> volume prune [--all|-a]- Remove unused volumes (anonymous only, or all with --all)
Image Management:
/<prefix> image ls- List all Docker images with repository, tag, ID, creation date, and size/<prefix> image history <name|id>- Show image layer history/<prefix> image prune [--all|-a]- Remove unused images (dangling only, or all with --all)/<prefix> image rm <name|id> [<name|id> ...]- Delete specific image(s) not in use
Note: All flags support both long format (
--flag) and short format (-f) for convenience.
/dg help # Show help message
/dg ps # Quick list of running containers
/dg all # List all containers
/dg status nginx # Get status of container named "nginx"
/dg log nginx 100 # Get last 100 lines of logs
/dg exec nginx ls -la # Execute command in container
/dg exec app npm run test # Run tests inside app container
/dg exec db psql -U postgres -c "SELECT * FROM users LIMIT 10" # Query database
/dg stats # Show stats for all running containers
/dg stats nginx # Show stats for single container
/dg stats nginx app db # Show stats for multiple containers
/dg stats -p myapp # Show stats for entire project
/dg stats --full # Show stats with network & block I/O
/dg stats -f -p myapp # Show full stats for project
# Container control
/dg start nginx # Start single container
/dg start nginx app db # Start multiple containers
/dg start --with-deps gluetun # Start gluetun and any stopped dependents
/dg start -w gluetun # Same as --with-deps (shorthand)
/dg start --restart-deps gluetun # Start gluetun and restart running dependents
/dg start -r gluetun # Same as --restart-deps (shorthand)
/dg stop nginx app # Stop multiple containers
/dg stop --with-deps gluetun # Stop gluetun and its dependents
/dg stop -w gluetun # Same as --with-deps (shorthand)
/dg restart app # Restart with auto-detection of network dependents
# Project control
/dg start-project myapp # Start all containers in myapp project
/dg stop-project myapp media # Stop containers (skips bot if it's in the project)
/dg stop-project --force myapp # Force stop including bot itself
/dg stop-project -f myapp # Same as --force (shorthand)
/dg restart-project myapp # Restart entire project (skips bot if it's in the project)
/dg restart-project --force myapp # Force restart including bot itself
/dg restart-project -f myapp # Same as --force (shorthand)
# Volume management
/dg volume ls # List all volumes (compact view)
/dg volume ls --detailed # List volumes with container usage details
/dg volume ls -d # Same as --detailed (shorthand)
/dg volume my-volume # Inspect specific volume with container details
/dg volume prune # Remove unused anonymous volumes only
/dg volume prune --all # Remove ALL unused volumes (including named)
/dg volume prune -a # Same as --all (shorthand)
# Image management
/dg image ls # List all images
/dg image history nginx:latest # Show layer history for nginx image
/dg image prune # Remove dangling images only
/dg image prune --all # Remove ALL unused images
/dg image prune -a # Same as --all (shorthand)
/dg image rm nginx:old # Remove specific image
/dg image rm nginx:old redis:6 # Remove multiple images
For commands that may produce large output (ps, all, log, exec, stats, volume ls, image ls, image history):
- Small outputs (≤4096 chars): Displayed inline in Telegram with Markdown formatting
- Large outputs (>4096 chars): Automatically sent as a downloadable
.txtfile attachment
This ensures you never lose data due to Telegram's message length limits.
DockerGram provides real-time resource monitoring for your Docker containers. The stats command shows CPU usage, memory usage/limit/percentage, and optionally network and block I/O statistics.
Usage:
/dg stats # All running containers (grouped by project)
/dg stats <name|id> [...] # Specific container(s)
/dg stats -p <project> [...] # Entire project(s)
/dg stats --full|-f # Include network & block I/O stats
Examples:
/dg stats # Overview of all running containers
/dg stats nginx # Single container stats
/dg stats nginx redis postgres # Multiple containers
/dg stats -p media_server # All containers in a project
/dg stats --full # All containers with I/O stats
/dg stats -f -p myapp # Project stats with I/OWhat's Included:
- CPU Usage: Percentage based on host CPU cores
- Memory: Usage / Limit (Percentage)
- Network I/O (with
--full): RX/TX bytes across all interfaces - Block I/O (with
--full): Read/Write bytes
Important Notes:
- Only works on running containers
- Stats are real-time snapshots (not averages)
- CPU percentage can exceed 100% on multi-core systems (e.g., 200% = using 2 cores fully)
- Large stats outputs automatically sent as downloadable files
- The
statuscommand also includes CPU/memory stats for running containers
The exec command allows you to run arbitrary commands inside running containers, similar to docker exec -it <container> <command>.
Usage:
/dg exec <container-name|id> <command> [args...]
Examples:
/dg exec nginx ls -la # List files in nginx container
/dg exec nginx cat /etc/nginx/nginx.conf # View nginx config
/dg exec app npm run test # Run tests
/dg exec db psql -U postgres -c "SELECT version()" # Query PostgreSQL
/dg exec redis redis-cli INFO stats # Get Redis stats
Important Notes:
- Only works on running containers
- Captures both stdout and stderr
- Output sent as file if it exceeds Telegram's message limit
- Commands run non-interactively (no TTY allocation)
- Useful for quick debugging, inspections, and one-off commands
DockerGram provides comprehensive volume management capabilities for inspecting, monitoring, and cleaning up Docker volumes.
Usage:
/dg volume ls [--detailed|-d] # List all volumes
/dg volume <name> # Inspect specific volume
/dg volume prune [--all|-a] # Remove unused volumes
Volume Listing:
/dg volume ls # Quick list: name, driver, size
/dg volume ls --detailed # Detailed: includes containers using each volumeThe detailed view shows which containers are using each volume (running or stopped), making it easy to understand volume usage across your system.
Volume Inspection:
/dg volume my-data # Get detailed info for specific volumeShows:
- Volume name and driver
- Mount point path
- Labels (compose project, etc.)
- Size and reference count
- All containers using this volume (with state)
Volume Pruning:
/dg volume prune # Remove unused anonymous volumes only (safe)
/dg volume prune --all # Remove ALL unused volumes (including named)Docker distinguishes between:
- Anonymous volumes: Auto-generated names (e.g.,
a1b2c3d4e5f6...) - Named volumes: User-specified names (e.g.,
db-data,my-volume)
By default, prune only removes unused anonymous volumes (Docker's default behavior). Use --all to remove all unused volumes including named ones.
Important Notes:
- Volume list with
--detailedmay be sent as file if you have many volumes - Pruning is permanent - deleted volumes cannot be recovered
- A volume is "unused" if no containers (running or stopped) reference it
- The bot will show you exactly which volumes will be deleted and space reclaimed
DockerGram provides comprehensive image management capabilities for listing, inspecting, cleaning, and removing Docker images.
Usage:
/dg image ls # List all images
/dg image history <name|id> # Show image layer history
/dg image prune [--all|-a] # Remove unused images
/dg image rm <name|id> [...] # Delete specific images
Image Listing:
/dg image ls # Shows: repository, tag, ID, creation date, sizeDisplays all images on your Docker daemon with total size summary. Large lists are automatically sent as downloadable files.
Image History:
/dg image history nginx:latest # View layer-by-layer build history
/dg image history abc123def456 # Works with image IDs tooShows detailed layer history including:
- Layer ID
- Creation timestamp
- Layer size
- Build command used
Perfect for understanding image composition and debugging build issues. Large histories are sent as files.
Image Pruning:
/dg image prune # Remove dangling images only (safe)
/dg image prune --all # Remove ALL unused imagesDocker distinguishes between:
- Dangling images: Untagged layers from builds (e.g.,
<none>:<none>) - Unused images: Tagged images not referenced by any containers
By default, prune only removes dangling images (Docker's default behavior). Use --all to remove all unused images including tagged ones.
Image Removal:
/dg image rm nginx:latest # Remove single image
/dg image rm nginx:old redis:6 # Remove multiple images at onceRemoves specific images with validation:
- Checks if image is in use by any container (running or stopped)
- Prevents accidental removal of images needed by containers
- Supports batch removal with per-image success/failure reporting
- Shows descriptive error if image is in use
Important Notes:
- Only removes images not referenced by any containers (running or stopped)
- Pruning and removal are permanent - deleted images must be re-pulled or rebuilt
- An image is "unused" if no containers reference it in their Image or ImageID fields
- The bot shows exactly which images will be deleted and space reclaimed
- Use
docker pullto re-download removed images if needed
- Docker daemon running
- Telegram Bot Token (from @BotFather)
- Your Telegram User ID (send
/startto @userinfobot)
docker run -d \
--name dockergram \
--restart unless-stopped \
-v /var/run/docker.sock:/var/run/docker.sock \
-e TELEGRAM_BOT_TOKEN=your_bot_token_here \
-e ALLOWED_USER_IDS=123456789 \
-e COMMAND_PREFIX=dg \
luall0/dockergram:latestCreate a docker-compose.yml:
services:
dockergram:
image: luall0/dockergram:latest
container_name: dockergram
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
TELEGRAM_BOT_TOKEN: your_bot_token_here
ALLOWED_USER_IDS: 123456789,987654321 # Comma-separated for multiple users
COMMAND_PREFIX: dg # Optional, defaults to 'dg'
DOCKER_SOCKET_PATH: /var/run/docker.sock # Optional, defaults to this path
ALLOW_SELF_RESTART: false # Optional, prevents accidental bot disconnection
healthcheck:
test: ["CMD", "node", "dist/healthcheck.js"]
interval: 30s
timeout: 5s
start_period: 10s
retries: 3Start the bot:
docker compose up -dEnvironment Variables:
TELEGRAM_BOT_TOKEN(required): Your Telegram bot token from BotFatherALLOWED_USER_IDS(required): Comma-separated list of authorized Telegram user IDsCOMMAND_PREFIX(optional): Command prefix for bot commands (default:dg)DOCKER_SOCKET_PATH(optional): Path to Docker socket (default:/var/run/docker.sock)ALLOW_SELF_RESTART(optional): Allow project commands to stop/restart the bot (default:false)
Health Check: The Docker image includes a built-in health check that verifies:
- Docker daemon connectivity (via
docker.ping()) - Telegram API connectivity (via
bot.telegram.getMe())
The health check runs every 30 seconds and marks the container as unhealthy if either check fails. This allows Docker Compose or orchestration tools to automatically restart the container if connectivity is lost.
For development or building from source:
Prerequisites:
- Node.js >= 18.0.0
- Yarn package manager
-
Clone the repository
-
Install dependencies:
yarn install
-
Copy
.env.exampleto.envand configure:cp .env.example .env
-
Set your environment variables in
.env:TELEGRAM_BOT_TOKEN: Your Telegram bot tokenDOCKER_SOCKET_PATH: Path to Docker socket (default:/var/run/docker.sock)COMMAND_PREFIX: Command prefix for all bot commands (default:dg)ALLOWED_USER_IDS: Comma-separated list of authorized Telegram user IDs
Run in development mode with hot reload:
yarn devCompile TypeScript to JavaScript:
yarn buildRun the compiled bot:
yarn startyarn dev- Run in development mode with hot reloadyarn build- Compile TypeScriptyarn start- Run production buildyarn lint- Lint the codebaseyarn typecheck- Type check without emitting filesyarn test- Run all testsyarn test:watch- Run tests in watch modeyarn test:coverage- Generate test coverage report
DockerGram provides intelligent container and project management with dependency-aware operations. This goes beyond Docker's basic commands and is critical for containers using shared network namespaces.
When you use Docker's basic restart command on a container that shares its network with dependents (using network_mode: "service:<container>" or container:<id>), the dependent containers lose network connectivity:
- Parent container (e.g., gluetun VPN) restarts
- Docker creates a new network namespace for the parent
- Dependent containers (e.g., qbittorrent) remain attached to the old namespace
- ❌ Network connectivity breaks - containers can no longer communicate
This is especially critical for:
- VPN containers (gluetun, wireguard) with services routing through them
- Reverse proxies (nginx, traefik) with services using their network
- Network sidecars (tailscale, cloudflared) sharing network namespaces
Example Docker Compose setup:
services:
gluetun:
image: qmcgaw/gluetun
# VPN configuration
qbittorrent:
image: linuxserver/qbittorrent
network_mode: "service:gluetun" # Routes through gluetun's VPN
depends_on:
- gluetunStart a container with its dependents:
/dg start --with-deps gluetun
/dg start -w gluetun # Short form
- Starts gluetun first
- Then starts any dependent containers that are stopped
- Perfect for bringing up a VPN with its services
Start a container and restart running dependents:
/dg start --restart-deps gluetun
/dg start -r gluetun # Short form
- Starts gluetun
- Force-restarts any running dependents (to re-attach to new network namespace)
- Use when you need dependents to reconnect immediately
Stop a container with its dependents:
/dg stop --with-deps gluetun
/dg stop -w gluetun # Short form
- Stops dependents first (clean shutdown)
- Then stops the parent container
- Maintains proper shutdown order
Automatically detects and restarts network-dependent containers:
/dg restart gluetun
What happens:
- ✅ Detects qbittorrent uses gluetun's network
- ✅ Stops qbittorrent first
- ✅ Stops and starts gluetun (creates new namespace)
- ✅ Starts qbittorrent (attaches to new namespace)
- ✅ Shows you which dependents were restarted
Why stop-then-start instead of restart?
- Docker's
restartcommand doesn't allow dependents to detach/reattach - We use
stop()→start()sequence to ensure clean namespace recreation - This is the only way to preserve network connectivity
Start entire Docker Compose projects in dependency order:
/dg start-project media_server
What happens:
- ✅ Analyzes
depends_onlabels andnetwork_modesettings - ✅ Builds dependency graph with topological sort
- ✅ Starts containers in correct order (parents before children)
- ✅ Handles complex multi-level dependencies automatically
Stop entire Docker Compose projects in reverse dependency order:
/dg stop-project media_server
What happens:
- ✅ Analyzes dependencies
- ✅ Stops containers in reverse order (children before parents)
- ✅ Ensures clean shutdown without breaking dependencies
Restarts entire Docker Compose projects in dependency order:
/dg restart-project media_server
What happens:
- ✅ Stops ALL containers in the project
- ✅ Analyzes
depends_onlabels andnetwork_modesettings - ✅ Builds dependency graph with topological sort
- ✅ Starts containers in correct order (parents before children)
- ✅ Handles complex multi-level dependencies automatically
Why this matters:
- Docker Compose's
restart: truefeature only works withdocker composecommands - DockerGram uses the Docker API directly (bypasses Docker Compose)
- We implement dependency resolution at the API level
- Ensures services like tailscale start after nginx, qbittorrent starts after gluetun, etc.
When DockerGram runs inside a Docker Compose project, there's a risk of accidentally stopping or restarting the bot itself, causing immediate disconnection. To prevent this, DockerGram includes self-container protection.
How It Works:
- The bot's Docker image includes a label:
dockergram.self=true - When you run
stop-projectorrestart-project, the bot automatically skips itself - You'll see a message: "
⚠️ Skipped 1 self-container(s): dockergram. Use --force to override" - Direct container commands (
stop,restart) are never restricted
Overriding Protection:
There are two ways to override this protection when you need to restart the bot:
-
Per-command override (use
--forceor-fflag):/dg stop-project --force myproject /dg stop-project -f myproject # Short form /dg restart-project --force myproject /dg restart-project -f myproject # Short form -
Global override (set environment variable):
environment: ALLOW_SELF_RESTART: true
Important Notes:
start-projecthas no protection - starting a stopped bot is harmless (you need the bot running to issue commands)- Direct container commands (
/dg stop dockergram,/dg restart dockergram) always work - advanced users retain full control - Protection only applies to project-level operations where accidental disconnection is most likely
Network Mode Detection: DockerGram detects dependencies by checking for:
network_mode: "container:<name>"network_mode: "service:<name>"network_mode: "container:<full-64-char-id>"network_mode: "container:<short-12-char-id>"
Dependency Resolution:
- Parses
com.docker.compose.depends_onlabels from containers - Builds dependency graph using Kahn's topological sort algorithm
- Avoids double-counting (e.g., when both
depends_onandnetwork_modereference same container) - Falls back gracefully on circular dependencies
| Operation | Basic Docker Commands | DockerGram Dependency-Aware |
|---|---|---|
| Start container | ✅ Works | ✅ Works + optional dependent handling |
| Stop container | ✅ Works | ✅ Works + optional dependent handling |
| Restart container | ❌ Breaks network dependents | ✅ Auto-restarts dependents |
| Start compose project | ❌ Random order | ✅ Respects dependency order |
| Stop compose project | ❌ Random order | ✅ Reverse dependency order |
| VPN + apps setup | ❌ Apps lose VPN on restart | ✅ Maintains VPN routing |
| Reverse proxy + services | ❌ Services lose proxy | ✅ Maintains proxy connection |
You can set any prefix you want in your .env file:
COMMAND_PREFIX=docker # Use /docker ps, /docker all, etc.
COMMAND_PREFIX=bot # Use /bot ps, /bot all, etc.Note: All commands require the configured prefix. Commands without the prefix will be ignored to prevent conflicts with other bots.
dockergram/
├── src/
│ ├── commands/ # Bot command handlers
│ ├── config/ # Configuration management
│ ├── middleware/ # Telegraf middleware (auth, prefix, etc.)
│ ├── services/ # Docker service integration
│ ├── utils/ # Utility functions (logger, formatters, etc.)
│ └── index.ts # Application entry point
├── tests/
│ ├── helpers/ # Shared test utilities
│ ├── unit/ # Unit tests (pure functions)
│ └── integration/ # Integration tests (with mocks)
├── .env.example # Environment variables template
├── jest.config.js # Jest test configuration
├── package.json # Project dependencies
└── tsconfig.json # TypeScript configuration
DockerGram includes a comprehensive test suite covering unit and integration scenarios.
# Run all tests
yarn test
# Run tests in watch mode (for development)
yarn test:watch
# Generate coverage report
yarn test:coverage-
Unit Tests (
tests/unit/): Test pure functions without external dependencies- Formatters (container list formatting, status formatting)
- Telegram utilities (message size handling)
-
Integration Tests (
tests/integration/): Test components with mocked dependencies- Command handlers (ps, all, status, log, exec, stats, start, stop, restart, start/stop/restart-project, volume, image)
- Docker service operations (including exec, stats, volume management, image management, network dependency detection and topological sort)
- Authentication middleware
- ✅ No External Dependencies: All tests use mocks (no real Docker or Telegram required)
- ✅ Fast Execution: Tests run quickly without external services
- ✅ Type-Safe Mocking: Uses
jest-mock-extendedfor TypeScript support - ✅ CI/CD Ready: Perfect for continuous integration pipelines
When adding new features:
- Commands: Add integration tests in
tests/integration/<command>.command.test.ts - Utilities: Add unit tests in
tests/unit/<module>.test.ts - Use shared helpers from
tests/helpers/test-utils.tsto reduce duplication
See CLAUDE.md for detailed testing guidelines and patterns.
This bot requires access to the Docker socket, which provides full control over Docker. Ensure you:
- Configure
ALLOWED_USER_IDSto restrict access - Never expose your bot token
- Run with appropriate permissions
- Review and understand the security implications
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Ensure all tests pass (
yarn test) - Submit a pull request
Big shoutout to Claude Code and Anthropic for building such an incredible tool that empowers developers and makes building projects like this so much more efficient and enjoyable.
Apache 2.0