Deep Dive & Technical Overview

Docker Image Updater Logo

Docker Image Updater

Automatic container image updates for Docker Compose environments — with a premium real-time dashboard.

Docker Pulls GitHub Stars MIT License Rust Docker Compose

Project Overview

Modern DevOps teams invest heavily in CI/CD pipelines that build and push Docker images to container registries. However, getting those new images running in production — especially in Docker Compose environments — often still requires manual intervention: SSH into the server, pull the new image, restart the service, and verify it's healthy.

Docker Image Updater eliminates this gap entirely.

It is a self-hosted, lightweight agent that:

  • Watches your container registries for new image versions on a configurable interval
  • Automatically pulls the new image and recreates affected containers
  • Verifies the rollout is complete before marking the service as Synced
  • Exposes a real-time web dashboard so your team can see status, manage rollbacks, and trigger actions — all from a browser

Whether you run a handful of self-hosted services or a fleet of Docker Compose stacks, Docker Image Updater gives you ArgoCD-style GitOps UX without requiring Kubernetes.

How It Works: Step-by-Step

Step 1 ── Scan Registry

Every CHECK_INTERVAL seconds, the engine authenticates with the configured registry (ECR, ACR, GCR, etc.) and fetches the latest tagged image list.

Step 2 ── Detect New Tag

The 14-tier sorting algorithm ranks candidates by: push timestamp → semver → timestamp tag → build ID → generic. It filters out pinned tags and ignored tags.

Step 3 ── Trigger Update

If the desired tag differs from current_tag in the compose file, the engine marks the service as deploying=true and saves the state (UI badge immediately shows "Deploying…").

Step 4 ── Pull New Image

docker compose -f <path> pull. Layers are downloaded in parallel per service.

Step 5 ── Replace Container

The old container is recreated with the new image. ROLLBACKS use --force-recreate to ensure any stale process state is overwritten.

Step 6 ── Vulnerability Scan

If enabled, the engine triggers a Trivy scan on the newly deployed image, generating a summary for the UI and an in-depth report available for download.

Step 7 ── Confirm Running

The engine verifies the deployment command exited cleanly, confirming Docker restarted the container successfully.

Step 8 ── Auto Sync

current_tag is updated. If this was a manual rollback, pinned_tag is cleared and newer tags are added to ignored_tags to keep the service pinned at the rolled-back version.

Quick Logic Flow

graph LR classDef registry fill:#FF9900,stroke:#c47f00,stroke-width:2px,color:#fff; classDef engine fill:#1e40af,stroke:#0056b3,stroke-width:2px,color:#fff; classDef yaml fill:#0f766e,stroke:#0d5f57,stroke-width:2px,color:#fff; classDef container fill:#7c3aed,stroke:#6d28d9,stroke-width:2px,color:#fff; classDef admin fill:#374151,stroke:#1f2937,stroke-width:2px,color:#fff; classDef ui fill:#0e7490,stroke:#0c6280,stroke-width:2px,color:#fff; ECR[(AWS ECR)]:::registry -->|Poll| Updater[Image Updater Engine]:::engine HUB[(Docker Hub)]:::registry -->|Poll| Updater ACR[(Azure ACR)]:::registry -->|Poll| Updater GCP[(GCP GCR/AR)]:::registry -->|Poll| Updater HARBOR[(Harbor)]:::registry -->|Poll| Updater SWR[(Huawei SWR)]:::registry -->|Poll| Updater DOCR[(DO DOCR)]:::registry -->|Poll| Updater Updater -->|Update| YAML[docker-compose.yaml]:::yaml YAML -->|Recreate| containers[Running Containers]:::container Admin[DevOps Admin]:::admin -->|Manage| UI[Web Dashboard]:::ui UI -->|Control| Updater

Key Features

Feature Description
🔍 Automatic Image DetectionPolls registries every N seconds and detects new tags or digest changes
🚀 Rolling Container UpdatesPulls image and recreates containers with zero manual SSH required
🩺 Health VerificationTracks deploying state and only marks service Synced only after container is confirmed running
🔄 Auto Service SyncAfter a successful rollout, service state automatically transitions to Synced
🦀 Rust Core EngineHigh-performance, memory-safe backend built with Axum and Tokio — ~15 MB RAM footprint
🌐 Multi-Registry SupportAWS ECR, Docker Hub, Azure ACR, GCP GCR/AR, Harbor, Huawei SWR, DigitalOcean DOCR — all 7 active
🔄 Atomic RollbacksRevision history shows last 5 tags per service; one-click rollback auto-deploys and auto-syncs
🖥️ Premium DashboardGlassmorphism-inspired, dark-mode web UI with live status & controls
🛡️ Vulnerability ScanningIntegrated Trivy scanning with detailed CVE reports
🏷️ Intelligent Tag Sorting14-tier priority algorithm handles Semver, timestamps, build IDs, etc.

Supported Registries

