Switch Language
Toggle Theme

Docker Installation Guide 2025: Complete Solutions from Permission Denied to Success

Docker Installation Troubleshooting Guide

Introduction

Last Wednesday at 10 PM, I was staring at that red “permission denied” message in my terminal, feeling utterly defeated. This was my third attempt at installing Docker—first time WSL 2 failed, second time the daemon refused to start, and now that it was finally installed, running docker ps gave me… permission denied.

I know you’ve probably experienced this kind of frustration too.

To be honest, installing Docker should be simple: download the installer, double-click, click next. But reality is Windows forces you to deal with WSL 2 and Hyper-V, Mac splits between Intel and Apple Silicon versions, and Linux throws various dependency and permission issues at you. Each platform has its own reserved pit waiting for you to fall in.

This article is my post-mortem after falling into all those pits. I’ve compiled the 10+ most common issues across Windows, Mac, and Linux, with updated solutions for 2025 (yes, many tutorials from 2020-2022 are already outdated). So, which platform gave you which error? Keep reading—there’s a solution for you here.

Windows Platform Issues

Installing Docker on Windows basically means wrestling with two brothers: WSL 2 and Hyper-V. Docker Desktop now requires WSL 2 backend, and if your system version is wrong or virtualization isn’t enabled, you’ll see all sorts of cryptic error messages.

Issue 1: Incomplete WSL 2 Installation

This is what Windows users encounter most. You click to install Docker Desktop, and a popup tells you “WSL 2 installation is incomplete,” then says nothing else, leaving you completely confused.

The error looks like this:

Docker Desktop requires WSL 2 backend
WSL 2 installation is incomplete

The root cause is actually three things: your Windows version is too old (below 10.0.19041), or WSL features aren’t enabled at all, or virtualization is disabled in BIOS.

How to fix it:

First step, check Windows version. Press Win+R, type winver and hit enter, check the version number. You need at least Windows 10 22H2 (build 19045) or Windows 11 23H2 (build 22631+). If you don’t meet this, you need to upgrade your system first.

Second step, enable WSL features. Go to Control Panel → Programs and Features → Turn Windows features on or off, find “Windows Subsystem for Linux” and “Virtual Machine Platform,” check both. You must restart after this step, don’t skip it.

Third step, update WSL version. After restarting, open PowerShell (as administrator) and run:

wsl --update
wsl --set-default-version 2

First line updates WSL to the latest version (you need 2.1.5+), second line sets WSL 2 as default.

If it still doesn’t work, you need to enter BIOS. Restart your computer, press Del or F2 (depends on motherboard brand), find Virtualization Technology or Intel VT-x/AMD-V option, change it to Enabled. Intel calls it VT-x, AMD calls it AMD-V—same thing.

Issue 2: Hyper-V Conflicts

Sometimes you’ll see this weird error:

HCS_E_HYPERV_NOT_INSTALLED
Docker Desktop - Unexpected WSL error

This means Hyper-V isn’t installed or is conflicting with other virtualization software. Docker Desktop relies on Hyper-V (or WSL 2) underneath, and if you have VMware or VirtualBox installed at the same time, conflicts may occur.

How to fix it:

If Hyper-V isn’t enabled, go to Windows features, find “Hyper-V,” check all sub-items, and restart. Note that Windows Home edition doesn’t support Hyper-V—you can only use WSL 2 backend.

If you’re using VMware or VirtualBox simultaneously, you need to choose one. Docker Desktop from version 4.x onwards pushes WSL 2 backend, which has relatively better compatibility. VMware Workstation 15.5+ theoretically can coexist with Hyper-V, but I’ve tried it—there are still various minor issues.

To be honest, the easiest approach is: use Docker Desktop (WSL 2) for development environment, use VMware/VirtualBox for production or test VMs—keep them separate.

Issue 3: Insufficient Installation Permissions

This error usually pops up during installation:

Installation Failed
Component CommunityInstaller.EnableFeaturesAction failed

The reason is simple: you didn’t run the installer with administrator privileges, or antivirus software blocked it.

How to fix it:

Right-click the Docker Desktop installer, select “Run as administrator.” If firewall or antivirus prompts appear during installation, choose allow.

There’s another easily overlooked thing: check C drive space. Docker Desktop needs at least 10GB of free space, and more if you have many images. If C drive is insufficient, you can change Docker data storage location after installation, but that’s another topic.

