Guides

How to Fix the Permission Denied Error in Docker

fix the permission denied error in Docker

Introduction

Docker has become the de facto standard for containerizing applications, enabling developers to build, ship, and run software quickly across various environments. However, one of the most common issues users encounter is the infamous “permission denied” error. Whether you’re running Docker commands on the host machine, building images, or executing operations inside a container, file permissions and user privileges can sometimes block you from moving forward.

In this comprehensive guide, we will explore why the permission denied error occurs in Docker, how Linux file permissions and Docker’s security model interact, and walk through multiple solutions to fix these errors. We will also cover advanced topics such as SELinux and AppArmor contexts, best practices for volume mounts, and how to manage user privileges both on the host and inside containers.

Understanding Linux File Permissions and Docker

To grasp why permission denied errors happen in Docker, it’s essential to have a basic understanding of Linux file permissions. In Linux, every file and directory has three categories of permissions: owner, group, and others. For each category, three types of permissions exist: read (r), write (w), and execute (x).

When you run a Docker container, files and directories on your host are accessed by processes that may run as different UIDs (user IDs) or GIDs (group IDs). If the Docker daemon or the process inside the container tries to access a file it doesn’t have permission for, you’ll see a permission denied error. Furthermore, Docker employs additional security mechanisms like namespaces, capabilities, and mandatory access control (e.g., AppArmor or SELinux), all of which can influence file access.

Basic Permission Bits

  • Read (r): Allows viewing file contents or listing directory contents.
  • Write (w): Allows modifying file contents or creating/deleting files in a directory.
  • Execute (x): Allows executing a file or traversing a directory.

You can check permissions with ls -l, which outputs something like:

-rwxr-xr-- 1 alice developers 4096 Jun  1 10:00 script.sh

In this example, owner is alice, group is developers, and others have read-only access. If a process runs as a user outside of this scope, it won’t be able to write or execute the file.

Common Causes of Permission Denied in Docker

Before diving into specific solutions, let’s enumerate the most frequent reasons Docker users see a permission denied error:

  1. Docker CLI Invocation without Sudo: Running docker commands as a non-root user who is not in the docker group.
  2. Incorrect Ownership of Files on Host: Mounting host directories or files into the container that are owned by a different user or group not accessible by the container’s process.
  3. File Mode Bits: Host files or directories might not have the execute bit for scripts or the required read/write bit for data files.
  4. SELinux or AppArmor Restrictions: Security policies preventing Docker processes from reading or writing certain paths.
  5. Permissions inside Container: The user inside the container does not have correct UID/GID or capabilities to access a file/directory.
  6. Volume Mount Mismatch: Host volumes mounted with root-only permissions, causing the container process to be denied access.

In the sections below, we’ll tackle each of these causes with targeted fixes.

Fixing “Permission Denied” for Docker Commands on Host

When you install Docker on a Linux distribution, the Docker daemon (dockerd) runs as root. The Docker CLI (docker) communicates with the daemon via a UNIX socket located at /var/run/docker.sock. By default, this socket is owned by root:docker and has permission bits srw-rw----. This means only root or users in the docker group can communicate with the Docker daemon.

Symptoms

$ docker ps
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post http://%2Fvar%2Frun%2Fdocker.sock/v1.41/containers/json: dial unix /var/run/docker.sock: connect: permission denied

This indicates your current user is not in the docker group or you are missing sudo privileges.

Solution Options

1. Add Your User to the docker Group

The most common recommendation is to add your user account to the docker group. This allows you to run Docker commands without sudo.

# Create the docker group if it doesn’t exist
sudo groupadd docker

# Add your user (e.g., alice) to the docker group
sudo usermod -aG docker alice

# After this, you must log out and log back in for the group change to take effect

Once you log back in, verify membership:

$ id -nG
alice docker sudo

You should now be able to run:

$ docker run hello-world

2. Use sudo for Docker Commands

If you prefer not to manage group membership, you can prefix every Docker command with sudo:

$ sudo docker ps

Note that using sudo is straightforward but can be cumbersome over time. It’s generally cleaner to adjust group permissions.

Fixing Permission Denied When Building Docker Images

When building images using a Dockerfile, you may COPY or ADD files from your host into the image. If Docker cannot read these files due to host file permissions, the build will fail:

Step 3/10 : COPY app/script.sh /usr/local/bin/script.sh
COPY failed: stat /home/alice/project/app/script.sh: permission denied

Solutions

1. Ensure Read Permission on Host Files

Make sure the user running docker build has read access to all files in the build context:

$ chmod -R u+r project/

If multiple users or CI pipelines need access, adjust group permissions:

# Assume files belong to alice:developers
sudo chown -R alice:developers project/
sudo chmod -R g+r project/

2. Correct .dockerignore

Sometimes your context directory contains files with restrictive permissions that you don’t actually need in your image (e.g., .env or .git directories). Exclude them in .dockerignore to avoid permission issues and reduce build context size.

# .dockerignore
.env
.git
node_modules

Fixing Permission Denied for Mounted Volumes

One of Docker’s most powerful features is volume mounting. However, mismatched user IDs between host and container can cause permission denied errors when reading or writing data in a mounted directory.

$ docker run -v /home/alice/data:/data my-image
Error: EACCES: permission denied, open '/data/config.json'

Common Scenarios

  • The host directory is owned by alice:alice with mode 700, but the container process runs as root or another user.
  • The container image’s user has a different UID/GID than the host file owner.
  • SELinux/AppArmor is enforcing policies that block access to that path.

Solutions

1. Adjust Ownership on the Host

Change ownership of the host directory to match the user inside the container. If your container runs as root (UID 0) by default, you could:

$ sudo chown -R root:root /home/alice/data
$ sudo chmod -R 755 /home/alice/data

If your container runs as a non-root user, adjust accordingly. For example, if the container uses UID 1000:

$ sudo chown -R 1000:1000 /home/alice/data
$ sudo chmod -R 750 /home/alice/data

2. Use --user Flag to Match UIDs

When running the container, specify the UID and GID to match the host directory’s owner:

$ docker run --user $(id -u):$(id -g) -v /home/alice/data:/data my-image

This ensures the process inside the container runs with the same privileges as alice on the host, avoiding permission mismatches.

3. Use Named Volumes Instead of Host Mounts

If you don’t need to inspect the files on the host directly, use a named volume. Docker will manage the volume’s ownership automatically:

$ docker volume create my-data
$ docker run -v my-data:/data my-image

By default, this volume is owned by root:root inside the container. You can then change ownership within the Dockerfile or at runtime.

Fixing Permission Denied Inside the Container

Sometimes a container’s application fails due to permission issues at runtime:

Unhandled promise rejection Error: EACCES: permission denied, mkdir '/app/logs'

Common Causes

  • The Dockerfile creates files or directories owned by root, but the application runs as a non-root user.
  • Scripts lack execute permissions (chmod +x).
  • Applications attempt to write to protected system paths.

Solutions

1. Explicitly Set Ownership in Dockerfile

In your Dockerfile, after creating directories, set the correct owner and permissions:

FROM node:14-alpine

# Create app directory
RUN mkdir -p /usr/src/app

# Change ownership to node user
RUN chown -R node:node /usr/src/app

# Switch to non-root user
USER node

# Copy application files
WORKDIR /usr/src/app
COPY --chown=node:node package*.json ./
RUN npm install
COPY --chown=node:node . .

CMD ["npm", "start"]

By using --chown=node:node with COPY or RUN chown, you ensure files are accessible to the node user.

2. Grant Execute Permissions to Scripts

If your entrypoint or startup script lacks execute permission, the container will error out:

Step 5/7 : RUN chmod +x entrypoint.sh

Or set permissions before the build:

$ chmod +x entrypoint.sh
$ docker build -t my-image .

3. Avoid Writing to Root-Owned Directories

By default, most official images run as root. If your application tries to write to /usr or /etc without proper permissions, it will fail. Instead, create a dedicated writable directory (e.g., /data or /app) and set ownership accordingly.

SELinux and AppArmor Restrictions

Many Linux distributions (e.g., CentOS, Fedora, RHEL) enable SELinux by default, while others (e.g., Ubuntu) use AppArmor. These mandatory access control (MAC) systems can prevent Docker from mounting or accessing certain host directories, causing permission denied errors even if file permissions appear correct.

SELinux Contexts

When you mount a host directory into a Docker container, SELinux requires the correct security context (SELinux label) on that directory. The context for Docker typically needs to be z or Z.

Temporary Fix with :z or :Z

Add a :z or :Z suffix to your volume mount:

$ docker run -v /home/alice/data:/data:z my-image

:z tells Docker to share the volume content between containers (allowing multiple containers to read/write).
:Z tells Docker to give exclusive access to the container.

Permanent Fix with chcon

You can permanently set the SELinux context on the host directory:

$ sudo chcon -Rt svirt_sandbox_file_t /home/alice/data

