diff --git a/casaos-fix-docker-api-version/README.md b/casaos-fix-docker-api-version/README.md new file mode 100644 index 0000000..7d3cfc0 --- /dev/null +++ b/casaos-fix-docker-api-version/README.md @@ -0,0 +1,142 @@ +# Fix Docker API Version Error for CasaOS + +This script fixes common Docker errors with CasaOS including: +- `Error response from daemon: client version 1.43 is too old. Minimum supported API version is 1.44` +- `OCI runtime create failed: runc create failed: unable to start container process: error during container init: open sysctl net.ipv4.ip_unprivileged_port_start file: reopen fd 8: permission denied` +- Docker permission issues and corrupted overlay2 storage +- CVE-2025-52881 AppArmor issues in LXC/Proxmox environments + +## The Problem + +These errors commonly occur with **CasaOS** when: +1. Docker gets upgraded to a very recent version (API 1.44+) that is incompatible with CasaOS's older Docker client +2. Docker overlay2 filesystem permissions become corrupted +3. Container runtime state becomes inconsistent +4. **NEW**: containerd.io 1.7.28-2 or newer causes AppArmor permission errors in LXC/Proxmox containers + +CasaOS uses Docker API 1.43, and when the system Docker gets auto-upgraded or the storage becomes corrupted, it breaks compatibility. + +### Special Note for LXC/Proxmox Users + +If you're running CasaOS or Docker in an LXC container (common with Proxmox), you may encounter the `permission denied` error after updating containerd. This is caused by **CVE-2025-52881** security patches that conflict with AppArmor profiles in nested containers. + +**The error looks like:** +``` +failed to create shim task: OCI runtime create failed: runc create failed: +unable to start container process: error during container init: +open sysctl net.ipv4.ip_unprivileged_port_start file: reopen fd 8: permission denied +``` + +This script automatically detects LXC environments and installs **containerd.io 1.7.28-1** (the last version before the breaking change) to prevent this issue. + +**References:** +- GitHub Issue: https://github.com/opencontainers/runc/issues/4968 +- Proxmox Forum: https://forum.proxmox.com/threads/docker-inside-lxc-net-ipv4-ip_unprivileged_port_start-error.175437/ + +## What does this script do? + +- Detects your operating system (Debian/Ubuntu-based) +- **Detects LXC/Proxmox environment** and adjusts containerd version accordingly +- Checks if CasaOS is installed +- Stops CasaOS services temporarily (if installed) +- Cleans Docker runtime state and fixes permissions +- Fixes overlay2 directory permissions +- Downgrades Docker to version 24.0.7 (compatible with both CasaOS and modern systems) +- **Installs containerd.io 1.7.28-1** in LXC/Proxmox to avoid CVE-2025-52881 AppArmor issues +- Configures Docker daemon with proper settings +- Holds Docker packages to prevent automatic upgrades +- Removes standalone docker-compose if present +- Installs Docker Compose plugin +- Restarts Docker service properly +- Restarts CasaOS services (if installed) +- **Intelligently detects and fixes** the sysctl permission denied error + +## Run command + +```bash +bash -c "$(wget -qLO - https://raw.githubusercontent.com/bigbeartechworld/big-bear-scripts/master/casaos-fix-docker-api-version/run.sh)" +``` + +## Can't Resolve Domain + +To resolve this issue, please follow these steps: + +1. Copy the contents of run.sh from this repository. +2. Create a file named run.sh on your server. +3. Execute the following command on your server: + +```bash +bash run.sh +``` + +## What causes these errors? + +These errors occur when: +- Docker gets auto-upgraded to version 25+ or 26+ (API 1.44+) +- CasaOS still uses Docker API 1.43 in older versions +- There's a version mismatch between CasaOS's Docker client and the system's Docker daemon +- System updates automatically upgrade Docker without considering CasaOS compatibility +- Docker overlay2 storage permissions become corrupted +- Container runtime (runc/containerd) state becomes inconsistent +- Improper system shutdowns or Docker crashes leave stale state files +- **containerd.io 1.7.28-2 or newer** in LXC/Proxmox (CVE-2025-52881 AppArmor conflict) + +## Requirements + +- Debian or Ubuntu-based Linux distribution +- Sudo privileges or root access +- Active internet connection +- CasaOS installed (optional - script works without it too) + +## After running the script + +You can verify the fix by running: +```bash +docker version +``` + +Both the client and server API versions should now be compatible. The script installs Docker 24.0.7 which: +- Supports API version 1.43 (compatible with older CasaOS) +- Is stable and well-tested +- Is held at this version to prevent auto-upgrades + +## Preventing future issues + +The script automatically holds Docker packages to prevent automatic upgrades: +```bash +sudo apt-mark hold docker-ce docker-ce-cli containerd.io +``` + +**Important for LXC/Proxmox users:** The script holds containerd.io at version 1.7.28-1 to prevent the CVE-2025-52881 AppArmor issue. Do not upgrade containerd until this issue is resolved upstream. + +If you want to allow Docker upgrades in the future (after confirming CasaOS compatibility), run: +```bash +sudo apt-mark unhold docker-ce docker-ce-cli containerd.io +``` + +⚠️ **Warning for LXC users**: Before unholdingcontainerd.io, check if the AppArmor issue has been fixed: +- Check: https://github.com/opencontainers/runc/issues/4968 +- Or test in a non-production environment first + +## Version Information + +- Docker CE: 24.0.7 +- Docker API: 1.43 compatible +- containerd.io: 1.7.28-1 (for LXC/Proxmox environments) +- Works with CasaOS 0.4.x series + +## Alternative Solutions for LXC/Proxmox (Advanced) + +If you prefer not to downgrade containerd, you can modify the LXC container configuration on the Proxmox host: + +**Option 1: Disable AppArmor for the container** (in `/etc/pve/lxc/$CTID.conf`): +``` +lxc.apparmor.profile: unconfined +lxc.mount.entry: /dev/null sys/module/apparmor/parameters/enabled none bind 0 0 +``` + +**Option 2: Wait for upstream fixes:** +- Proxmox/LXC to update their AppArmor profiles +- containerd/runc to implement workarounds + +This script uses the downgrade approach as it's the safest and most reliable solution that doesn't require host-level configuration changes. diff --git a/casaos-fix-docker-api-version/run.sh b/casaos-fix-docker-api-version/run.sh new file mode 100755 index 0000000..1936fdc --- /dev/null +++ b/casaos-fix-docker-api-version/run.sh @@ -0,0 +1,853 @@ +#!/usr/bin/env bash + +# BigBear CasaOS Docker Client Version Fix +# Script to fix Docker client version 1.43 is too old error for CasaOS +# This script downgrades Docker to a version compatible with CasaOS +# +# GitHub: https://github.com/BigBearTechWorld +# Community: https://community.bigbeartechworld.com +# Support: https://ko-fi.com/bigbeartechworld +# + +set -e + +echo "==========================================" +echo "BigBear CasaOS Docker Version Fix Script" +echo "==========================================" +echo "" +echo "Here are some links:" +echo "https://community.bigbeartechworld.com" +echo "https://github.com/BigBearTechWorld" +echo "" +echo "If you would like to support me, please consider buying me a tea:" +echo "https://ko-fi.com/bigbeartechworld" +echo "" +echo "==========================================" +echo "" + +# Compatible Docker versions for CasaOS +# Using Docker 24.x series which supports API 1.43 (older CasaOS versions) +# but is also compatible with API 1.44 (newer Docker daemons) +readonly DOCKER_CE_VERSION="5:24.0.7-1~" +readonly DOCKER_CLI_VERSION="5:24.0.7-1~" +# Using containerd.io 1.7.28-1 to avoid CVE-2025-52881 AppArmor issues in LXC/Proxmox +# Version 1.7.28-2 and newer cause "permission denied" errors on sysctl in nested containers +readonly CONTAINERD_VERSION="1.7.28-1" + +# Function to display current versions +display_versions() { + echo "Current Docker versions:" + if command -v docker &>/dev/null; then + docker version 2>&1 || echo "Unable to get full version info due to API mismatch" + echo "" + else + echo "Docker command not found" + echo "" + fi +} + +# Function to check if running as root or with sudo +check_sudo() { + if [ "$EUID" -eq 0 ]; then + SUDO="" + else + SUDO="sudo" + fi +} + +# Function to detect the OS +detect_os() { + if [ -f /etc/os-release ]; then + . /etc/os-release + OS=$ID + VERSION_CODENAME=${VERSION_CODENAME:-$(lsb_release -cs 2>/dev/null)} + else + echo "Cannot detect OS. This script supports Debian/Ubuntu-based systems." + exit 1 + fi + echo "Detected OS: $OS ${VERSION_CODENAME}" + echo "" +} + +# Function to check if CasaOS is installed +check_casaos() { + if command -v casaos &>/dev/null; then + echo "CasaOS is installed: $(casaos -v 2>/dev/null || echo 'version unknown')" + return 0 + else + echo "CasaOS not detected." + return 1 + fi +} + +# Function to detect if running in LXC/Proxmox container +check_lxc_environment() { + if [ -f /proc/1/environ ]; then + if grep -qa "container=lxc" /proc/1/environ 2>/dev/null; then + return 0 + fi + fi + + # Alternative check: systemd-detect-virt + if command -v systemd-detect-virt &>/dev/null; then + if systemd-detect-virt -c | grep -q "lxc"; then + return 0 + fi + fi + + return 1 +} + +# Function to check containerd.io version +check_containerd_version() { + if ! command -v containerd &>/dev/null; then + echo "not_installed" + return 1 + fi + + # Get installed version + local version=$(dpkg -l | grep containerd.io | awk '{print $3}' | head -n1) + echo "$version" + return 0 +} + +# Function to stop CasaOS services +stop_casaos_services() { + echo "Stopping CasaOS services..." + + CASA_SERVICES=( + "casaos-gateway.service" + "casaos-message-bus.service" + "casaos-user-service.service" + "casaos-local-storage.service" + "casaos-app-management.service" + "casaos.service" + ) + + for SERVICE in "${CASA_SERVICES[@]}"; do + if $SUDO systemctl is-active --quiet "$SERVICE" 2>/dev/null; then + echo " Stopping $SERVICE..." + $SUDO systemctl stop "$SERVICE" || true + fi + done + echo "" +} + +# Function to start CasaOS services +start_casaos_services() { + echo "Starting CasaOS services..." + + CASA_SERVICES=( + "casaos-gateway.service" + "casaos-message-bus.service" + "casaos-user-service.service" + "casaos-local-storage.service" + "casaos-app-management.service" + "casaos.service" + ) + + for SERVICE in "${CASA_SERVICES[@]}"; do + if $SUDO systemctl is-enabled --quiet "$SERVICE" 2>/dev/null; then + echo " Starting $SERVICE..." + $SUDO systemctl start "$SERVICE" || true + fi + done + echo "" +} + +# Function to validate daemon.json +validate_daemon_json() { + local daemon_json="/etc/docker/daemon.json" + + if [ ! -f "$daemon_json" ]; then + return 0 + fi + + # Check if it's valid JSON + if command -v python3 &>/dev/null; then + if ! python3 -m json.tool "$daemon_json" > /dev/null 2>&1; then + echo "ERROR: daemon.json is not valid JSON" + return 1 + fi + elif command -v jq &>/dev/null; then + if ! jq empty "$daemon_json" > /dev/null 2>&1; then + echo "ERROR: daemon.json is not valid JSON" + return 1 + fi + fi + + return 0 +} + +# Function to detect and fix Docker errors +detect_and_fix_docker_errors() { + echo "Analyzing Docker error logs..." + + # Get recent Docker logs + local docker_logs=$($SUDO journalctl -u docker --no-pager -n 100 2>/dev/null) + + # Check for specific errors and apply fixes + + # Error 1: overlay2.override_kernel_check unknown option + if echo "$docker_logs" | grep -q "unknown option overlay2.override_kernel_check"; then + echo "Detected: Invalid overlay2.override_kernel_check option in daemon.json" + echo "Fix: Removing invalid storage-opts from daemon.json..." + + if [ -f /etc/docker/daemon.json ]; then + # Backup the file + $SUDO cp /etc/docker/daemon.json /etc/docker/daemon.json.backup.$(date +%Y%m%d_%H%M%S) + + # Remove the invalid option using python or sed + if command -v python3 &>/dev/null; then + $SUDO python3 << 'EOF' +import json +try: + with open('/etc/docker/daemon.json', 'r') as f: + config = json.load(f) + + # Remove storage-opts if it contains the invalid option + if 'storage-opts' in config: + config['storage-opts'] = [opt for opt in config['storage-opts'] + if 'overlay2.override_kernel_check' not in opt] + if not config['storage-opts']: + del config['storage-opts'] + + with open('/etc/docker/daemon.json', 'w') as f: + json.dump(config, f, indent=2) + print("Fixed: Removed invalid storage-opts") +except Exception as e: + print(f"Error: {e}") +EOF + else + # Fallback: create a simple daemon.json + $SUDO tee /etc/docker/daemon.json > /dev/null </dev/null || true + $SUDO systemctl stop containerd 2>/dev/null || true + + if [ -d /run/containerd ]; then + $SUDO rm -rf /run/containerd/* 2>/dev/null || true + fi + + $SUDO systemctl start containerd 2>/dev/null || true + sleep 2 + echo "Runtime state cleaned" + return 0 + fi + fi + + # Error 4: Address already in use + if echo "$docker_logs" | grep -q "address already in use"; then + echo "Detected: Port conflict" + echo "Fix: Cleaning stale Docker sockets..." + + $SUDO systemctl stop docker 2>/dev/null || true + $SUDO systemctl stop docker.socket 2>/dev/null || true + + # Remove stale sockets + $SUDO rm -f /var/run/docker.sock + $SUDO rm -f /var/run/docker.pid + + sleep 2 + echo "Stale sockets removed" + return 0 + fi + + echo "No specific Docker errors detected in logs" + return 1 +} + +# Function to remove standalone Docker Compose if it exists +remove_standalone_docker_compose() { + if command -v docker-compose &>/dev/null; then + echo "Standalone docker-compose found. Checking installation method..." + + # Check if docker-compose was installed via package manager + if dpkg -l | grep -qw docker-compose 2>/dev/null; then + echo "Removing docker-compose installed via package manager..." + $SUDO apt-get remove -y docker-compose + else + echo "Removing standalone docker-compose binary..." + $SUDO rm -f $(which docker-compose) + fi + echo "" + fi +} + +# Function to clean Docker state and fix permissions +clean_docker_state() { + echo "Cleaning Docker state and fixing permissions..." + + # Stop Docker first + if $SUDO systemctl is-active --quiet docker; then + echo "Stopping Docker service..." + $SUDO systemctl stop docker + sleep 2 + echo "" + fi + + # Clean up Docker runtime state + if [ -d /var/run/docker ]; then + echo "Cleaning Docker runtime state..." + $SUDO rm -rf /var/run/docker/* + echo "" + fi + + # Fix containerd state + if [ -d /run/containerd ]; then + echo "Cleaning containerd state..." + $SUDO rm -rf /run/containerd/runc + $SUDO rm -rf /run/containerd/io.containerd* + echo "" + fi + + # Clean up any stale container state + if [ -d /var/lib/docker/containers ]; then + echo "Cleaning container state..." + $SUDO find /var/lib/docker/containers -name "*.pid" -delete 2>/dev/null || true + echo "" + fi + + # Fix core Docker directory permissions + if [ -d /var/lib/docker ]; then + echo "Fixing Docker directory permissions..." + $SUDO chown -R root:root /var/lib/docker + $SUDO chmod 711 /var/lib/docker + + # Fix specific subdirectories + [ -d /var/lib/docker/overlay2 ] && $SUDO chmod 755 /var/lib/docker/overlay2 + [ -d /var/lib/docker/containers ] && $SUDO chmod 755 /var/lib/docker/containers + [ -d /var/lib/docker/image ] && $SUDO chmod 755 /var/lib/docker/image + [ -d /var/lib/docker/volumes ] && $SUDO chmod 755 /var/lib/docker/volumes + + # Fix overlay2/l directory which is critical for overlay2 storage + if [ -d /var/lib/docker/overlay2/l ]; then + $SUDO chmod 700 /var/lib/docker/overlay2/l + fi + echo "" + fi + + echo "Docker state cleanup complete" + echo "" +} + +# Function to downgrade Docker to compatible version +downgrade_docker() { + echo "Setting up Docker repository..." + $SUDO apt-get update + echo "" + + echo "Installing prerequisites..." + $SUDO apt-get install -y \ + apt-transport-https \ + ca-certificates \ + curl \ + gnupg \ + lsb-release + echo "" + + # Add Docker's official GPG key + echo "Adding Docker's official GPG key..." + $SUDO install -m 0755 -d /etc/apt/keyrings + $SUDO curl -fsSL https://download.docker.com/linux/${OS}/gpg -o /etc/apt/keyrings/docker.asc + $SUDO chmod a+r /etc/apt/keyrings/docker.asc + echo "" + + # Set up the stable repository + echo "Setting up Docker repository..." + echo \ + "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/${OS} \ + ${VERSION_CODENAME} stable" | \ + $SUDO tee /etc/apt/sources.list.d/docker.list > /dev/null + echo "" + + # Update package index with new repository + echo "Updating package lists with Docker repository..." + $SUDO apt-get update + echo "" + + # Get available versions + echo "Available Docker CE versions:" + apt-cache madison docker-ce | head -n 5 + echo "" + + # Hold Docker packages to prevent auto-upgrade + echo "Configuring Docker packages to prevent auto-upgrade..." + $SUDO apt-mark unhold docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin 2>/dev/null || true + echo "" + + # Install specific Docker version compatible with CasaOS + echo "Installing Docker version compatible with CasaOS (24.0.7)..." + + ARCH=$(dpkg --print-architecture) + DOCKER_CE_FULL="${DOCKER_CE_VERSION}${OS}~${VERSION_CODENAME}" + DOCKER_CLI_FULL="${DOCKER_CLI_VERSION}${OS}~${VERSION_CODENAME}" + CONTAINERD_FULL="${CONTAINERD_VERSION}~${OS}~${VERSION_CODENAME}" + + # Check if we're in LXC and warn about containerd version + if check_lxc_environment; then + echo "" + echo "==========================================" + echo "LXC/Proxmox Environment Detected" + echo "==========================================" + echo "" + echo "Installing containerd.io ${CONTAINERD_VERSION} to avoid CVE-2025-52881 AppArmor issues." + echo "This version is safe and prevents 'permission denied' errors on sysctl." + echo "" + echo "For more information, see:" + echo "https://github.com/opencontainers/runc/issues/4968" + echo "" + fi + + echo "Installing docker-ce-cli=${DOCKER_CLI_FULL}" + echo "Installing docker-ce=${DOCKER_CE_FULL}" + echo "Installing containerd.io=${CONTAINERD_FULL}" + echo "" + + $SUDO apt-get install -y --allow-downgrades \ + docker-ce-cli=${DOCKER_CLI_FULL} \ + docker-ce=${DOCKER_CE_FULL} \ + containerd.io=${CONTAINERD_FULL} \ + docker-buildx-plugin \ + docker-compose-plugin || { + echo "" + echo "Specific version installation failed. Trying alternative method..." + echo "" + + # Fallback: try without the full version string but keep containerd specific + $SUDO apt-get install -y --allow-downgrades \ + docker-ce=5:24.0.* \ + docker-ce-cli=5:24.0.* \ + containerd.io=${CONTAINERD_FULL} \ + docker-buildx-plugin \ + docker-compose-plugin || { + # Last resort: try with pattern match for containerd + echo "" + echo "Trying with containerd.io version pattern..." + echo "" + $SUDO apt-get install -y --allow-downgrades \ + docker-ce=5:24.0.* \ + docker-ce-cli=5:24.0.* \ + containerd.io=1.7.28-1* \ + docker-buildx-plugin \ + docker-compose-plugin + } + } + echo "" + + # Hold packages to prevent auto-upgrade + echo "Holding Docker packages at current version..." + $SUDO apt-mark hold docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin + echo "" + + # Check if daemon.json exists and validate it + if [ -f /etc/docker/daemon.json ]; then + echo "Existing daemon.json found - preserving user configuration..." + if ! validate_daemon_json; then + echo "WARNING: Your existing daemon.json may have syntax errors" + echo "Please check /etc/docker/daemon.json for any issues" + else + echo "Existing daemon.json is valid - keeping it unchanged" + fi + else + echo "No daemon.json found - Docker will use default settings" + fi + echo "" + + # Fix overlay2 permissions if directory exists + if [ -d /var/lib/docker/overlay2 ]; then + echo "Fixing overlay2 directory permissions..." + $SUDO chown -R root:root /var/lib/docker/overlay2 + $SUDO chmod -R 755 /var/lib/docker/overlay2 + if [ -d /var/lib/docker/overlay2/l ]; then + $SUDO chmod 700 /var/lib/docker/overlay2/l + fi + echo "" + fi + + # Reload systemd and restart Docker service + echo "Reloading systemd daemon..." + $SUDO systemctl daemon-reload + echo "" + + # Stop docker socket to prevent auto-restart + echo "Stopping Docker socket and service..." + $SUDO systemctl stop docker.socket 2>/dev/null || true + $SUDO systemctl stop docker + sleep 2 + echo "" + + # Start docker socket first, then service + echo "Starting Docker socket..." + $SUDO systemctl start docker.socket + sleep 1 + echo "" + + echo "Starting Docker service..." + $SUDO systemctl start docker + sleep 3 + echo "" + + # Verify Docker is running + if ! $SUDO systemctl is-active --quiet docker; then + echo "==========================================" + echo "ERROR: Docker service failed to start" + echo "==========================================" + echo "" + echo "Checking Docker status and logs..." + $SUDO systemctl status docker --no-pager -l || true + echo "" + echo "Recent Docker logs:" + $SUDO journalctl -u docker --no-pager -n 50 || true + echo "" + + # Attempt to detect and fix the error + echo "==========================================" + echo "Attempting automatic error detection and fix..." + echo "==========================================" + echo "" + + if detect_and_fix_docker_errors; then + # Try to start Docker again after fix + echo "" + echo "Reloading systemd and restarting Docker..." + $SUDO systemctl daemon-reload + $SUDO systemctl stop docker.socket 2>/dev/null || true + $SUDO systemctl stop docker 2>/dev/null || true + sleep 2 + $SUDO systemctl start docker.socket + sleep 1 + $SUDO systemctl start docker + sleep 3 + + if $SUDO systemctl is-active --quiet docker; then + echo "✓ Docker started successfully after automatic fix!" + echo "" + else + echo "✗ Docker still failed to start after automatic fix" + echo "" + echo "Checking for daemon.json syntax errors..." + if command -v dockerd &>/dev/null; then + $SUDO dockerd --validate 2>&1 || true + fi + echo "" + echo "Please check the error messages above." + if [ -f /etc/docker/daemon.json ]; then + echo "daemon.json location: /etc/docker/daemon.json" + echo "Backups are in: /etc/docker/daemon.json.backup.*" + fi + echo "" + return 1 + fi + else + echo "Could not automatically detect/fix the error" + echo "" + if [ -f /etc/docker/daemon.json ]; then + echo "daemon.json location: /etc/docker/daemon.json" + echo "You may need to manually review this file" + fi + echo "" + return 1 + fi + else + echo "Docker service started successfully!" + echo "" + + # Test Docker functionality + echo "Testing Docker functionality..." + if $SUDO docker info >/dev/null 2>&1; then + echo "Docker is responding correctly!" + echo "" + + # Additional test: Try to run a simple container to check for runtime errors + echo "Testing container creation..." + if $SUDO docker run --rm hello-world >/dev/null 2>&1; then + echo "✓ Container test successful - Docker is fully functional" + else + echo "⚠ Container test failed - attempting to fix runtime issues..." + + # Check for the specific sysctl permission error + test_output=$($SUDO docker run --rm hello-world 2>&1 || true) + if echo "$test_output" | grep -q "open sysctl.*permission denied"; then + echo "" + echo "Detected: Container runtime sysctl permission error (CVE-2025-52881)" + echo "" + + # Check containerd version + local current_containerd=$(check_containerd_version) + echo "Current containerd.io version: $current_containerd" + + if [[ "$current_containerd" =~ 1\.7\.(28-2|29) ]] || [[ "$current_containerd" =~ 1\.7\.(3[0-9]) ]]; then + echo "" + echo "==========================================" + echo "ERROR: Problematic containerd.io version detected!" + echo "==========================================" + echo "" + echo "You have containerd.io $current_containerd which causes this error." + echo "This script should have installed version 1.7.28-1." + echo "" + echo "This is a known issue with newer containerd versions in LXC/Proxmox." + echo "See: https://github.com/opencontainers/runc/issues/4968" + echo "" + echo "To fix manually:" + echo " sudo apt-get install -y --allow-downgrades containerd.io=1.7.28-1~${OS}~${VERSION_CODENAME}" + echo " sudo apt-mark hold containerd.io" + echo " sudo systemctl restart docker" + echo "" + return 1 + fi + + echo "This error can also indicate corrupted Docker storage" + echo "" + echo "==========================================" + echo "RECOMMENDED ACTION: Full Docker Reset" + echo "==========================================" + echo "" + echo "This will:" + echo " • Remove all containers and images" + echo " • Clear all Docker volumes" + echo " • Reset Docker to clean state" + echo " • Fix all permission issues" + echo "" + + # Ask for user confirmation + read -p "Do you want to proceed with Docker reset? (yes/no): " -r + echo "" + + if [[ $REPLY =~ ^[Yy][Ee][Ss]$ ]] || [[ $REPLY =~ ^[Yy]$ ]]; then + echo "Performing Docker reset..." + + # Stop all Docker services + $SUDO systemctl stop docker.socket 2>/dev/null || true + $SUDO systemctl stop docker 2>/dev/null || true + $SUDO systemctl stop containerd 2>/dev/null || true + sleep 2 + + # Backup important data + timestamp=$(date +%Y%m%d_%H%M%S) + echo "Creating backup at /var/lib/docker.backup.$timestamp ..." + $SUDO mv /var/lib/docker /var/lib/docker.backup.$timestamp + + # Recreate Docker directory structure + echo "Creating fresh Docker directory structure..." + $SUDO mkdir -p /var/lib/docker + $SUDO chmod 711 /var/lib/docker + + # Clean all runtime state + $SUDO rm -rf /run/containerd/* 2>/dev/null || true + $SUDO rm -rf /var/run/docker/* 2>/dev/null || true + + # Restart services + echo "Starting Docker services..." + $SUDO systemctl start containerd 2>/dev/null || true + sleep 2 + $SUDO systemctl start docker.socket + sleep 1 + $SUDO systemctl start docker + sleep 5 + + # Test again + echo "Testing Docker after reset..." + if $SUDO docker run --rm hello-world >/dev/null 2>&1; then + echo "" + echo "✓ Docker reset successful!" + echo "✓ Containers can now run properly" + echo "" + echo "Your old data is backed up at:" + echo " /var/lib/docker.backup.$timestamp" + echo "" + else + echo "" + echo "✗ Docker still has issues after reset" + echo "Please check the logs with:" + echo " sudo journalctl -u docker --no-pager -n 100" + fi + else + echo "Docker reset cancelled." + echo "" + echo "⚠ WARNING: Your Docker installation has container runtime errors" + echo "Containers will not be able to start until this is resolved." + echo "" + echo "To manually reset later:" + echo " sudo systemctl stop docker" + echo " sudo mv /var/lib/docker /var/lib/docker.backup" + echo " sudo systemctl start docker" + fi + else + echo "⚠ Container test failed for unknown reason" + echo "Error output:" + echo "$test_output" + fi + fi + else + echo "Warning: Docker started but may not be fully functional" + $SUDO docker info || true + fi + fi + echo "" +} + +# Main function +main() { + echo "Step 1: Checking system..." + check_sudo + detect_os + + echo "Step 2: Checking for CasaOS..." + CASAOS_INSTALLED=false + if check_casaos; then + CASAOS_INSTALLED=true + fi + echo "" + + echo "Step 2a: Checking environment..." + if check_lxc_environment; then + echo "Running in LXC/Proxmox container - will use containerd.io ${CONTAINERD_VERSION}" + echo "This avoids CVE-2025-52881 AppArmor sysctl permission issues." + else + echo "Running on standard system (not LXC)" + fi + echo "" + + echo "Step 3: Displaying current Docker versions..." + display_versions + + echo "Step 4: Stopping CasaOS services (if installed)..." + if [ "$CASAOS_INSTALLED" = true ]; then + stop_casaos_services + else + echo "CasaOS not installed, skipping service stop." + echo "" + fi + + echo "Step 5: Removing standalone docker-compose if present..." + remove_standalone_docker_compose + + echo "Step 6: Cleaning Docker state and fixing permissions..." + clean_docker_state + + echo "Step 7: Installing Docker version compatible with CasaOS..." + if ! downgrade_docker; then + echo "==========================================" + echo "ERROR: Docker installation/configuration failed" + echo "==========================================" + echo "" + echo "Attempting to start Docker..." + + # Try to start Docker + $SUDO systemctl start docker.socket 2>/dev/null || true + $SUDO systemctl start docker + sleep 3 + + if ! $SUDO systemctl is-active --quiet docker; then + echo "Could not start Docker. Please check the error messages above." + exit 1 + fi + + echo "Docker started with previous configuration." + echo "The version downgrade may have failed, but Docker is running." + echo "" + fi + + echo "==========================================" + echo "Docker Configuration Complete!" + echo "==========================================" + echo "" + echo "Current Docker versions:" + docker version 2>&1 || echo "Unable to get Docker version" + echo "" + if command -v docker &>/dev/null; then + docker compose version 2>&1 || echo "Unable to get Docker Compose version" + fi + echo "" + + if [ "$CASAOS_INSTALLED" = true ]; then + echo "Step 8: Restarting CasaOS services..." + start_casaos_services + + echo "==========================================" + echo "CasaOS Docker Fix Complete!" + echo "==========================================" + echo "" + echo "Docker has been set to version 24.0.7 (compatible with CasaOS)" + echo "Docker packages have been held to prevent automatic upgrades." + echo "" + echo "To allow Docker to be upgraded in the future, run:" + echo " sudo apt-mark unhold docker-ce docker-ce-cli containerd.io" + echo "" + echo "If you found this helpful, please consider supporting BigBear:" + echo " https://ko-fi.com/bigbeartechworld" + echo "" + else + echo "==========================================" + echo "Docker version has been set to 24.0.7" + echo "This version is compatible with CasaOS API 1.43" + echo "==========================================" + echo "" + fi + + echo "The Docker client version error should now be resolved." + echo "You can now run your Docker commands without API version issues." +} + +# Execute the main function +main