This commit is contained in:
jpmvaz
2026-09-13 19:54:18 +01:00
commit bf46819e1a
2 changed files with 488 additions and 0 deletions
+82
View File
@@ -0,0 +1,82 @@
# Docker Factory Reset Script for Ubuntu
A comprehensive Python script that completely resets Docker to a fresh installation state on Ubuntu systems. This script removes all containers, images, volumes, networks, build cache, and even wipes the Docker data directories to give you a clean slate.
## 🚨 Warning
**This script is EXTREMELY DESTRUCTIVE!**
It will permanently delete:
- ✗ All Docker containers (running and stopped)
- ✗ All Docker images
- ✗ All Docker volumes (including all data stored in them)
- ✗ All custom Docker networks
- ✗ All build cache
- ✗ All Docker system data (`/var/lib/docker` and `/var/lib/containerd`)
**There is NO undo. All data will be permanently lost.**
Only use this script if you:
- Want to completely reset Docker to a fresh state
- Are experiencing issues that require a clean Docker installation
- Are decommissioning a system and want to clean up Docker
- Understand that ALL Docker data will be lost
## 📋 Features
-**Real-time output**: See exactly what's happening as commands execute
-**Progress indicators**: Visual progress bars for batch operations
-**Step-by-step execution**: Clear indication of each phase
-**Safety confirmation**: Requires explicit confirmation before proceeding
-**Comprehensive cleanup**: Removes everything Docker-related
-**Service management**: Properly stops and restarts Docker daemon
-**Final state report**: Shows the clean state after reset
-**Execution time tracking**: Reports how long the reset took
## 🔧 Requirements
### System Requirements
- **Operating System**: Ubuntu (18.04, 20.04, 22.04, 24.04 or later)
- **Docker**: Must be installed (any version)
- **Python**: Python 3.6 or later (usually pre-installed on Ubuntu)
- **Privileges**: Must be run as root (using `sudo`)
### Dependencies
All dependencies are part of Python's standard library:
- `subprocess` - For running system commands
- `sys` - For system operations
- `os` - For file system operations
- `time` - For timing and delays
No additional packages need to be installed.
## 🚀 Usage
Run the script with sudo:
```bash
sudo python3 docker_full_factory_reset.py
```
The script will ask you to type `RESET_DOCKER_UBUNTU` to confirm.
## 📖 What Each Step Does
1. **Containers**: Stops and removes all containers
2. **Images**: Removes all images
3. **Networks**: Removes custom networks (keeps default ones)
4. **Volumes**: Removes all volumes
5. **Prune**: Clears build cache and system artifacts
6. **Stop services**: Stops `docker` and `containerd`
7. **Delete directories**: Removes `/var/lib/docker` and `/var/lib/containerd`
8. **Start services**: Restarts Docker and verifies with `docker info`
## 🔍 Verify After Reset
```bash
docker run hello-world
```
## ⚠ Final Warning
This script deletes **ALL** Docker data. Back up anything important first.
+406
View File
@@ -0,0 +1,406 @@
#!/usr/bin/env python3
"""
Docker Factory Reset Script for Ubuntu
Completely resets Docker to a fresh installation state.
"""
import subprocess
import sys
import os
import time
from typing import List
class ProgressBar:
"""Simple progress indicator for operations."""
def __init__(self, total: int, description: str = ""):
self.total = total
self.current = 0
self.description = description
def update(self, increment: int = 1):
self.current += increment
self._display()
def _display(self):
if self.total == 0:
percentage = 100
else:
percentage = int((self.current / self.total) * 100)
bar_length = 40
filled = int((percentage / 100) * bar_length)
bar = '' * filled + '' * (bar_length - filled)
print(f"\r [{bar}] {percentage}% ({self.current}/{self.total}) {self.description}", end='', flush=True)
def complete(self):
self.current = self.total
self._display()
print() # New line after completion
def run_cmd_realtime(cmd: List[str], check: bool = False, show_output: bool = True) -> int:
"""
Run a command and stream stdout/stderr in real-time.
Returns the exit code.
If check=True, exits the script on non-zero return code.
"""
if show_output:
print(f"\n▶ RUN: {' '.join(cmd)}")
print("" * 60)
try:
process = subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, # Merge stderr into stdout
text=True,
bufsize=1, # Line buffered
)
# Stream output line by line
if show_output:
for line in process.stdout:
print(line, end='') # Print without adding extra newline
else:
# Consume output even if not showing
for _line in process.stdout:
pass
process.wait()
code = process.returncode
if show_output:
if code != 0:
print(f"✗ Command exited with code {code}")
if check:
sys.exit(code)
else:
print(f"✓ Command completed successfully")
return code
except FileNotFoundError:
print(f"✗ ERROR: Command not found: {' '.join(cmd)}")
sys.exit(1)
def run_cmd_quiet(cmd: List[str]) -> tuple:
"""
Run a command quietly and return (exit_code, stdout, stderr).
Used for listing/checking operations.
"""
try:
result = subprocess.run(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
)
return result.returncode, result.stdout.strip(), result.stderr.strip()
except FileNotFoundError:
print(f"✗ ERROR: Command not found: {' '.join(cmd)}")
sys.exit(1)
def require_root():
if os.geteuid() != 0:
print("✗ This script must be run as root (use sudo).")
sys.exit(1)
def docker_installed() -> bool:
code, out, err = run_cmd_quiet(["docker", "--version"])
if code != 0:
print("✗ Docker does not appear to be installed or accessible.")
if err:
print(err)
return False
print(f"✓ Docker found: {out}")
return True
def list_ids(cmd: List[str]) -> List[str]:
code, out, _err = run_cmd_quiet(cmd)
if code != 0:
return []
return [line.strip() for line in out.splitlines() if line.strip()]
def stop_and_remove_containers():
print("\n" + "=" * 60)
print("STEP 1/8: CONTAINERS")
print("=" * 60)
container_ids = list_ids(["docker", "ps", "-aq"])
if not container_ids:
print(" No containers found.")
return
print(f" Found {len(container_ids)} container(s)")
running_ids = list_ids(["docker", "ps", "-q"])
if running_ids:
print(f"\n Stopping {len(running_ids)} running container(s)...")
progress = ProgressBar(len(running_ids), "stopping containers")
for container_id in running_ids:
run_cmd_realtime(["docker", "stop", container_id], show_output=False)
progress.update()
progress.complete()
else:
print(" No running containers to stop.")
print(f"\n Removing all {len(container_ids)} container(s)...")
progress = ProgressBar(len(container_ids), "removing containers")
for container_id in container_ids:
run_cmd_realtime(["docker", "rm", "-f", container_id], show_output=False)
progress.update()
progress.complete()
print("✓ All containers removed")
def remove_images():
print("\n" + "=" * 60)
print("STEP 2/8: IMAGES")
print("=" * 60)
image_ids = list_ids(["docker", "images", "-aq"])
if not image_ids:
print(" No images found.")
return
print(f" Found {len(image_ids)} image(s)")
print("\n Removing all images...")
progress = ProgressBar(len(image_ids), "removing images")
for image_id in image_ids:
run_cmd_realtime(["docker", "rmi", "-f", image_id], show_output=False)
progress.update()
progress.complete()
print("✓ All images removed")
def remove_networks():
print("\n" + "=" * 60)
print("STEP 3/8: NETWORKS")
print("=" * 60)
code, out, err = run_cmd_quiet(["docker", "network", "ls", "--format", "{{.Name}}"])
if code != 0:
print(f"✗ Error listing networks: {err}")
return
default_networks = {"bridge", "host", "none"}
networks = [n.strip() for n in out.splitlines() if n.strip()]
custom_networks = [n for n in networks if n not in default_networks]
if not custom_networks:
print(" No custom networks found.")
return
print(f" Found {len(custom_networks)} custom network(s): {', '.join(custom_networks)}")
print("\n Removing custom networks...")
progress = ProgressBar(len(custom_networks), "removing networks")
for network in custom_networks:
run_cmd_realtime(["docker", "network", "rm", network], show_output=False)
progress.update()
progress.complete()
print("✓ All custom networks removed")
def remove_volumes():
print("\n" + "=" * 60)
print("STEP 4/8: VOLUMES")
print("=" * 60)
volume_names = list_ids(["docker", "volume", "ls", "-q"])
if not volume_names:
print(" No volumes found.")
return
print(f" Found {len(volume_names)} volume(s)")
print("\n Removing all volumes...")
progress = ProgressBar(len(volume_names), "removing volumes")
for volume in volume_names:
run_cmd_realtime(["docker", "volume", "rm", "-f", volume], show_output=False)
progress.update()
progress.complete()
print("✓ All volumes removed")
def prune_system():
print("\n" + "=" * 60)
print("STEP 5/8: SYSTEM PRUNE & BUILD CACHE")
print("=" * 60)
print(" Pruning builder cache...")
run_cmd_realtime(["docker", "builder", "prune", "-af"])
print("\n Running system prune (extra safety)...")
run_cmd_realtime(["docker", "system", "prune", "-af", "--volumes"])
def stop_docker_service():
print("\n" + "=" * 60)
print("STEP 6/8: STOP DOCKER DAEMON")
print("=" * 60)
print(" Stopping Docker service...")
run_cmd_realtime(["systemctl", "stop", "docker"])
print("\n Stopping containerd service...")
run_cmd_realtime(["systemctl", "stop", "containerd"])
print("✓ Docker daemon stopped")
def wipe_docker_data_dirs():
print("\n" + "=" * 60)
print("STEP 7/8: DELETE DOCKER DATA DIRECTORIES")
print("=" * 60)
paths = ["/var/lib/docker", "/var/lib/containerd"]
existing_paths = [p for p in paths if os.path.exists(p)]
if not existing_paths:
print(" No Docker data directories found.")
return
print(f" Found {len(existing_paths)} data director(ies) to delete")
progress = ProgressBar(len(existing_paths), "deleting directories")
for p in paths:
if os.path.exists(p):
print(f"\n Deleting {p} ...")
code, out, _err = run_cmd_quiet(["du", "-sh", p])
if code == 0 and out:
print(f" Size: {out.split()[0]}")
run_cmd_realtime(["rm", "-rf", p], show_output=False)
progress.update()
else:
print(f" {p} does not exist; skipping.")
progress.complete()
print("✓ All Docker data directories deleted")
def start_docker_service():
print("\n" + "=" * 60)
print("STEP 8/8: START DOCKER DAEMON")
print("=" * 60)
print(" Starting containerd service...")
run_cmd_realtime(["systemctl", "start", "containerd"])
print("\n Starting Docker service...")
run_cmd_realtime(["systemctl", "start", "docker"])
print("\n Waiting for Docker to initialize...")
for i in range(5):
time.sleep(1)
code, out, _err = run_cmd_quiet(["systemctl", "is-active", "docker"])
if code == 0 and out.strip() == "active":
print(f"✓ Docker service is active (took {i+1}s)")
break
else:
print("⚠ Warning: Docker service may not be active yet.")
print("\n Running docker info to verify...")
run_cmd_realtime(["docker", "info"])
def show_final_state():
print("\n" + "=" * 60)
print("FINAL DOCKER STATE")
print("=" * 60)
cmds = [
(["docker", "ps", "-a"], "CONTAINERS"),
(["docker", "images"], "IMAGES"),
(["docker", "network", "ls"], "NETWORKS"),
(["docker", "volume", "ls"], "VOLUMES"),
]
for cmd, title in cmds:
print(f"\n{title}")
print("" * 60)
code, out, err = run_cmd_quiet(cmd)
if code == 0:
print(out if out else "(empty)")
else:
print("✗ Command failed")
if err:
print(err)
def show_banner():
banner = """
╔════════════════════════════════════════════════════════════╗
║ ║
║ DOCKER FACTORY RESET FOR UBUNTU ║
║ ║
║ Completely resets Docker to fresh state ║
║ ║
╚════════════════════════════════════════════════════════════╝
"""
print(banner)
def main():
show_banner()
require_root()
if not docker_installed():
sys.exit(1)
print("\n⚠ WARNING: This script will COMPLETELY RESET Docker on this Ubuntu host.")
print("\nIt will:")
print(" • Stop and remove ALL containers (running and stopped)")
print(" • Remove ALL images")
print(" • Remove ALL volumes")
print(" • Remove ALL custom networks")
print(" • Prune ALL build cache and system data")
print(" • STOP Docker daemon")
print(" • DELETE /var/lib/docker and /var/lib/containerd")
print(" • START Docker daemon again")
print("\n⚠ You will lose ALL Docker data on this machine.")
print("\n" + "" * 60)
confirm = input("\nType 'RESET_DOCKER_UBUNTU' to continue: ")
if confirm != "RESET_DOCKER_UBUNTU":
print("\n✗ Aborted.")
sys.exit(0)
start_time = time.time()
stop_and_remove_containers()
remove_images()
remove_networks()
remove_volumes()
prune_system()
stop_docker_service()
wipe_docker_data_dirs()
start_docker_service()
show_final_state()
elapsed_time = time.time() - start_time
print("\n" + "=" * 60)
print("✓ DOCKER FACTORY RESET COMPLETE")
print(f" Total time: {elapsed_time:.2f} seconds")
print("=" * 60)
print("\nDocker has been reset to a fresh installation state.\n")
if __name__ == "__main__":
main()