Docker WSL: Disk Cleanup & Optimization

Docker Desktop on Windows uses WSL2 with dynamic VHDX files. They grow when adding images/containers but don’t shrink automatically when deleting them. Result: C: drive fills up, even though docker system df shows free space. 💡 Solution: manual VHDX optimization via PowerShell + Docker utility. 📦 Cleanup script Create file # File: $HOME\Scripts\docker-clear-wsl.ps1 $script = @' $LOCAL = "$env:LOCALAPPDATA\Docker\wsl" $VHD1 = Join-Path $LOCAL "disk\docker_data.vhdx" $VHD2 = Join-Path $LOCAL "main\ext4.vhdx" # 1. Docker cleanup docker system prune -f # 2. Reclaim space via official tool docker run --rm --privileged --pid=host docker/desktop-reclaim-space docker rmi docker/desktop-reclaim-space -f # 3. Stop Docker Desktop Get-Process -Name "Docker Desktop","com.docker.backend","com.docker.build" ` -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue # 4. Shutdown WSL wsl --shutdown # 5. Optimize VHDX files (compact) if (Test-Path $VHD1) { Optimize-VHD -Path $VHD1 -Mode Full } if (Test-Path $VHD2) { Optimize-VHD -Path $VHD2 -Mode Full } # 6. Restart Docker Desktop Start-Sleep -Seconds 2 Start-Process -FilePath "$env:ProgramFiles\Docker\Docker\Docker Desktop.exe" ` -ErrorAction SilentlyContinue '@ $script | Out-File -FilePath "$HOME\Scripts\docker-clear-wsl.ps1" -Encoding UTF8 Run # As Administrator (required for Optimize-VHD) powershell.exe -ExecutionPolicy Bypass -File "$HOME\Scripts\docker-clear-wsl.ps1" 🔍 How it works Step Command What it does 1 docker system prune -f Removes stopped containers, unused images, build cache 2 docker/desktop-reclaim-space Official Docker tool to reclaim space in WSL2 3 Stop-Process Gracefully stops Docker Desktop (otherwise VHDX is locked) 4 wsl --shutdown Fully shuts down WSL, freeing files for optimization 5 Optimize-VHD -Mode Full Compacts VHDX files, returning space to host 6 Start-Process Restarts Docker Desktop Rationale: ...

17 Mar 2026 · 3 min · 570 words · Potato Energy Team, ponfertato

GitHub CLI: Bulk Delete Old Issues

Long-running projects accumulate outdated issues: bugs for old versions, irrelevant features, test tickets. Manual deletion takes significant time. The script automatically finds and deletes (or marks) old issues by specified labels. 💡 Script uses dry-run by default - shows what would be deleted without actual deletion. 📦 Script: delete-issues.sh Full code #!/bin/bash # Delete old GitHub Issues by labels and date # Usage: ./delete-issues.sh [--execute] set -euo pipefail # === CONFIG === REPO="owner/repo" # Repository in owner/repo format LABELS='label1,label2,label3' # Labels to filter (comma-separated) CUTOFF="2025-12-31T23:59:59Z" # Delete issues created BEFORE this date DRY_RUN=true # true = preview only, false = actually delete # Parse arguments if [[ "${1:-}" == "--execute" ]]; then DRY_RUN=false echo "⚠️ Mode: ACTUAL DELETION" else echo "ℹ️ Mode: DRY RUN (nothing will be deleted)" fi echo "🔍 Searching issues in $REPO with labels: $LABELS, created before $CUTOFF" echo "---" # Fetch and filter issues gh issue list --repo "$REPO" --state all --limit 1000 \ --json number,title,createdAt,labels,url | \ jq -r --arg labels "$LABELS" --arg cutoff "$CUTOFF" ' ($labels | split(",")) as $label_array | .[] | select(.createdAt < $cutoff) | select(.labels | map(.name) | any(. as $l | $label_array | index($l))) | "\(.number)|\(.title)|\(.url)" ' | \ while IFS='|' read -r number title url; do if [[ "$DRY_RUN" == "true" ]]; then echo "[DRY RUN] ##$number - $title" echo " $url" else echo "🗑 Deleting ##$number - $title" gh issue delete "$REPO" "$number" --yes sleep 1 # Small pause to avoid rate limits fi done echo "---" echo "✅ Done" Install dependencies # GitHub CLI # Windows (winget): winget install GitHub.cli # Linux (Ubuntu/Debian): sudo apt install gh # macOS (Homebrew): brew install gh # Authenticate gh auth login # jq (JSON processor) # Windows (winget): winget install jq.jq # Linux: sudo apt install jq # macOS: brew install jq Run # Make script executable chmod +x delete-issues.sh # DRY RUN (safe mode - preview only) ./delete-issues.sh # ACTUAL DELETION (add --execute flag) ./delete-issues.sh --execute 🔍 How it works Step-by-step breakdown Step Command What it does 1 gh issue list --json ... Fetches issues as JSON with fields: number, title, date, labels, URL 2 jq -r ... Filters: date < cutoff AND has at least one of specified labels 3 while read ... Processes each matching issue 4 gh issue delete Deletes issue (only if DRY_RUN=false) jq filter logic ($labels | split(",")) as $label_array | # Split label string into array .[] | # For each issue select(.createdAt < $cutoff) | # Only if created before cutoff select( .labels | map(.name) | # Get list of label names any(. as $l | $label_array | index($l)) # Check if any matches our labels ) | "\(.number)|\(.title)|\(.url)" # Format output Rationale: ...

