A production Docker host loses all containers after a corrupted image rollout, causing $250,000 in lost revenue per hour. The first minutes decide whether the outage can be contained or the loss escalates. An Ansible playbook for Docker deployment automates the recovery and guarantees consistent provisioning of containers across the fleet.
📑 Table of Contents
- ⏱ Minute 0‑2 — Stop the Bleed
- 🛡 Minute 2‑10 — Contain and Assess Scope
- 🗂 Collect Docker logs
- 🔍 Verify image checksum
- 🔀 Minute 10‑X — Recovery Decision Tree
- 🚀 Deploy verified image
- 🔐 Preventive Controls — Stop This From Happening Again
- 🟩 Final Thoughts
- ❓ Frequently Asked Questions
- How do I ensure the playbook runs only on the affected hosts?
- Can I use this playbook with Docker Swarm or Kubernetes?
- What is the recommended way to store the trusted image digests?
- 📚 References & Further Reading
⏱ Minute 0‑2 — Stop the Bleed
Isolate the faulty host to prevent further damage.
What to do:
$ ssh admin@docker-host-01
admin@docker-host-01:~$ sudo systemctl stop docker
Stopping Docker: [OK]
admin@docker-host-01:~$ sudo ufw deny from any to any port 2375
Rule added
Stopping the Docker daemon halts container creation; blocking port 2375 eliminates remote API access, so no new containers can be instantiated while the investigation proceeds.
Why this, not the obvious alternative: Disabling the daemon is safer than killing individual containers because a corrupted image can be auto‑redeployed by orchestration tools.
“If the host keeps serving a bad image, every new container inherits the fault.”
Key point: Immediate isolation cuts off the propagation path of the corrupted image, buying critical time for forensic analysis.
🛡 Minute 2‑10 — Contain and Assess Scope
Collect logs, verify image integrity, and prepare a clean environment.
🗂 Collect Docker logs
Logs reveal which containers were affected and whether any privileged containers executed unexpected commands. (Also read: Ansible Playbook: Install Docker + Run a Container on EC2 (2026))
$ sudo journalctl -u docker -since "1 hour ago" | tail -n 20
Sep 12 14:32:01 docker-host-01 dockerd[1245]: Starting up
Sep 12 14:32:02 docker-host-01 dockerd[1245]: Loading images from /var/lib/docker
Sep 12 14:32:05 docker-host-01 dockerd[1245]: Error: failed to pull image "mycorp/app:latest"
...
🔍 Verify image checksum
Use docker image inspect to compare the digest of the deployed image against the known‑good digest stored in a trusted registry.
$ sudo docker image inspect mycorp/app:latest -format='{{.RepoDigests}}'
[mycorp/app@sha256:3b1e5f9c8d7a9e4a6c2f5d1e9b4c7a6d5e9f1c2b3a4d5e6f7a8b9c0d1e2f3a4b]
If the digest does not match the expected value, the image is corrupted.
Create a minimal Ansible playbook that gathers facts and prepares a clean state.
# recover.yml
- name: Recover Docker host hosts: docker_hosts become: true tasks: - name: Ensure Docker is stopped service: name: docker state: stopped - name: Remove all containers command: docker rm -f $(docker ps -aq) ignore_errors: true - name: Prune dangling images command: docker image prune -f
What this does:
- service: stops the Docker daemon, guaranteeing no containers start during cleanup.
- docker rm -f $(docker ps -aq): force‑removes every container, including those in an unhealthy state; the command runs in O(N) time where N is the number of containers.
- docker image prune -f: deletes untagged images, freeing disk space and removing layers that could otherwise be re‑used.
Why this, not the obvious alternative: Directly deleting files under /var/lib/docker bypasses Docker’s internal state management and can corrupt the storage driver.
Key point: A focused Ansible playbook restores a host to a known‑good baseline without manual intervention. (Also read: Provision EC2 with Terraform, Configure with Ansible — End-to-End (2026)) (More onPythonTPoint tutorials)
🔀 Minute 10‑X — Recovery Decision Tree
Beyond ten minutes decide whether to redeploy from scratch or roll back based on image verification.
Critical question: Does the trusted registry contain a verified image tag for the service? (Also read: Create an EC2 Instance with Ansible — Complete Playbook (2026))
If the trusted image exists: Deploy the verified image using the playbook below.
If the trusted image is missing: Roll back to the previous stable tag and notify the CI pipeline.
If the host shows filesystem corruption: Re‑image the server from a golden AMI and run the playbook anew.
If none of the above: Escalate to the incident‑response manager for manual remediation.
🚀 Deploy verified image
Extend the earlier playbook to pull and run the good image.
# deploy.yml
- name: Deploy clean containers hosts: docker_hosts become: true tasks: - name: Pull verified image docker_image: name: mycorp/app tag: stable source: pull repository: registry.mycorp.com - name: Run container docker_container: name: app image: mycorp/app:stable state: started restart_policy: unless-stopped ports: - "8080:80"
What this does:
- docker_image: pulls the exact tag from a trusted registry, guaranteeing image integrity; the module verifies the image digest before download, reducing the risk of tampered layers.
- docker_container: starts the container with a restart policy that survives host reboots.
- ports: maps host port 8080 to container port 80, exposing the service safely.
According to the official Ansible documentation, the docker_image module validates the image digest before pulling, providing an additional safeguard against tampered layers.
Key point: The decision tree ensures you only deploy images that have been cryptographically verified, reducing the chance of re‑introducing the fault.
🔐 Preventive Controls — Stop This From Happening Again
Implement these controls to reduce future risk of corrupted Docker deployments.
- Image signing with Notary: Enforce Docker Content Trust so only signed images can be pulled.
- Immutable host images: Use Ansible to provision hosts from a read‑only base image, preventing accidental modifications.
-
CI gatekeeper: Add an Ansible task that runs
docker trust inspectbefore any CI push to the registry. -
Automated health checks: Deploy a periodic Ansible playbook that runs
docker container healthand alerts on failures. -
Role‑based access control (RBAC): Restrict who can push to the
stabletag, limiting exposure to insider errors.
What this does:
- Image signing: Guarantees the binary layers have not been altered after being built.
- Immutable hosts: Eliminates drift that can cause mismatched Docker daemon versions.
- CI gatekeeper: Catches unsigned images before they reach production.
- Health checks: Detects regressions early, allowing automated remediation.
- RBAC: Reduces the attack surface by limiting privileged operations.
Key point: A layered defense—combining signed images, immutable infrastructure, and continuous verification—prevents the scenario that triggered this incident.
🟩 Final Thoughts
Automating Docker recovery with an Ansible playbook for Docker deployment transforms a reactive firefighting effort into a repeatable process. By stopping the bleed, containing the scope, and following a clear decision tree, you reduce MTTR and protect revenue.
Embedding preventive controls directly into the Ansible automation pipeline ensures the same mistake cannot reappear without detection. The approach scales across dozens of hosts, keeping the container fleet consistent and auditable.
❓ Frequently Asked Questions
How do I ensure the playbook runs only on the affected hosts?
Use an inventory group that lists the compromised hosts, then invoke the playbook with ansible-playbook -i inventory.yml recover.yml. The hosts entry in the playbook restricts execution to that group.
Can I use this playbook with Docker Swarm or Kubernetes?
The core tasks—stopping the daemon, pruning images, and pulling a verified tag—are compatible with Swarm. For Kubernetes, replace the Docker modules with the k8s module, but keep the same verification logic.
What is the recommended way to store the trusted image digests?
Store digests in a secure Vault or an encrypted Ansible variable file, then reference them in the docker_image task using the digest parameter.
💡 Want to practise this hands-on? DigitalOcean gives new accounts $200 free credit for 60 days — enough to spin up a full Linux/Docker/Kubernetes environment at no cost.
📚 Recommended reading: Best DevOps & cloud books on Amazon — from Linux fundamentals to Kubernetes in production, curated for working engineers.
📚 References & Further Reading
- Official Ansible Docker module docs — complete reference for Docker tasks: docs.ansible.com
- Docker Content Trust guide — details on image signing and verification: docs.docker.com
- Docker best practices for production — recommended patterns for image management: docs.docker.com
Top comments (0)