Registry Provider Auth Method Status
AWS ECR Amazon Web Services IAM Role / Access Key + Secret Active
Docker Hub Docker Inc. Username + Password / Token (public or private) Active
Azure ACR Microsoft Azure Admin credentials / Service Principal (AcrPull) Active
GCP GCR / Artifact Registry Google Cloud Access Token / Service Account JSON Active
Harbor CNCF / Self-hosted Username + Password (robot accounts supported) Active
Huawei SWR Huawei Cloud AK/SK credentials / Pre-generated login key Active
DigitalOcean DOCR DigitalOcean Personal Access Token (PAT) Active

All seven registries are supported by generate_env.sh auto-configuration — select your registry at runtime and the script generates a ready-to-use .updater.env in seconds.

System Architecture

flowchart TD %% ── External Sources ────────────────────────────────────────────────── subgraph REGISTRIES["☁️ Container Registries"] direction LR ECR["🟠 AWS ECR"] ACR["🔵 Azure ACR"] GCR["🔴 GCP Artifact Registry"] SWR["🟣 Huawei SWR"] HUB["🐳 Docker Hub"] end subgraph USERS["👥 Users"] direction LR DEVOPS["🧑‍💻 DevOps Engineer"] CICD["⚙️ CI/CD Pipeline"] end %% ── Core Engine ─────────────────────────────────────────────────────── subgraph ENGINE["🔧 Docker Image Updater — Core Engine (Rust: src/main.rs)"] direction TB SCANNER["🔍 Registry Scanner\nPolls every CHECK_INTERVAL seconds\nFetches tags + digests + push timestamps"] SORTER["🏷️ Tag Sort & Filter Engine\n14-tier priority algorithm\nRegex ALLOW_TAGS filter\nRespects pinned & ignored tags"] DEPLOYER["🚀 Rollout Controller\nEdits docker-compose.yaml\ndocker compose pull\ndocker compose up -d"] VALIDATOR["🩺 Health Validator\nVerifies deploy exit code\nSets deploying = false\nUpdates current_tag"] STATE["🗄️ State Manager\nThread-safe JSON store\nstate_lock prevents race conditions\nHot-reloads .env each cycle"] API["🌐 Axum REST API\n/api/state /api/rollback\n/api/sync /api/logs\n/api/prune /api/cleanup"] end %% ── Target Infrastructure ───────────────────────────────────────────── subgraph INFRA["🐳 Host Infrastructure"] direction TB COMPOSE1["📄 docker-compose.yaml\n(Main services)"] COMPOSE2["📄 frontend/docker-compose.yaml"] COMPOSE3["📄 backend/docker-compose.yaml"] DOCKER["🐋 Docker Daemon\n/var/run/docker.sock"] CONTAINERS["📦 Running Containers\nweb_nginx · api_server\nfrontend · backend"] end %% ── Dashboard ───────────────────────────────────────────────────────── subgraph UI["🖥️ Web Dashboard (port 8080)"] direction LR LOGIN["🔐 Login Screen\nMulti-user Auth"] DASH["📊 Service Cards\n🔵 Deploying…\n🟡 OutOfSync\n🟢 Synced"] HISTORY["📜 Revision History\nLast 5 tags + digests"] ACTIONS["⚡ Actions\nRollback · Sync · Logs\nStart · Stop · Prune"] end %% ── Data Flows ──────────────────────────────────────────────────────── ECR & ACR & GCR & SWR & HUB -->|"Tags + Digests"| SCANNER CICD -->|"Push new image"| REGISTRIES SCANNER -->|"Candidate list"| SORTER SORTER -->|"Best tag selected\ndeploying = true"| STATE SORTER -->|"Update needed"| DEPLOYER DEPLOYER -->|"Pull + Recreate"| DOCKER DOCKER -->|"Manages"| CONTAINERS DOCKER -->|"Deploy success/fail"| VALIDATOR VALIDATOR -->|"current_tag updated\ndeploying = false\npinned_tag cleared"| STATE COMPOSE1 & COMPOSE2 & COMPOSE3 -->|"Read/Write"| DEPLOYER DOCKER -.->|"socket"| DEPLOYER STATE <-->|"Read / Write"| API API <-->|"REST API"| DASH DEVOPS -->|"Browser"| LOGIN LOGIN --> DASH DASH <--> HISTORY DASH <--> ACTIONS ACTIONS -->|"Rollback / Sync / Prune"| API %% ── Styles ──────────────────────────────────────────────────────────── classDef registry fill:#FF9900,color:#fff,stroke:#c47f00,stroke-width:2px classDef engine fill:#1e40af,color:#fff,stroke:#1e3a8a,stroke-width:2px classDef state fill:#0f766e,color:#fff,stroke:#0d5f57,stroke-width:2px classDef infra fill:#7c3aed,color:#fff,stroke:#6d28d9,stroke-width:2px classDef ui fill:#0e7490,color:#fff,stroke:#0c6280,stroke-width:2px classDef user fill:#374151,color:#fff,stroke:#1f2937,stroke-width:2px class ECR,ACR,GCR,SWR,HUB registry class SCANNER,SORTER,DEPLOYER,VALIDATOR,API engine class STATE state class COMPOSE1,COMPOSE2,COMPOSE3,DOCKER,CONTAINERS infra class LOGIN,DASH,HISTORY,ACTIONS ui class DEVOPS,CICD user