17 Mar 2026 · 4 min · 819 words · Potato Energy Team, ponfertato

Docker: Scheduled Automatic Shutdown

For home servers and test environments, resource saving is important: containers can be stopped and the system powered off during nights or off-hours. This guide describes a safe method with state preservation and automatic recovery. 💡 Method suits OrangePI, Raspberry Pi, old PCs, and any systems where power efficiency matters. 📦 Container shutdown script Create script # File: /usr/local/bin/stop_containers_and_shutdown.sh cat > /usr/local/bin/stop_containers_and_shutdown.sh << 'EOF' #!/bin/bash # # Script saves running container IDs, # stops them, and initiates system shutdown. # CONTAINERS_FILE="/etc/active_containers.txt" echo "=== $(date '+%Y-%m-%d %H:%M:%S') ===" echo "Starting container shutdown and system power-off script" # Get list of running containers (by ID) RUNNING_CONTAINERS=$(docker ps -q) if [ -n "${RUNNING_CONTAINERS}" ]; then echo "Saving running containers to ${CONTAINERS_FILE}" echo "${RUNNING_CONTAINERS}" > "${CONTAINERS_FILE}" docker stop ${RUNNING_CONTAINERS} echo "Containers stopped." else echo "No running containers." [ -f "${CONTAINERS_FILE}" ] && rm -f "${CONTAINERS_FILE}" fi sleep 10 echo "Shutting down system." /sbin/shutdown -h now EOF Make executable chmod +x /usr/local/bin/stop_containers_and_shutdown.sh How it works Step Description docker ps -q Gets IDs of all running containers > /etc/active_containers.txt Saves list for recovery docker stop Gracefully stops containers (SIGTERM) sleep 10 Allows time for operations to complete shutdown -h now Powers off the system Rationale: ...

17 Mar 2026 · 4 min · 813 words · Potato Energy Team, ponfertato

Docker Volumes: Backup & Migration

Docker Volumes store data independently from containers but require a separate approach for backup. This guide describes universal methods for working with volumes using popular services as examples. 💡 Replace volume names in examples with your own. Methods apply to any containers. 📦 Backup volumes Via docker-volume-backup (recommended) docker run --rm \ -v portainer_data:/backup/portainer_data \ -v postgres_data:/backup/postgres_data \ -v redis_data:/backup/redis_data \ -v /opt/docker/backup:/archive \ --entrypoint backup \ offen/docker-volume-backup:v2 Parameters: Parameter Description -v <volume>:/backup/<name> Map volume to backup directory -v /opt/docker/backup:/archive Where to save archive on host --entrypoint backup Run backup mode --rm Remove container after completion Advantages of this method: ...

16 Mar 2026 · 3 min · 632 words · Potato Energy Team, ponfertato

OpenWRT: Advanced Router Configuration

Practical guide to OpenWRT configuration for advanced home use. Covers configurations that extend router functionality: DNS-level traffic filtering, secure remote access via WireGuard, metrics monitoring, and automated notifications. 💡 All sensitive values are replaced with <...>. Substitute your own values. 📦 Package installation opkg update # Monitoring: prometheus exporter + modules opkg install \ prometheus-node-exporter-lua \ prometheus-node-exporter-lua-nat_traffic \ prometheus-node-exporter-lua-netstat \ prometheus-node-exporter-lua-openwrt \ prometheus-node-exporter-lua-wifi \ prometheus-node-exporter-lua-wifi_stations # WireGuard: kernel module + tools + LuCI opkg install \ kmod-wireguard \ wireguard-tools \ luci-proto-wireguard # DNS over HTTPS opkg install https-dns-proxy # Debug utilities opkg install curl jq tmux htop Purpose: ...

16 Mar 2026 · 7 min · 1341 words · Potato Energy Team, ponfertato

OrangePI: Data Recovery & Migration

OrangePI and other ARM single-board computers often use eMMC or SD cards with limited write endurance. Over time, storage fills up, degrades, or fails. This guide describes a method for data recovery and migration to external storage (USB SSD/HDD) via a chroot environment. 💡 Method is universal: works for OrangePI, Raspberry Pi, NanoPi, and other ARM systems. 📦 Preparation Requirements Component Requirements USB drive SSD/HDD, capacity ≥ eMMC data Live image Any Linux with ARM support (optional) Access root or sudo, physical access to board Network Ethernet or WiFi (for remote access) Check connected storage # Show all MMC devices (eMMC, SD card) ls /dev/mmc* # Show all block devices lsblk # Show partitions and mount points df -h Expected output: ...

16 Mar 2026 · 4 min · 812 words · Potato Energy Team, ponfertato