This command recursively sets the SELinux type to svirt_sandbox_file_t, which Docker containers may access by default.

AppArmor Profiles

On Ubuntu or Debian, AppArmor profiles can restrict container access. If you encounter a permission denied error even when file permissions and SELinux contexts are correct, check the AppArmor profile applied to the container. By default, Docker uses the docker-default AppArmor profile.

Disable or Adjust AppArmor Profile

To quickly test whether AppArmor is the culprit, you can run the container with an unconfined profile:

$ docker run --security-opt apparmor=unconfined -v /home/alice/data:/data my-image

If this solves the permission denied error, consider modifying your docker-default profile to allow access to the needed paths, or create a custom profile.

Fixing “Permission Denied” When Using docker exec

Running commands inside a running container with docker exec can also trigger permission denied errors if the target file or directory doesn’t permit access to the default user (often root or a non-root application user).

$ docker exec my-container cat /var/log/app.log
cat: /var/log/app.log: Permission denied

Solutions

1. Specify --user to Match Ownership

If the file inside the container is owned by a non-root user (e.g., appuser with UID 1001), specify that user:

$ docker exec --user 1001:1001 my-container cat /var/log/app.log

2. Adjust Permissions Inside the Container

You can temporarily change permissions inside the container if you have root access:

$ docker exec -u root my-container chmod +r /var/log/app.log
$ docker exec my-container cat /var/log/app.log

If you need to automate this on container start, add a RUN chmod step in your Dockerfile or an entrypoint script.

Best Practices to Avoid Permission Denied Errors

The best way to fix permission denied errors is to proactively follow best practices when creating and running Docker images.

1. Build as Non-Root User When Possible

Running containers as root can lead to security risks. Instead, create and switch to a non-root user in your Dockerfile and ensure all necessary directories have the correct owner:

FROM python:3.9-slim

# Create a non-root user
RUN useradd --create-home appuser
USER appuser
WORKDIR /home/appuser/app
COPY --chown=appuser:appuser . .
RUN pip install --no-cache-dir -r requirements.txt
CMD ["python", "app.py"]

2. Set Proper Ownership and Permissions Early

Right after creating directories or copying files in your Dockerfile, change ownership so later steps don’t encounter permission issues:

RUN mkdir -p /data && chown -R appuser:appuser /data

3. Use docker-compose with user: and volumes: Correctly

When using docker-compose.yml, you can set the user and group for services and specify mount options for SELinux:

version: "3.8"
services:
  web:
    image: my-web-app
    user: "1001:1001"
    volumes:
      - type: bind
        source: ./data
        target: /data
        bind:
          propagation: rshared
          selinux: true

The selinux: true option appends :z to the mount, ensuring the correct SELinux context.

4. Leverage Multi-Stage Builds to Minimize Permissions Complexity

Multi-stage builds can help keep sensitive files out of final images and reduce the need for complex permission management. Build as root in an intermediate stage, then copy only necessary artifacts into a non-root final stage:

FROM golang:1.18 AS builder
WORKDIR /build
COPY . .
RUN go build -o myapp

FROM alpine:3.15
RUN apk add --no-cache ca-certificates
COPY --from=builder /build/myapp /usr/local/bin/myapp
RUN adduser -D appuser
USER appuser
CMD ["/usr/local/bin/myapp"]

Summary

Permission denied errors in Docker often stem from mismatches between file ownership, permission bits, and the user or security context under which Docker processes operate. By understanding Linux file permissions, Docker’s security model, and tools like SELinux and AppArmor, you can diagnose and resolve these errors effectively. Key takeaways:

  • Add your user to the docker group or use sudo to avoid “permission denied” for Docker CLI commands.
  • Ensure host files and directories have appropriate read/write/execute bits before building images or mounting as volumes.
  • Match UIDs/GIDs between host and container when mounting volumes, or adjust ownership using chown.
  • Grant execute permissions for scripts used during image build or container startup.
  • Account for SELinux and AppArmor policies by using :z/:Z flags or adjusting security context with chcon.
  • Build images with a non-root user whenever possible and set ownership early in the Dockerfile.
  • Leverage multi-stage builds and docker-compose user settings for cleaner, more secure images.

Following these best practices and troubleshooting steps will help you maintain a smooth, secure Docker workflow free from permission issues.

Frequently Asked Questions (20 FAQs)

1. Why do I get “permission denied” when running docker ps?

This happens because your user is not in the docker group. Either add your user to the group with sudo usermod -aG docker $USER and re-login, or run Docker commands using sudo.