Oh, and if your company computer has group policy restrictions, you might not be able to install it. In that case, you need to ask IT to grant permissions, or install Docker Engine in Linux subsystem to bypass it (but then you lose the GUI).

Mac Platform Issues

Installing Docker on Mac is relatively hassle-free, but since Apple launched M1/M2 chips, new pits have appeared. Most common is downloading the wrong version—Intel version on Apple Silicon Mac, or vice versa.

Issue 1: M1/M2 Chip Compatibility

Symptoms are pretty obvious: Docker Desktop icon doesn’t appear in menu bar at all, or it appears but keeps showing “Docker Desktop is starting…” forever. Running docker commands in Terminal returns:

Cannot connect to the Docker daemon at unix:///var/run/docker.sock.
Is the docker daemon running?

The problem is most likely you downloaded the wrong installer. Docker’s website has two versions: “Mac with Apple chip” and “Mac with Intel chip”—download the wrong one and it definitely won’t start.

How to fix it:

First confirm what chip your Mac has. Click the Apple logo in upper left → About This Mac, look at the “Chip” line. If it says “Apple M1” or “Apple M2,” you need the Apple Silicon version; if it says “Intel Core,” you need the Intel version.

If you downloaded the wrong one, you need to completely uninstall and reinstall. Open Terminal and run:

# Uninstall Docker Desktop
/Applications/Docker.app/Contents/MacOS/uninstall

# Delete leftover config files
rm -rf ~/Library/Group\ Containers/group.com.docker
rm -rf ~/Library/Containers/com.docker.docker
rm -rf ~/.docker

These commands will completely remove Docker and its cache data. Then go to the official website, download the version for your chip, and install again.

There’s another small detail: M1/M2 Macs need Rosetta 2 to be compatible with some x86 images. If you haven’t installed it, run this:

softwareupdate --install-rosetta

After installation, restart Docker Desktop—it should start normally.

Issue 2: Daemon Startup Stuck

Sometimes Docker Desktop can start, the icon appears, but it’s stuck in “Starting…” state. Opening Activity Monitor, you can see Docker processes running, but you just can’t use it.

This situation is mostly due to corrupted config files or conflicting processes occupying Docker’s ports.

How to fix it:

First move: reset Docker Desktop. Click the Docker icon in menu bar, select Troubleshoot, then click “Reset to factory defaults.” This will clear all containers, images, and configs—essentially restoring factory settings. If you have important images, remember to back them up first.

If reset still doesn’t work, check for port conflicts. Docker uses ports 2375 and 2376 by default, which might be occupied by other programs. Run:

# Check port usage
lsof -i :2375
lsof -i :2376

# If there's output, note the PID and kill the process
kill -9 <PID>

After killing conflicting processes, try restarting Docker Desktop.

There’s an even more aggressive method: delete Docker VM files.

rm -rf ~/Library/Containers/com.docker.docker/Data/vms

This will force Docker to rebuild the VM environment. After deletion, restart Docker Desktop—it will automatically create a new VM.

Issue 3: File Mount Permission Denied

When running a container with a local directory mount, you get an error:

Error response from daemon: Mounts denied:
The path /Users/yourname/project is not shared from the host and is not known to Docker.

This means Docker doesn’t have permission to access the directory you want to mount. macOS takes privacy seriously—Docker can only access specific paths by default.

How to fix it:

Open Docker Desktop settings → Resources → File Sharing, click the plus sign to add the directory you need to mount. Generally, /Users, /Volumes, /private, /tmp are allowed by default, but subdirectories might need to be added separately.

If it still doesn’t work, go to System Preferences → Security & Privacy → Privacy → Full Disk Access, make sure Docker Desktop is checked. macOS 14.3+ has stricter permission management—don’t skip this step.

Another pit: if you’re mounting an external hard drive or network share, you might need to configure it separately in Docker settings. External drive paths are usually under /Volumes—remember to add them.

Linux Platform Issues

Installing Docker on Linux is theoretically the simplest—after all, Docker was designed for Linux. But in reality, there are plenty of pits, especially around permissions and dependencies.

Issue 1: Permission Denied (Most Frequent)

Almost every Linux beginner encounters this. After installing Docker, you excitedly run docker ps, then:

docker: Got permission denied while trying to connect to the Docker daemon socket
at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/...":
dial unix /var/run/docker.sock: connect: permission denied.

Looking at this long string of red text, it’s easy to lose your cool. The root cause is that Docker daemon runs as root, and your current user doesn’t have permission to access /var/run/docker.sock socket file.

How to fix it:

Add your user to the docker group. Run this command:

sudo usermod -aG docker $USER

This command means adding the current user ($USER) to the docker group (-aG docker). But note—this isn’t done yet.

Group modifications don’t take effect immediately. You need to re-login or refresh the user group:

newgrp docker

Or directly logout and login again. Many people get stuck here—they modify the group but don’t re-login, then continue to get errors and think the method doesn’t work.

Verify if it took effect:

groups

If the output includes the word docker, you’re good. Try running docker ps again—it shouldn’t error.

However, there’s a security concern here. Adding a user to the docker group essentially gives that user root privileges—docker can access the entire filesystem. It’s fine for personal development machines, but be cautious on production servers.

If it still doesn’t work, check socket file permissions:

ls -l /var/run/docker.sock

Normally it should show srw-rw---- 1 root docker. If not, manually change it:

sudo chmod 666 /var/run/docker.sock

But this is a temporary solution—it will reset after restart. The correct approach is still adding to the user group.

Issue 2: Missing Dependencies (Ubuntu/Debian Systems)

This error usually appears during installation:

docker-desktop : Depends: docker-ce-cli but it is not installable
The following packages have unmet dependencies:
 docker-desktop : Depends: pass but it is not installable
                  Depends: uidmap but it is not installable
                  Depends: gnome-terminal but it is not installable

It looks like a bunch of things are missing, but the root cause is you haven’t added Docker’s official repository. The system’s default apt sources don’t have Docker, or the version is too old.

How to fix it (Ubuntu example):

First uninstall old versions (if any):

sudo apt-get remove docker docker-engine docker.io containerd runc

Then set up Docker’s official repository. This step is crucial—many tutorials skip it or write it too briefly:

# Update apt package index
sudo apt-get update

# Install necessary dependencies
sudo apt-get install ca-certificates curl gnupg lsb-release

# Add Docker official GPG key
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

# Set up Docker repository
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Note the last line—$(lsb_release -cs) will automatically detect your Ubuntu version codename (like jammy, focal). If you’re using Linux Mint, there might be a pit here—Mint is based on Ubuntu but has different version numbers. Check the /etc/os-release file and use the UBUNTU_CODENAME value, not Mint’s own version number.

After adding the repository, update and install:

sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

This time it will download from Docker’s official source and all dependencies will be resolved. After installation, run docker --version to check.

Issue 3: Daemon Startup Failure

After installing Docker, running commands prompts:

Cannot connect to the Docker daemon at unix:///var/run/docker.sock.
Is the docker daemon running?

This is similar to Mac’s issue, but on Linux the daemon is managed through systemd, so troubleshooting is different.

How to fix it:

First check Docker service status:

sudo systemctl status docker

If it shows inactive (dead) or failed, the service didn’t start or failed to start. Try starting manually:

sudo systemctl start docker
sudo systemctl enable docker  # Set to start on boot

If startup fails, look at detailed logs:

sudo journalctl -u docker.service -n 50

This will show the last 50 log lines, usually revealing the specific error cause.

Common sub-issues:

SELinux Conflicts (CentOS/RHEL systems):
If logs mention SELinux-related errors, try temporarily disabling it:

sudo setenforce Permissive

This is temporary—it will revert after restart. To permanently disable, edit /etc/selinux/config, but it’s not recommended for production environments to disable SELinux—better to configure policies.

Config File Syntax Errors:
If you’ve modified /etc/docker/daemon.json, check if the JSON syntax is correct. Missing a comma or extra quote will cause startup failure. Use jsonlint or an online tool to validate it.

Firewall Blocking:
Some Linux distributions have strict firewall rules that might block Docker. Temporarily disable firewall for testing:

sudo systemctl stop firewalld  # CentOS/RHEL
sudo ufw disable              # Ubuntu

If it can start after disabling firewall, it’s a firewall issue—you need to configure rules to allow Docker.

Issue 4: Port Conflicts