Auto-Configuration: generate_env.sh

Instead of manually editing updater.env, run generate_env.sh to auto-detect running containers and produce a ready-to-use config in under 5 minutes.

  • Presents an interactive registry menu — choose from all 7 providers
  • Docker Hub shows a sub-menu: Public / Private / Both
  • Scans only containers belonging to the selected registry — other registries are ignored
  • Auto-detects account IDs, regions, project IDs, and namespaces from running container image URIs
  • Preserves existing credentials on re-runs — never overwrites tokens you've already set
========================================= Select Cloud Provider & Container Registry ========================================= 1) AWS - Amazon ECR 2) Azure - Azure Container Registry (ACR) 3) GCP - Google Container Registry (GCR / Artifact Registry) 4) Docker Hub 5) Harbor - Harbor Registry 6) Huawei Cloud - SWR (Software Repository for Containers) 7) DigitalOcean - DO Container Registry (DOCR) ========================================= Enter your choice [1-7]:

IAM / Credentials Setup Scripts

Each cloud provider has a dedicated role script that creates the minimum-permission service account or IAM role required by the updater, then outputs the exact values to paste into updater.env.

Script Cloud What It Creates Outputs
ecr-role.sh AWS IAM Role with ECR read policy AWS_ROLE_ARN
acr-role.sh Azure Service Principal with AcrPull role AZURE_REGISTRY, AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET
gcp-role.sh GCP Service Account with artifactregistry.reader or storage.objectViewer GCP_REGISTRY_URL, GCP_PROJECT, GCP_SERVICE_ACCOUNT_JSON
harbor-role.sh Harbor Robot account via /api/v2.0/robots (project-scoped or system-level) HARBOR_URL, HARBOR_USERNAME, HARBOR_PASSWORD
swr-role.sh Huawei Validates AK/SK by deriving HMAC-SHA256 login key and testing docker login SWR_REGION, SWR_ORGANIZATION, SWR_ACCESS_KEY, SWR_SECRET_KEY
docr-role.sh DigitalOcean Validates PAT via DO API and tests docker login registry.digitalocean.com DO_REGISTRY, DO_TOKEN

All scripts follow the same pattern: check for required CLI tools, create or validate credentials with minimum permissions, then print the exact KEY=VALUE lines to paste into updater.env.

Project Folder Structure

DI-Updater/ │ ├── generate_env.sh # 7-registry interactive auto-config script ├── updater-compose.yml # Deployment manifest for the updater itself ├── updater_state.json # Internal state persistence file ├── .updater.env # Active runtime configuration (gitignored) │ ├── src/ │ └── main.rs # Core Engine: Registry scanner + Axum API (Rust) │ ├── templates/ │ └── index.html # Main dashboard SPA (Tailwind + Vanilla JS) │ ├── Landingpage/ │ ├── index.html # Product landing page │ └── docs.html # This technical documentation │ ├── backend/ # Example service groups ├── frontend/ # (Targeted by COMPOSE_FILE_PATH_*) │ └── ecr-role.sh # Helper: Configure AWS IAM permissions

Security Matrix

Risk Mitigation Strategy
Docker socket exposureMount /var/run/docker.sock only on trusted servers; run the agent as a non-exposed internal service.
Plaintext credentialsPasswords are hashed with SHA256 in-memory; .updater.env is gitignored and protected with local FS permissions.
AWS Cloud AccessUses IAM Roles with Least Privilege (Read-only ECR access) instead of long-lived static keys.
Network exposureDashboard binds to 8080; recommend running behind an authenticated reverse proxy (Nginx/Traefik) with TLS.

Deployment Lifecycle

sequenceDiagram autonumber participant Registry as Container Registry participant Engine as Update Engine participant Docker as Docker Daemon participant State as State Manager participant UI as Web Dashboard loop Every CHECK_INTERVAL seconds Engine->>Registry: Poll for latest tags Registry-->>Engine: Tags + Digests + PushedAt Engine->>Engine: Apply sort & filter logic alt New tag or digest detected Engine->>State: Set deploying=true → save UI-->>UI: Badge → 🔵 Deploying… Engine->>Docker: docker compose pull Docker-->>Engine: Image ready Engine->>Docker: docker compose up -d Docker-->>Engine: Container running Engine->>State: Set current_tag, clear pinned_tag, deploying=false → save UI-->>UI: Badge → 🟢 Synced end end

Badge State Machine

stateDiagram-v2 [*] --> Synced Synced --> Deploying : New Tag Detected Synced --> Deploying : Manual Rollback Deploying --> Synced : Deploy Success Deploying --> OutOfSync : Deploy Failure OutOfSync --> Deploying : Manual Sync OutOfSync --> Deploying : New Tag Detected