Skip to content

Mangrullo

Crystal CI GitHub release License

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

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_64
  • mangrullo-static-linux-arm64 - Linux ARM64
  • mangrullo-web-static-linux-amd64 - Web interface for Linux x86_64
  • mangrullo-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:

  1. Install Crystal (>= 1.16.3) following the official installation guide

  2. Clone the repository: bash git clone https://github.com/ralsina/mangrullo.git cd mangrullo

  3. Install dependencies: bash shards install

  4. Build the project: bash shards build

  5. 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_USER and MANGRULLO_WEB_PASSWORD to 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)

  1. Command-line arguments - Always take precedence
  2. Environment variables - Used when CLI argument is not provided
  3. Configuration file - YAML file for persistent settings
  4. 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-major is 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:

  1. Pulls the target image (for versioned tags, the newer tag; for moving tags like latest or postgres:16, the same reference with its new digest)
  2. Stops the container and renames it to a temporary backup name
  3. Creates the replacement with the original configuration under the original name
  4. Starts it — and if anything fails, renames the backup back and restarts it
  5. Removes the backup once the replacement is confirmed running

Development

Prerequisites

  • Crystal >= 1.16.3
  • Docker (for testing)
  • Git

Setup

  1. Clone the repository:

bash git clone https://github.com/ralsina/mangrullo.git cd mangrullo

  1. Install dependencies:

bash shards install

  1. Run tests:

bash crystal spec

  1. 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

  1. Fork the repository
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Make your changes
  4. Add tests for new functionality
  5. Ensure all tests pass (crystal spec)
  6. Format your code (crystal tool format)
  7. Commit your changes (git commit -am 'Add some feature')
  8. Push to the branch (git push origin my-new-feature)
  9. 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

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_image no 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_HOST support
  • 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