This is relatively rare, but quite annoying when encountered:

Error starting daemon: error initializing graphdriver: driver not supported
bind: address already in use

Usually Docker’s default ports (2375 or 2376) are occupied by other programs, or port conflicts when trying to configure remote access.

How to fix it:

Check port usage:

sudo netstat -tulnp | grep 2375
sudo netstat -tulnp | grep 2376

If there’s output, note the PID and kill the occupying process:

sudo kill -9 <PID>

If you need remote Docker access (not recommended—security risk), you can modify the listening port. Edit /etc/docker/daemon.json:

{
  "hosts": ["unix:///var/run/docker.sock", "tcp://127.0.0.1:2376"]
}

This only listens on local loopback address 127.0.0.1, which is relatively safe. If you want to listen on all interfaces (0.0.0.0), make sure to configure TLS encryption—don’t go naked.

After modifying config, restart Docker:

sudo systemctl daemon-reload
sudo systemctl restart docker

One pit to note: if you configure hosts in both daemon.json and systemd service file, they’ll conflict. Check /lib/systemd/system/docker.service—if the ExecStart line has -H parameter, comment it out and only configure in daemon.json.

Common Issues and Best Practices

No matter which platform you’re on, there are several common verification and configuration steps after installing Docker that can save a lot of future trouble.

Verify Installation Success

Don’t rush to start using it—first confirm Docker is really installed properly. Run these commands:

# Check Docker version
docker --version

# Check Docker Compose version (new versions integrated in Docker)
docker compose version

# Run test container (this is the official Hello World)
docker run hello-world

# View system information
docker info

docker run hello-world will download a small image and run it—if you see “Hello from Docker!” everything is normal. docker info shows storage driver, logging driver, container count and other detailed information—very useful when there are problems.

Configure Registry Mirror (Must-do for Users in China)

If you’re in China and don’t configure a registry mirror, pulling images can be slow enough to make you doubt life. Docker Hub’s official source has very unstable access in China—timeouts are common.

Edit Docker config file (Linux is /etc/docker/daemon.json, Windows/Mac in Docker Desktop settings under Docker Engine tab):

{
  "registry-mirrors": [
    "https://docker.m.daocloud.io",
    "https://registry.docker-cn.com"
  ]
}

After saving, restart Docker:

# Linux
sudo systemctl restart docker

# Mac/Windows: Right-click Docker icon → Restart

Verify if it took effect:

docker info | grep -A 5 "Registry Mirrors"

You should see your configured mirror addresses.

Note, public mirrors in China are sometimes unstable too—configure several backups. Some mirrors require account registration (like Alibaba Cloud Container Registry), but speed is indeed faster.

Limit Log Size (Prevent Disk From Being Filled)

Docker container logs have no size limit by default—long-running containers might generate tens of GB of logs, filling up the disk. I encountered this once—server disk was full, all containers crashed.

Add log configuration to daemon.json:

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}

This configuration means: each container log max 10MB, keep the last 3 files. Over 10MB will automatically rotate, old logs will be deleted.

If you need long-term log storage, recommend using ELK or Loki logging systems—don’t store locally.

Set Storage Driver

Different storage drivers have very different performance. On Linux, overlay2 is recommended—it’s currently the fastest. Most modern systems default to it, but older versions might use devicemapper or aufs, which perform much worse.

Check current storage driver:

docker info | grep "Storage Driver"

If it’s not overlay2, add this to daemon.json:

{
  "storage-driver": "overlay2"
}

Changing storage driver requires restarting Docker and will clear all container and image data—remember to back up important content first.

Several Pit-Avoidance Principles

These are lessons I learned from falling into pits:

  1. Prioritize official documentation. Docker’s official documentation (docs.docker.com) is very clear—many tutorials on search engines just copy it, and sometimes copy it wrong. When encountering problems, go to official docs first—saves time.

  2. Pay attention to tutorial dates. Docker updates quickly—many tutorials from 2020-2022 are already outdated. When reading tutorials, check publication date first, prioritize those from the last year or two.

  3. Make good use of docker info and logs. docker info shows system configuration, docker logs <container-ID> shows container output, journalctl -u docker.service (Linux) shows daemon logs. 90% of problems have clues in the logs.

  4. Don’t install Docker Desktop in VMs. Docker Desktop itself runs VMs—installing it in a VM creates nested virtualization with poor performance and weird errors. In VMs, recommend installing Docker Engine directly.

  5. Don’t run containers as root. Containers that can run as regular user shouldn’t use root. This is a security best practice—though many people use root for convenience, never do this in production.