2. How do I fix “COPY failed: permission denied” during docker build?

Ensure the files being copied have read permissions for the Docker build context user. Run chmod -R u+r path/to/files or adjust file ownership with chown so Docker can read them.

3. Why can’t my container write to a mounted volume?

The host directory might be owned by a different UID/GID than the one used inside the container. Use chown -R on the host to match the container user, or run Docker with --user $(id -u):$(id -g) to align UIDs.

4. What does :z suffix do when mounting volumes?

On SELinux-enabled systems, appending :z changes the security context of the mounted directory to allow multiple containers to share it. It ensures Docker can read/write the volume without SELinux blocking access.

5. How do I permanently fix SELinux context for a host directory?

Use sudo chcon -Rt svirt_sandbox_file_t /path/to/dir. This recursively sets the SELinux type to svirt_sandbox_file_t, which Docker containers can access by default.

6. My container logs say “permission denied” for a script. What should I check?

Verify the script has execute permissions (chmod +x script.sh) and that the user inside the container owns the script. In your Dockerfile, use RUN chmod +x /path/to/script.sh or COPY --chown=user:user.

7. Can I run Docker commands without sudo on Ubuntu?

Yes. Add your user to the docker group (sudo usermod -aG docker $USER), then log out and back in. You can then run Docker commands without sudo.

8. Why do I get “permission denied” inside the container when reading a file I just copied?

The file may be owned by root with restrictive permissions. Use COPY --chown=user:user in the Dockerfile or add RUN chown user:user /path/to/file to give the container’s user access.

9. How do I adjust AppArmor profile if it’s blocking container file access?

Test by disabling AppArmor (--security-opt apparmor=unconfined). If it works, create or modify a custom AppArmor profile to allow access to the required paths or keep the container unconfined if security requirements allow.

10. Is it safe to run containers as root?

Running as root inside containers can be a security risk. It’s best to create a non-root user in your Dockerfile, set appropriate ownership, and switch to that user before running your application.

11. Why does docker exec show “permission denied” on a file owned by root?

By default, docker exec runs as root. If you’re targeting a file owned by another user, specify --user UID:GID to match ownership. Alternatively, adjust file permissions inside the container with chmod.

12. My CI/CD pipeline fails with permission errors during docker build. How can I fix this?

Ensure the CI user has read permissions on all files in the build context. In your CI script, run chmod -R u+r . or adjust ownership to the CI user’s UID/GID before invoking docker build.

13. How do I avoid permission issues when copying files between Windows host and Linux container?

On Windows, use Git Bash or WSL to ensure proper UNIX permissions. After cloning your repo, run chmod +x ./script.sh before building the image. Alternatively, use git config core.fileMode false to preserve execution bits.

14. Can Docker Desktop on Mac/Windows face permission denied errors?

Yes. When mounting OS X or Windows folders, Docker Desktop uses a virtualization layer. Ensure the shared folder is enabled in Docker Desktop’s preferences and that your user has read/write permission on that directory in the host OS.

15. Why does docker-compose fail with permission denied on volume mounts?

Check that docker-compose.yml specifies correct mount options (volumes: with :z or :Z for SELinux). Ensure host directory ownership matches user: in your service definition or adjust ownership on the host.

16. How can I troubleshoot SELinux blocking container access?

Check Audit logs (/var/log/audit/audit.log) for AVC denials. If you see denied operations, use audit2allow to generate a custom policy module or apply :z on volume mounts.

17. My Docker build is slow after fixing permission issues—why?

Adding chmod or chown in a Dockerfile can increase build time. To optimize, combine file system operations in fewer layers, use multi-stage builds, and minimize the number of file permission changes.

18. Why can’t my non-root application write to /var/log inside the container?

The /var/log directory is owned by root. Create a dedicated logs directory in your Dockerfile:

RUN mkdir -p /app/logs && chown -R appuser:appuser /app/logs

Then point your application to write logs there instead.

19. Will changing file permissions on the host affect other applications?

Yes. Changing ownership or permissions on a shared directory can impact other services relying on those files. Limit changes to project-specific folders or use group-based permissions to isolate impacts.

20. How do I prevent future permission denied issues in Docker?

Follow these best practices:

  • Use non-root users in Dockerfiles.
  • Set file ownership and permissions explicitly during build.
  • Align UIDs/GIDs for volume mounts.
  • Use named volumes for data persistence when possible.
  • Account for SELinux/AppArmor early by using :z/:Z or adjusting security contexts.