Docker Daemon Socket Errors — Why Disk Full Crashes CI/CD
100% disk usage silently crashes dockerd and blocks all CI/CD builds.
20+ years shipping production infrastructure and CI/CD at scale. Drawn from code that ran under real load.
- ✓Basic programming fundamentals
- ✓A computer with internet access
- ✓Willingness to follow along with examples
- Error: 'Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?' means the Docker CLI cannot reach the daemon process
- The daemon listens on a Unix socket at /var/run/docker.sock by default
- Common causes: daemon not running, permission denied, socket missing, WSL2 issues
- Fix: start the daemon, add user to docker group, or check socket permissions
- On Linux, run: sudo systemctl start docker
- Biggest mistake: running everything with sudo instead of fixing group permissions
The 'Cannot connect to the Docker daemon' error is the most common and infuriating connectivity failure in containerized development. It occurs when the Docker CLI client cannot reach the Docker daemon (dockerd) through its Unix socket, typically located at /var/run/docker.sock.
This socket is the primary IPC endpoint — a file-based communication channel that the CLI uses to send API requests to the daemon. When the disk hosting that socket fills up, the daemon cannot write to its internal state or create new containers, causing it to silently drop the socket connection or refuse new ones.
The result is a cryptic error that halts CI/CD pipelines, local builds, and any Docker operation dead in its tracks.
This error is fundamentally different from permission-denied issues (which produce 'permission denied' or 'dial unix /var/run/docker.sock: connect: permission denied'). A disk-full scenario manifests as a connection refused or timeout because the daemon has effectively stopped listening.
In production CI/CD environments like GitHub Actions, Jenkins, or GitLab CI, this is catastrophic — a full disk on the build runner means every subsequent job fails immediately, often cascading across teams. The root cause is almost always log files, dangling images, or build cache consuming the partition where /var/lib/docker or the socket directory resides.
You should not confuse this with Docker Desktop's socket behavior on macOS/Windows, where the socket is actually a symlink to a gRPC FUSE proxy inside a VM. On those platforms, disk-full errors manifest differently — the VM disk fills up, not the host socket.
The fix differs accordingly. In production, the only reliable prevention is aggressive log rotation, periodic docker system prune, and monitoring disk usage on the Docker data directory. Systemd-based systems add another layer of complexity: the docker.socket unit can be activated independently of docker.service, meaning the socket file exists and is listening, but the daemon itself may be dead or unresponsive due to disk pressure — a silent betrayal that makes debugging even harder.
Docker has two parts: the command-line tool you type commands into, and a background service (the daemon) that actually does the work. This error means the command-line tool tried to talk to the background service, but the line was dead. Either the service is not running, your user does not have permission to pick up the phone, or the phone line (socket file) is missing entirely.
The error 'Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?' occurs when the Docker CLI cannot communicate with the Docker daemon process. The daemon is the background service that manages containers, images, networks, and volumes.
This error blocks all Docker operations — every docker command will fail until the connection is restored. The root cause varies across environments: the daemon may not be running, the user may lack socket permissions, or the socket file may be missing entirely. This guide covers every cause, the exact fix for each, and prevention strategies for production systems.
What Causes This Error?
The error 'Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?' occurs when the Docker CLI cannot establish a connection to the Docker daemon process through the Unix socket.
The Docker architecture has two components: the Docker CLI (the command you type) and the Docker daemon (the background service that manages containers). The CLI communicates with the daemon through a Unix socket at /var/run/docker.sock. When this socket is unavailable, inaccessible, or the daemon process is not running, every Docker command fails with this error.
There are five primary causes: the daemon is not running, the user lacks socket permissions, the socket file is missing, the disk is full, or the environment is misconfigured (WSL2, remote Docker hosts). Each cause requires a different fix.
import os import subprocess import json from dataclasses import dataclass from typing import Optional, Dict, List from enum import Enum class DaemonStatus(Enum): RUNNING = "running" STOPPED = "stopped" FAILED = "failed" UNKNOWN = "unknown" NOT_INSTALLED = "not_installed" class SocketStatus(Enum): EXISTS = "exists" MISSING = "missing" PERMISSION_DENIED = "permission_denied" WRONG_PATH = "wrong_path" @dataclass class DiagnosticResult: component: str status: str detail: str fix_command: Optional[str] = None severity: str = "info" class DockerDaemonDiagnostics: """ Diagnoses Docker daemon connection issues. """ SOCKET_PATH = "/var/run/docker.sock" DAEMON_SERVICE = "docker" @staticmethod def check_daemon_installed() -> DiagnosticResult: """ Check if Docker is installed. """ try: result = subprocess.run( ["docker", "--version"], capture_output=True, text=True, timeout=5 ) if result.returncode == 0: return DiagnosticResult( component="docker_installation", status="installed", detail=result.stdout.strip(), severity="info", ) return DiagnosticResult( component="docker_installation", status="error", detail="Docker command exists but returned an error", severity="warning", ) except FileNotFoundError: return DiagnosticResult( component="docker_installation", status="not_installed", detail="Docker CLI not found in PATH", fix_command="Install Docker: https://docs.docker.com/engine/install/", severity="critical", ) @staticmethod def check_daemon_running() -> DiagnosticResult: """ Check if the Docker daemon process is running. """ try: result = subprocess.run( ["systemctl", "is-active", "docker"], capture_output=True, text=True, timeout=5 ) status = result.stdout.strip() if status == "active": return DiagnosticResult( component="daemon_process", status="running", detail="Docker daemon is active and running", severity="info", ) elif status == "inactive": return DiagnosticResult( component="daemon_process", status="stopped", detail="Docker daemon is installed but not running", fix_command="sudo systemctl start docker && sudo systemctl enable docker", severity="critical", ) elif status == "failed": return DiagnosticResult( component="daemon_process", status="failed", detail="Docker daemon entered a failed state", fix_command="sudo journalctl -u docker.service -n 50 --no-pager", severity="critical", ) else: return DiagnosticResult( component="daemon_process", status="unknown", detail=f"Unexpected daemon status: {status}", severity="warning", ) except FileNotFoundError: return DiagnosticResult( component="daemon_process", status="unknown", detail="systemctl not found — possibly macOS or non-systemd Linux", severity="info", ) @staticmethod def check_socket() -> DiagnosticResult: """ Check if the Docker socket exists and is accessible. """ socket_path = DockerDaemonDiagnostics.SOCKET_PATH if not os.path.exists(socket_path): return DiagnosticResult( component="socket_file", status="missing", detail=f"Socket file does not exist at {socket_path}", fix_command="sudo systemctl restart docker", severity="critical", ) if not os.access(socket_path, os.R_OK | os.W_OK): stat_info = os.stat(socket_path) import grp try: group_name = grp.getgrgid(stat_info.st_gid).gr_name except KeyError: group_name = str(stat_info.st_gid) return DiagnosticResult( component="socket_permissions", status="permission_denied", detail=f"Socket exists but current user lacks read/write permissions. Socket group: {group_name}", fix_command=f"sudo usermod -aG {group_name} $USER && newgrp {group_name}", severity="critical", ) return DiagnosticResult( component="socket_file", status="exists", detail=f"Socket file exists and is accessible at {socket_path}", severity="info", ) @staticmethod def check_disk_space() -> DiagnosticResult: """ Check disk space on the Docker data directory. """ docker_root = "/var/lib/docker" if not os.path.exists(docker_root): return DiagnosticResult( component="disk_space", status="unknown", detail=f"Docker data directory not found at {docker_root}", severity="warning", ) stat = os.statvfs(docker_root) free_gb = (stat.f_bavail * stat.f_frsize) / (1024 ** 3) total_gb = (stat.f_blocks * stat.f_frsize) / (1024 ** 3) used_pct = ((total_gb - free_gb) / total_gb) * 100 if used_pct > 95: return DiagnosticResultcritical", detail=f"Disk usage at {used_pct:.1f}% — {free_gb:.1f}GB free of {total_gb:.1f}GB", fix_command="docker system prune -af --volumes", severity="critical", ) elif used_pct > 80: return DiagnosticResult( component="disk_space", status="warning", detail=f"Disk usage at {used_pct:.1f}% — {free_gb:.1f}GB free of {total_gb:.1f}GB", fix_command="docker system prune -af --filter 'until=168h'", severity="warning", ) return DiagnosticResult( component="disk_space", status="healthy", detail=f"Disk usage at {used_pct:.1f}% — {free_gb:.1f}GB free of {total_gb:.1f}GB", severity="info", ) @staticmethod def check_user_group() -> DiagnosticResult: """ Check if the current user is in the docker group. """ try: result = subprocess.run( ["groups"], capture_output=True, text=True, timeout=5 ) groups = result.stdout.strip().split() if "docker" in groups: return DiagnosticResult( component="user_group", status="member", detail="Current user is in the docker group", severity="info", ) else: return DiagnosticResult( component="user_group", status="not_member", detail=f"Current user ({os.getlogin()}) is not in the docker group. Groups: {', '.join(groups)}", fix_command="sudo usermod -aG docker $USER && newgrp docker", severity( component="disk_space", status="="critical", ) except Exception as e: return DiagnosticResult( component="user_group", status="unknown", detail=f"Could not check group membership: {e}", severity="warning", ) @staticmethod def run_full_diagnosis() -> List[DiagnosticResult]: """ Run all diagnostic checks and return results. """ checks = [ DockerDaemonDiagnostics.check_daemon_installed(), DockerDaemonDiagnostics.check_daemon_running(), DockerDaemonDiagnostics.check_socket(), DockerDaemonDiagnostics.check_disk_space(), DockerDaemonDiagnostics.check_user_group(), ] return checks @staticmethod def print_report(results: List[DiagnosticResult]) -> None: """ Print a formatted diagnostic report. """ severity_icons = { "critical": "[FAIL]", "warning": "[WARN]", "info": "[ OK ]", } print("\nDocker Daemon Diagnostic Report") print("=" * 60) for r in results: icon = severity_icons.get(r.severity, "[????]") print(f"\n{icon} {r.component}: {r.status}") print(f" {r.detail}") if r.fix_command: print(f" Fix: {r.fix_command}") critical = [r for r in results if r.severity == "critical"] if critical: print(f"\n{'=' * 60}") print(f"ACTION REQUIRED: {len(critical)} critical issue(s) found.") print("Run the fix commands above to resolve.") # Example usage if __name__ == "__main__": results = DockerDaemonDiagnostics.run_full_diagnosis() DockerDaemonDiagnostics.print_report(results)
- Docker CLI = the command you type (docker run, docker ps, etc.)
- Docker daemon = the background service (dockerd) that does the actual work
- Unix socket = the communication channel between CLI and daemon at /var/run/docker.sock
- If the socket is missing, broken, or permission-denied, all docker commands fail
- The daemon is a system service managed by systemd on Linux or Docker Desktop on macOS
Fixing on Linux
Linux is the most common environment for this error because Docker runs as a systemd service and socket permissions depend on group membership. The fix depends on whether the daemon is running, the socket exists, and the user has the correct permissions.
The most frequent cause on Linux is that the Docker daemon service is not running — either it was never started, it crashed, or it was not enabled to start on boot. The second most common cause is permission denied on the socket, which happens when the user is not in the docker group.
#!/bin/bash # ============================================ # Docker Daemon Connection Fix for Linux # Run these commands in order until the error is resolved # ============================================ set -e # Step 1: Check if Docker is installed if ! command -v docker &> /dev/null; then echo "Docker is not installed." echo "Install with: curl -fsSL https://get.docker.com | sh" exit 1 fi echo "Docker version: $(docker --version)" # Step 2: Check daemon status echo "\nChecking daemon status..." sudo systemctl status docker --no-pager # Step 3: Start daemon if not running if ! systemctl is-active --quiet docker; then echo "Daemon is not running. Starting..." sudo systemctl start docker sudo systemctl enable docker echo "Daemon started and enabled on boot." fi # Step 4: Check socket file if [ ! -S /var/run/docker.sock ]; then echo "Socket file missing. Restarting daemon..." sudo# Step 5: Check user group membership if ! groups | grep -q docker; then echo "Current user is not in the docker group systemctl restart docker sleep 2 fi ." echo "Adding user to docker group..." sudo usermod -aG docker $USER echo "Run 'newgrp docker' or log out and back in for changes to take effect." newgrp docker fi # Step 6: Check disk space DOCKER_ROOT="/var/lib/docker" if [ -d "$DOCKER_ROOT" ]; then USAGE=$(df "$DOCKER_ROOT" | tail -1 | awk '{print $5}' | tr -d '%') echo "\nDisk usage on $DOCKER_ROOT: ${USAGE}%" if [ "$USAGE" -gt 90 ]; then echo "WARNING: Disk usage above 90%. Consider running:" echo " docker system prune -af --volumes" fi fi # Step 7: Verify connection echo "\nVerifying Docker connection..." if docker info &> /dev/null; then echo "SUCCESS: Docker daemon is accessible." docker info --format 'Server Version: {{.ServerVersion}}' else echo "FAILED: Still cannot connect to Docker daemon." echo "Check logs: sudo journalctl -u docker.service -n 50" exit 1 fi
Fixing on macOS and Windows (WSL2)
On macOS and Windows, Docker runs inside a lightweight path is ~/.docker/run/docker.sock (not /var/run/docker.sock). Docker Desktop symlinks this to the standard location. On Windows with WSL2, the socket is provided by Docker Desktop's WSL integration — if Docker Desktop is not running on Windows, the WSL2 environment cannot connect.
#!/bin/bash # ============================================ # Docker Daemon Connection Fix for macOS and WSL2 # ============================================ # ---- macOS Fix ---- fix_macos() { echo "Checking Docker Desktop on macOS..." # Check if Docker Desktop is running if ! pgrep -x "Docker Desktop" > /dev/null; then echo "Docker Desktop is not running. Starting..." open -a "Docker Desktop" echo "Waiting for Docker Desktop to start (up to 60 seconds)..." for i in $(seq 1 60); do if docker info &> /dev/null; then echo "Docker Desktop is ready." return 0 fi sleep 1 done echo "Docker Desktop failed to start within 60 seconds." echo "Try: killall Docker Desktop && open -a 'Docker Desktop'" return 1 fi # Check socket symlink if [ ! -S /var/run/docker.sock ]; then echo "Socket symlink missing. Restarting Docker Desktop..." osascript -e 'quit app "Docker Desktop"' sleep 5 open -a "Docker Desktop" sleep 30 fi # Verify if docker info &> /dev/null; then echo "Docker connection OK." else echo "Still cannot connect. Try:" echo " 1. Docker Desktop > Troubleshoot > Clean / Purge data" echo " 2. Docker Desktop > Restart" echo " 3. rm -rf ~/.docker/run/docker.sock && restart Docker Desktop" fi } # ---- WSL2 Fix ---- fix_wsl2() { echo "Checking Docker in WSL2..." # Check if we are in WSL if ! grep -qi microsoft /proc/version 2>/dev/null; then echo "Not running in WSL. Use macOS fix or native Linux fix." return 1 fi # Check if Docker Desktop is running on Windows echo "Ensure Docker Desktop is running on Windows." echo "Check: Docker Desktop > Settings > Resources > WSL Integration" echo "Enable integration for your WSL2 distribution." # Restart WSL echo "\nRestarting WSL to refresh connection..." echo "Run from Windows PowerShell: wsl --shutdown" echo "Then reopen your WSL terminal." # Check socket if [ -S /var/run/docker.sock ]; then echo "Socket exists." else echo "Socket missing. Docker Desktop WSL integration may be disabled." echo "Open Docker Desktop > Settings > Resources > WSL Integration" echo "Toggle your distro off and on again." fi } # Main case "$(uname -s)" in Darwin*) fix_macos ;; Linux*) if grep -qi microsoft /proc/version 2>/dev/null; then fix_wsl2 else echo "Use the Linux fix script instead." fi ;; *) echo "Unsupported OS: $(uname -s)" ;; esac
- Docker Desktop must be running — it manages the VM that hosts the Docker daemon
- On macOS, the socket is at ~/.docker/run/docker.sock — Docker Desktop symlinks it
- On WSL2, Docker Desktop provides the daemon — do not install Docker Engine inside WSL2
- If WSL integration breaks, toggle it off and on in Docker Desktop Settings
- Docker Desktop uses significant RAM (2-4GB) — check if the VM has enough memory
Preventing This Error in Production
Preventing Docker daemon connection errors in production requires proactive monitoring, automatic recovery, and proper system configuration. Reactive fixes are unacceptable when container orchestration depends on daemon availability.
Three prevention strategies are essential: systemd watchdog for automatic daemon restart, disk usage monitoring with automatic pruning, and socket permission enforcement across deployments. These strategies ensure the daemon recovers from crashes without manual intervention.
#!/bin/bash # ============================================ # Docker Daemon Prevention Strategies # Run once on every production Docker host # ============================================ set -e # ---- Strategy 1: Systemd Watchdog ---- # Automatically restart Docker daemon if it becomes unresponsive setup_watchdog() { echo "Setting up systemd watchdog for Docker daemon..." # Create override directory sudo mkdir -p /etc/systemd/system/docker.service.d # Create watchdog override sudo tee /etc/systemd/system/docker.service.d/watchdog.conf > /dev/null << 'EOF' [Service] WatchdogSec=60 Restart=always RestartSec=5 EOF # Create health check script sudo tee /usr/local/bin/docker-healthcheck.sh > /dev/null << 'EOF' #!/bin/bash if docker info &> /dev/null; then exit 0 else exit 1 fi EOF sudo chmod +x /usr/local/bin/docker-healthcheck.sh # Reload systemd sudo systemctl daemon-reload sudo systemctl restart docker echo "Watchdog configured. Daemon will restart if unresponsive for 60 seconds." } # ---- Strategy 2: Automatic Disk Pruning ---- # Prevent disk exhaustion that crashes the daemon setup_auto_prune() { echo "Setting up automatic Docker disk pruning..." # Create pruning script sudo tee /usr/local/bin/docker-prune.sh > /dev/null << 'EOF' #!/bin/bash # Remove images older than 7 days # Keep running containers and their images LOGFILE="/var/log/docker-prune.log" { echo "=== Docker Prune: $(date) ===" echo "Before:" docker system df # Prune stopped containers, unused networks, dangling images docker system prune -f --filter "until=168h" # Prune unused images (not just dangling) docker image prune -af --filter "until=168h" # Prune build cache older than 7 days docker builder prune -f --filter "until=168h" echo "After:" docker system df echo "=== Done ===" } >> "$LOGFILE" 2>&1 EOF sudo chmod +x /usr/local/bin/docker-prune.sh # Add cron job: run every Sunday at 3 AM CRON_JOB="0 3 * * 0 /usr/local/bin/docker-prune.sh" (crontab -l 2>/dev/null | grep -v docker-prune; echo "$CRON_JOB") | crontab - echo "Auto-prune configured. Runs every Sunday at 3 AM." } # ---- Strategy 3: Disk Usage Alerting ---- # Alert before disk reaches critical levels setup_disk_alerts() { echo "Setting up disk usage alerts..." sudo tee /usr/local/bin/docker-disk-alert.sh > /dev/null << 'EOF' #!/bin/bash DOCKER_ROOT="/var/lib/docker" THRESHOLD=85 USAGE=$(df "$DOCKER_ROOT" | tail -1 | awk '{print $5}' | tr -d '%') if [ "$USAGE" -ge "$THRESHOLD" ]; then echo "WARNING: Docker disk usage at ${USAGE}% (threshold: ${THRESHOLD}%)" echo "Running containers:" docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Size}}' echo "\nDisk breakdown:" docker system df # Send alert (customize for your alerting system) # curl -X POST https://alerts.example.com/webhook -d "{\"text\": \"Docker disk at ${USAGE}%\"}" fi EOF sudo chmod +x /usr/local/bin/docker-disk-alert.sh # Add cron job: check every 15 minutes CRON_JOB="*/15 * * * * /usr/local/bin/docker-disk-alert.sh" (crontab -l 2>/dev/null | grep -v docker-disk-alert; echo "$CRON_JOB") | crontab - echo "Disk alerting configured. Checks every 15 minutes at 85% threshold." } # ---- Strategy 4: Socket Permission Enforcement ---- # Ensure socket permissions survive Docker upgrades setup_socket_permissions() { echo "Enforcing socket permissions..." # Ensure docker group exists sudo groupadd -f docker # Set socket ownership sudo tee /etc/docker/daemon.json > /dev/null << 'EOF' { "group": "docker", "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "3" }, "storage-driver": "overlay2" } EOF sudo systemctl restart docker echo "Socket permissions enforced via daemon.json." } # Main setup_watchdog setup_auto_prune setup_disk_alerts setup_socket_permissions echo "\nAll prevention strategies configured." echo "Docker daemon will now:" echo " - Auto-restart if unresponsive (60s watchdog)" echo " - Auto-prune old resources (weekly)" echo " - Alert at 85% disk usage (every 15 min)" echo " - Maintain socket permissions across restarts"
- systemd watchdog restarts the daemon automatically if it becomes unresponsive
- Automatic pruning prevents disk exhaustion — the #1 cause of daemon crashes
- Disk alerts give you time to act before the daemon crashes
- Socket permissions in daemon.json survive Docker upgrades and reboots
- For zero-downtime, run Docker across multiple hosts with orchestration (Swarm, Kubernetes)
The Socket Showdown: Docker Group vs. Root Access
This isn't a permission bug. It's a design choice. Docker's daemon listens on a Unix socket owned by root. By default, only root or members of the docker group can talk to it. That's the entire root cause. Most tutorials skip the WHY: Docker does this to prevent any random user from spinning up containers that can escape and pwn your host. If you can run docker run --privileged, you can effectively become root inside the container. So the group membership is a security boundary, not a chmod oversight. On Linux, the fix is dead simple: create the group if it doesn't exist, add your user, restart the Docker daemon, then log out and back in. But here's the nuance: /var/run/docker.sock must exist and have 660 permissions. If someone manually tightened permissions or if systemd's socket activation is borked, you'll still get the error. Check with ls -la /var/run/docker.sock. The socket is the gate. Everything else is noise.
// io.thecodeforge — devops tutorial # Verify socket exists and permissions are correct - name: Check Docker socket permissions shell: ls -la /var/run/docker.sock register: socket_info - name: Fail if socket missing or wrong ownership fail: msg: "Docker socket is absent or owned by wrong group." when: socket_info.stdout.find('srw-rw---- 1 root docker') == -1 # Expected output: # srw-rw---- 1 root docker 0 Jan 15 09:42 /var/run/docker.sock
Systemd's Silent Betrayal: Service vs. Socket Units
When you run systemctl start docker, you assume the daemon starts. But Docker ships with two systemd units: docker.service and docker.socket. The socket unit activates the service on demand. If the socket unit isn't running, the service can't bind to the socket. You get the "Cannot connect to the Docker daemon" error even if Docker itself is installed. This is a frequent footgun on Fedora, CentOS, and Arch. The fix: systemctl enable --now docker.socket. But here's the real WTF: if you manually start only the service (systemctl start docker), systemd's socket activation may leave the socket in a broken state if the service crashes. Check both. Run systemctl status docker.socket and systemctl status docker.service. If the socket is active but the service is dead, you have a corrupted state. Kill the socket, kill the service, then restart both in the right order: socket first, then service. Docker's own documentation glosses over this because they assume you use the init script, not raw systemd units. Don't be that dev who spends hours debugging only to find an inactive socket unit.
// io.thecodeforge — devops tutorial - name: Ensure Docker socket unit is active and enabled systemd: name: docker.socket state: started enabled: yes - name: Restart Docker service cleanly systemd: name: docker.service state: restarted daemon_reload: yes - name: Test connection command: docker version changed_when: false # Expected output: # Client: # Version: 24.0.7 # Server: # Engine: # Version: 24.0.7
systemctl start docker. Always do systemctl enable --now docker.socket first. Then start the service. This prevents socket activation conflicts that plague SELinux-heavy distros.WSL2's Dual-Headed Docker: Windows vs. Linux Context
On Windows with WSL2, you get two Docker daemons. One runs inside the Windows Docker Desktop VM. Another could be running inside your WSL2 distro if you installed Docker Engine manually. The error "Cannot connect to the Docker daemon" happens when your WSL2 terminal talks to the wrong daemon or none at all. The fix: decide which one you want. If you use Docker Desktop, it exposes a socket at /var/run/docker.sock inside the WSL2 distro via a bind mount. This works out of the box, but only if Docker Desktop's WSL2 integration is enabled for your specific distro. Open Docker Desktop → Settings → Resources → WSL Integration. Toggle your distro on. If it's off, your socket points to nothing. If you installed Docker Engine inside WSL2, you have a separate daemon that needs its own systemd or init.d management. That's a recipe for port conflicts. Real senior move: use Docker Desktop's integration and never install Docker Engine inside WSL2. It's a maintenance nightmare. But if you must, set DOCKER_HOST to tcp://localhost:2375 and run a separate daemon on a different port. Either way, verify with docker volume ls — if it hangs, your socket is dead.
// io.thecodeforge — devops tutorial # Check which socket is being used - name: Inspect Docker socket in WSL2 shell: ls -la /var/run/docker.sock register: socket_wsl - name: Verify Docker Desktop integration shell: docker context ls register: context_list - name: Set context to default if using Docker Desktop command: docker context use default when: context_list.stdout.find('desktop-linux') != -1 # Expected output of docker context ls: # NAME TYPE DESCRIPTION # default moby Current DOCKER_HOST based configuration # desktop-linux * moby Docker Desktop
docker context show returns default, check if Docker Desktop is actually running. On WSL2, you can have Docker Desktop installed but not started. The socket file exists but points nowhere. Start Docker Desktop from the Windows tray.Docker Daemon Crash During Deployment Blocked All CI/CD Pipelines for 6 Hours
- Docker daemon crashes silently when the disk fills — no graceful degradation
- Monitor Docker daemon health with docker info and systemd watchdog
- Set up automatic image pruning to prevent disk exhaustion
- Build servers need disk monitoring as a first-class concern, not an afterthought
sudo systemctl status dockersudo systemctl start docker && sudo systemctl enable dockersudo usermod -aG docker $USERnewgrp dockerls -la /var/run/docker.socksudo systemctl restart dockerdf -h /var/lib/dockerdocker system prune -af --volumeswsl --shutdownwsl && docker info| Environment | Most Common Cause | Quick Fix | Prevention |
|---|---|---|---|
| Linux (systemd) | Daemon not running | sudo systemctl start docker | systemctl enable docker |
| Linux (permissions) | User not in docker group | sudo usermod -aG docker $USER | Add to docker group at provision time |
| Linux (disk full) | Docker disk usage at 100% | docker system prune -af --volumes | Automatic weekly pruning via cron |
| macOS | Docker Desktop not running | open -a 'Docker Desktop' | Add to Login Items |
| WSL2 | Docker Desktop WSL integration off | Toggle integration in Settings | Enable integration for all distros |
| Snap Docker | Snap socket path different | export DOCKER_HOST=unix:///var/run/snap.docker.socket | Set DOCKER_HOST in shell profile |
| File | Command / Code | Purpose |
|---|---|---|
| io.thecodeforge.docker.daemon_diagnostics.py | from dataclasses import dataclass | What Causes This Error? |
| io.thecodeforge.docker.fix_linux.sh | set -e | Fixing on Linux |
| io.thecodeforge.docker.fix_macos_wsl.sh | fix_macos() { | Fixing on macOS and Windows (WSL2) |
| io.thecodeforge.docker.prevention.sh | set -e | Preventing This Error in Production |
| DockerSocketAudit.yml | - name: Check Docker socket permissions | The Socket Showdown |
| SystemdDockerFix.yml | - name: Ensure Docker socket unit is active and enabled | Systemd's Silent Betrayal |
| WSL2DockerCheck.yml | - name: Inspect Docker socket in WSL2 | WSL2's Dual-Headed Docker |
Key takeaways
Common mistakes to avoid
6 patternsRunning all docker commands with sudo instead of fixing permissions
Not enabling Docker to start on boot
Ignoring disk usage until the daemon crashes
Installing Docker Engine inside WSL2 when Docker Desktop is already running
Not checking daemon logs when the fix commands do not work
Restarting the daemon without checking why it crashed
Interview Questions on This Topic
What does the error 'Cannot connect to the Docker daemon at unix:///var/run/docker.sock' mean?
A developer reports this error on a shared development server. How do you diagnose and fix it?
How would you design a production monitoring system that prevents Docker daemon outages?
Frequently Asked Questions
The Docker daemon runs as root and the Unix socket at /var/run/docker.sock is owned by root:docker with permissions srw-rw----. Only root and members of the docker group can access it. If your user is not in the docker group, you need sudo to access the socket. To fix: sudo usermod -aG docker $USER, then log out and back in.
Adding a user to the docker group is equivalent to giving them root access. A docker group member can mount the host filesystem into a container and read or modify any file on the host. In production, limit docker group membership to trusted administrators. For CI/CD systems, use Docker socket proxies or rootless Docker instead.
Yes, configure a different socket path in /etc/docker/daemon.json with the 'hosts' key, or set the DOCKER_HOST environment variable. For example: export DOCKER_HOST=unix:///custom/path/docker.sock. This is useful for running multiple Docker daemons or using Snap-installed Docker which uses /var/run/snap.docker.socket.
Docker Engine is the standalone daemon ( macOS and Windows that includes Docker Engine running inside a lightweight VM. Docker Desktop manages the VM lifecycle, networking, and WSL2 integration. On Linux, you can use either — Docker Engine for servers, Docker Desktop for development convenience.
On Linux with systemd: sudo systemctl status docker. On any system: docker info. If docker info succeeds, the daemon is running. If it returns the connection error, the daemon is not running or the socket is inaccessible. You can also check the process directly: ps aux | grep dockerd.
This error means the Docker CLI attempted to connect to the Docker daemon through the Unix socket at /var/run/docker.sock but the connection was refused or the socket does not exist. There are four possible causes: (1) The Docker daemon is not running — fix with sudo systemctl start docker on Linux. (2) Your user does not have permission to access the socket — fix with sudo usermod -aG docker $USER. (3) The socket file is missing — check with ls -la /var/run/docker.sock. (4) On WSL2, the Docker Desktop backend is not running — open Docker Desktop on the Windows host and ensure it is started.
20+ years shipping production infrastructure and CI/CD at scale. Drawn from code that ran under real load.
That's Docker. Mark it forged?
3 min read · try the examples if you haven't