Quick Troubleshooting Checklist

Encountering Docker problems and don’t know where to start? Check in this order—can locate 90% of common issues.

Step 1: Basic Environment Check

  • Is Docker version new enough? Run docker --version, recommend latest stable version
  • Does system version meet requirements? Windows 10 19045+/Win11 22631+, macOS 13+, Ubuntu 20.04+
  • Enough disk space? At least 10GB free, use df -h (Linux/Mac) or File Explorer (Windows) to check

Step 2: Permissions and User Group Check (Linux/Mac)

  • Is current user in docker group? Run groups, should see docker
  • Did you re-login after changing user group? Many people miss this step—use newgrp docker or directly logout and re-login
  • Are socket file permissions correct? Run ls -l /var/run/docker.sock, should show srw-rw---- 1 root docker

Step 3: Service and Process Check

  • Is Docker daemon running?
    • Linux: sudo systemctl status docker
    • Mac: Open Activity Monitor and search Docker
    • Windows: Find Docker Desktop in Task Manager
  • Any port conflicts? Run netstat -tulnp | grep docker (Linux) or lsof -i :2375 (Mac)
  • Is firewall blocking? Temporarily disable firewall for testing (sudo systemctl stop firewalld or sudo ufw disable)

Step 4: Config File Check

  • Is daemon.json syntax correct? Use JSON validation tool to check, or back it up then delete it and restart Docker to test
  • Any duplicate hosts configuration? Check both daemon.json and systemd service file—don’t configure in both places
  • Can registry mirrors be accessed? ping registry.docker-cn.com or curl https://docker.m.daocloud.io

Step 5: Check Detailed Logs

This is the most critical step—logs usually have accurate error information:

  • Linux: sudo journalctl -u docker.service -n 50
  • Mac: Log files in ~/Library/Containers/com.docker.docker/Data/log/ directory
  • Windows: Event Viewer → Application and Service Logs → Docker Desktop

If you don’t understand the logs, that’s okay—copy the complete error message and Google it, most likely someone has encountered the same problem. Remember to search in English for better results.

Step 6: Ultimate Moves (When Really Stuck)

Try these “nuclear options” in order:

  1. Reset Docker Desktop to factory settings (Docker Desktop settings → Troubleshoot → Reset to factory defaults)
  2. Completely uninstall then reinstall (remember to delete config files and cache directories)
  3. Check if blocked by antivirus software (temporarily disable antivirus to test)
  4. Try a different version (if latest doesn’t work, try a slightly older stable version)

If none of these work, post your system info, Docker version, and complete error logs to Docker’s official forum or Stack Overflow—community experts will help.

Conclusion

Installing Docker—it’s both hard and easy. Hard because each platform has its own pits: Windows wrestles with WSL 2 and virtualization, Mac puzzles over chip versions, Linux fights permissions and dependencies. Easy because these pits actually have fixed patterns—once you know the root cause, just follow the methods to fix them.

Looking back at the issues listed in this article—permission denied, daemon won’t start, missing dependencies—basically covers 80% of Docker installation error scenarios. The remaining 20% might be weird environment issues, but as long as you learn to read logs, check documentation, and Google in English, you can slowly solve them too.

Finally, here’s some advice:

After installing Docker, don’t rush to use it—first run docker run hello-world to verify. Users in China remember to configure registry mirrors, or pulling images will be slow enough to make you doubt your internet. Also recommend configuring log size limits to avoid disk filling up later and spending time finding the cause.

When encountering problems, don’t panic—go through the quick troubleshooting checklist in this article, most can be solved yourself. If really stuck, go to Docker’s official forum or Stack Overflow for help, remember to include complete error information and system version—don’t just ask “why can’t I install Docker.”

So, go try it now. If this article helped you solve your problem, share it with other friends still being tortured by Docker installation. Everyone avoids a few more pits, development efficiency improves—that’s good.

15 min read · Published on: Dec 17, 2025 · Modified on: Dec 26, 2025

Comments

Sign in with GitHub to leave a comment

Related Posts