Mangrullo
Mangrullo is a Docker container update automation tool written in Crystal. It monitors running Docker containers and automatically updates them to newer image versions, similar to Watchtower but with a focus on simplicity and reliability.
Features
- 🔍 Automatic Monitoring: Continuously monitors running Docker containers for image updates
- 📦 Semantic Versioning: Intelligent version comparison with support for major/minor/patch updates
- 🛡️ Safe Updates: Optional control over major version upgrades to prevent breaking changes
- 🏃 Dry Run Mode: Test what would be updated without making actual changes
- 📊 Detailed Logging: Comprehensive logging with configurable log levels
- 🔄 Flexible Scheduling: Run once or set up continuous monitoring with custom intervals
- 🔧 Easy Configuration: Simple command-line interface with sensible defaults
- 🎯 Container Filtering: Check specific containers by name instead of all containers
- 🔄 Container Recreation: Properly recreates containers with new images (like Watchtower)
- 🌐 Multi-Registry Support: Works with Docker Hub, GitHub Container Registry, and more
- 📝 YAML Config Files: Optional configuration file support for persistent settings
- 🐳 Official Docker Images: Multi-architecture images available on GHCR
Quick Start (Docker)
The easiest way to run Mangrullo is using the official Docker image:
docker run -d \
--name mangrullo \
-v /var/run/docker.sock:/var/run/docker.sock \
ghcr.io/ralsina/mangrullo:latest
This will start Mangrullo in daemon mode, checking for updates every hour (default: 3600 seconds).
Installation
Docker (Recommended)
Pull the latest image from GitHub Container Registry:
docker pull ghcr.io/ralsina/mangrullo:latest
See DOCKER.md for detailed Docker deployment instructions, including docker-compose examples and environment variable configuration.
Pre-built Binaries
Static binaries are available on the Releases page for multiple architectures:
mangrullo-static-linux-amd64- Linux x86_64mangrullo-static-linux-arm64- Linux ARM64mangrullo-web-static-linux-amd64- Web interface for Linux x86_64mangrullo-web-static-linux-arm64- Web interface for Linux ARM64
These binaries include all dependencies and don't require Crystal to be installed.
From Source
If you prefer to build from source or need to customize:
-
Install Crystal (>= 1.16.3) following the official installation guide
-
Clone the repository:
bash git clone https://github.com/ralsina/mangrullo.git cd mangrullo -
Install dependencies:
bash shards install -
Build the project:
bash shards build -
Install the binary (optional):
bash cp bin/mangrullo /usr/local/bin/
Usage
Basic Usage
Monitor running containers and update them when new images are available:
# Run once and exit
mangrullo --once
# Run continuously with default intervals
mangrullo
# Allow major version upgrades
mangrullo --allow-major
# Dry run to see what would be updated
mangrullo --dry-run
Command Line Options
Usage:
mangrullo [--interval=<seconds>] [--allow-major] [--socket=<path>]
[--log-level=<level>] [--once] [--dry-run] [<container-name>...]
[--help] [--version]
Options:
--interval=<seconds> Check interval in seconds [default: 300]
--allow-major Allow major version upgrades
--socket=<path> Docker socket path [default: /var/run/docker.sock]
--log-level=<level> Log level (debug, info, warn, error) [default: info]
--once Run once and exit
--dry-run Show what would be updated without actually updating
--help Show this help message
--version Show version information
Arguments:
<container-name> Specific container names to check (if not specified, checks all containers)
Note: The CLI default check interval is 300 seconds (5 minutes). The
Docker entrypoint defaults to a gentler 3600 seconds (1 hour) via
MANGRULLO_INTERVAL to stay friendly to registry rate limits.
Examples
Check for updates once:
mangrullo --once
Monitor every 10 minutes with debug logging:
mangrullo --interval=600 --log-level=debug
Test updates including major versions:
mangrullo --dry-run --allow-major
Check only specific containers:
mangrullo --once flatnotes atuin radicale
Check specific containers (with or without leading slash):
mangrullo --once /flatnotes atuin /radicale
Use custom Docker socket:
mangrullo --socket=/path/to/docker.sock
Web Interface
Mangrullo includes a fully-featured web interface that provides a modern dashboard for monitoring and managing Docker container updates.
Starting the Web Interface
# Build and run the web interface
shards build mangrullo-web
./bin/mangrullo-web
The web interface starts on http://localhost:3000 and provides:
- Dashboard: Real-time overview of all containers and their update status
- Auto-refresh: Automatic updates every 30 seconds, plus live SSE events
- Container Management: Check for updates and update individual containers
- Bulk Operations: Updates are queued through a job queue with dry-run support
- Dry Run Modal: Comprehensive results display showing what would be updated
- Mission Control Theme: Token-driven dark (default) and light modes with a toggle
- Brand Identity: Custom cell tower icon and favicon integration
Key Features
- Auto-refresh Dashboard: Container status automatically updates without manual refresh
- Live Events: Server-Sent Events push update progress (pull/stop/create/start) to the dashboard
- Dark/Light Theme: Toggle in the navbar, persisted in
localStorage - Embedded Static Assets: All CSS, JavaScript, and images are baked into the binary for easy deployment
- Responsive Design: Works on desktop and mobile devices with proper scaling
- Real-time Status: Live indicators for update checks and container operations
- Dry Run Support: Comprehensive dry run results with detailed tables showing update status
- Bulk Update Operations: Update all containers with major version control and dry run options
- Optional HTTP Basic Auth: Set
MANGRULLO_WEB_USERandMANGRULLO_WEB_PASSWORDto protect the UI - Custom Branding: Cell tower icon throughout the interface
- Favicon Support: Both SVG and ICO favicons with cell tower branding
Web Environment Variables
| Variable | Description | Default |
|---|---|---|
MANGRULLO_WEB_PORT |
Web interface port | 3000 |
MANGRULLO_WEB_HOST |
Bind address | 0.0.0.0 |
MANGRULLO_WEB_USER |
Basic auth user (both auth vars required) | unset |
MANGRULLO_WEB_PASSWORD |
Basic auth password | unset |
Web Interface Architecture
The web interface uses:
- Kemal: Fast web framework for Crystal
- Baked File System: Static assets embedded in the binary for zero-dependency deployment
- State Manager: Shared state between web requests and background operations
- Auto-refresh: JavaScript-based periodic updates every 30 seconds
- Server-Sent Events: Live update progress pushed from the update flow
- Pico.css v2 (self-hosted) reskinned by a token-driven stylesheet
- Google Fonts: Chivo, Chivo Mono and Space Grotesk
- Material Icons: Google Material Icons for consistent iconography
Configuration
Mangrillo supports flexible configuration through multiple methods with a clear precedence order:
Precedence (highest to lowest)
- Command-line arguments - Always take precedence
- Environment variables - Used when CLI argument is not provided
- Configuration file - YAML file for persistent settings
- Default values - Built-in defaults as last resort
Command-Line Options
mangrullo [--interval=<seconds>] [--allow-major] [--socket=<path>]
[--log-level=<level>] [--once] [--dry-run] [<container-name>...]
| Option | Description | Default |
|---|---|---|
--interval=<seconds> |
Check interval in seconds | 300 |
--allow-major |
Allow major version upgrades | false |
--socket=<path> |
Docker socket path | /var/run/docker.sock |
--log-level=<level> |
Logging level (debug, info, warn, error) | info |
--once |
Run once and exit | false |
--dry-run |
Show what would be updated without changes | false |
<container-name>... |
Specific containers to check | all containers |
Environment Variables
All options can be set via environment variables with the MANGRULLO_ prefix:
| Variable | Description | Example |
|---|---|---|
MANGRULLO_INTERVAL |
Check interval | MANGRULLO_INTERVAL=600 |
MANGRULLO_ALLOW_MAJOR |
Allow major upgrades | MANGRULLO_ALLOW_MAJOR=true |
MANGRULLO_SOCKET |
Docker socket path | MANGRULLO_SOCKET=/var/run/docker.sock |
MANGRULLO_LOG_LEVEL |
Logging level | MANGRULLO_LOG_LEVEL=debug |
MANGRULLO_RUN_ONCE |
Run once and exit | MANGRULLO_RUN_ONCE=true |
MANGRULLO_DRY_RUN |
Dry run mode | MANGRULLO_DRY_RUN=true |
Configuration File
Configuration-file plumbing exists via docopt-config, but no CLI flag
passes a config file path yet, so YAML configuration files are not
currently available — use environment variables instead.
Docker Socket
By default, Mangrullo connects to the Docker daemon at /var/run/docker.sock. You can specify a different path using the --socket option or MANGRULLO_SOCKET environment variable.
Version Handling
Mangrullo uses semantic versioning to determine when updates are available:
- Patch updates (1.0.0 → 1.0.1): Always applied by default
- Minor updates (1.0.0 → 1.1.0): Always applied by default
- Major updates (1.0.0 → 2.0.0): Only applied when
--allow-majoris specified
Image Support
Mangrullo works with:
- Standard image tags (nginx:1.2.3)
- Rolling single-number tags (postgres:16, redis:7 — compared by digest)
- Registry prefixes (docker.io/library/nginx:1.2.3)
- Registry ports (localhost:5000/my-app)
- SHA256 digest pins (compared by digest)
- Latest tags (compared by digest)
- Multiple registries:
- Docker Hub (registry-1.docker.io)
- GitHub Container Registry (ghcr.io)
- LinuxServer.io (lscr.io - maps to ghcr.io/linuxserver/)
- Other standard Docker registry v2 implementations
Update Execution
When an update is detected, Mangrullo:
- Pulls the target image (for versioned tags, the newer tag; for moving
tags like
latestorpostgres:16, the same reference with its new digest) - Stops the container and renames it to a temporary backup name
- Creates the replacement with the original configuration under the original name
- Starts it — and if anything fails, renames the backup back and restarts it
- Removes the backup once the replacement is confirmed running
Development
Prerequisites
- Crystal >= 1.16.3
- Docker (for testing)
- Git
Setup
- Clone the repository:
bash
git clone https://github.com/ralsina/mangrullo.git
cd mangrullo
- Install dependencies:
bash
shards install
- Run tests:
bash
crystal spec
- Build the project:
bash
shards build
Running Tests
The project includes comprehensive unit tests:
# Run all tests
crystal spec
# Run specific test file
crystal spec spec/mangrullo_spec.cr
# Run with verbose output
crystal spec --verbose
The test suite covers:
- Container name matching and filtering
- Registry mapping and authentication
- Container recreation logic
- Version parsing and comparison
- Image update detection algorithms
Code Style
- Follow Crystal language conventions
- Use 2-space indentation
- Module names are CamelCase
- Constants are UPPER_SNAKE_CASE
- Method names are snake_case
Format code with:
crystal tool format
Architecture
Mangrullo is built with a modular architecture:
- Types (
src/types.cr): Core data structures and version comparison logic - Docker Client (
src/docker_client.cr): Docker API wrapper and container recreation - Image Checker (
src/image_checker.cr): Version checking and update detection - Update Manager (
src/update_manager.cr): Coordinates the update process with container filtering - Job Queue (
src/update_job_queue.cr): Background update jobs with status polling - Configuration (
src/config.cr): Command-line argument parsing - CLI (
src/cli.cr): Main command-line interface - Web Server (
src/web.cr+src/web_server.cr): Kemal web interface (optional) - Web Views (
src/web_views.cr+src/templates/dashboard.ecr): Dashboard template - Static Assets (
src/static_assets.cr,public/): Embedded CSS, JavaScript, and images - State Manager (
src/state_manager.cr): Shared state management for web interface - SSE (
src/sse.cr): Server-Sent Events streaming for live updates - Web Auth (
src/web_auth.cr): Optional HTTP Basic authentication - Error Handling (
src/error_handling.cr): Centralized error management
Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
Development Workflow
- Fork the repository
- Create your feature branch (
git checkout -b my-new-feature) - Make your changes
- Add tests for new functionality
- Ensure all tests pass (
crystal spec) - Format your code (
crystal tool format) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin my-new-feature) - Create a new Pull Request
Reporting Issues
Please use the GitHub Issues page to report bugs or request features.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
- Inspired by Watchtower
- Built with Crystal
- Uses the docr Docker client library
- Uses docopt.cr for command-line parsing
Changelog
v0.8.0
- Grafito-style facelift: CRT terminal marketing site and a Mission Control dashboard theme (dark/light)
- Updates pull the correct newer target tag (previously re-pulled the stale tag), with rollback-safe container recreation
pull_imageno longer silently pulls:latest; Docker socket connections reconnect after idle timeouts- Real SSE streaming, async bulk updates through the job queue, honest job status (no more 404-as-success)
- Optional HTTP Basic auth, registry credentials from
~/.docker/config.json,MANGRULLO_WEB_PORT/MANGRULLO_WEB_HOSTsupport - Single-number tags (
postgres:16) and registry ports (localhost:5000/app) parsed correctly
v0.1.0
- Initial release
- Basic container monitoring and update functionality
- Semantic version comparison
- Major version upgrade control
- Dry run mode
- Command-line interface
- Container-specific filtering (check only specified containers)
- Container recreation (properly updates containers with new images)
- Multi-registry support (Docker Hub, GHCR, lscr.io)
- Web interface framework (Kemal-based)
- Flexible container name matching (handles both "name" and "/name")
- Comprehensive error handling and logging