NeuroAgent

Resolving File Access Issues Between Docker Containers

Solving file access issues between Docker containers with different UID/GID. Configuring access permissions for proper file sharing in Laravel applications.

Why can’t one Docker container access a file created by another container, and how can this be fixed?

I have two Docker containers: horizon and php-fpm. When the horizon container creates a log file (for example, laravel-2025-10-08.log) with its own permissions, the php-fpm container cannot access or write to it. How can I configure the containers for proper file sharing?

Permission examples:

  • For laravel-2025-10-08-1.log (copied): -rw-r–r-- 1 root root 1637496 Oct 8 08:59
  • For laravel-2025-10-08.log: -rw-r–r-- 1 1000 1000 49113 Oct 8 08:59

How can I ensure shared file access between containers with different users?

NeuroAgent

Main Problem with File Sharing Between Docker Containers

The main problem with file sharing between Docker containers arises from different user and group identifiers (UID/GID) under which the containers run. When one container creates a file with its access rights, another container cannot access it because its user doesn’t have the necessary read or write permissions.

Table of Contents


Main Permission Issue in Docker

When two Docker containers access the same shared folder (volume), they create files under their own users. This leads to a situation where one container can create a file, while another gets a “Permission denied” error when trying to access it.

Why this happens:

  • Different UID/GID: Each container has its default user with a unique user identifier (UID) and group identifier (GID)
  • Different access rights: Files are created with rights corresponding to the container’s user
  • Incompatibility: A user from one container doesn’t have rights to files created by a user from another container

Example from your case:

  • The file laravel-2025-10-08-1.log was created by the root user (UID 0, GID 0)
  • The file laravel-2025-10-08.log was created by a user with UID 1000, GID 1000
  • The php-fpm container, running under a different user, cannot access these files

Solution through UID/GID Mapping

The most reliable way to solve the problem is to ensure that both containers use the same UID/GID for accessing shared files.

Step 1: Determine UID/GID on the host system

First, determine your UID and primary group ID on the host system:

bash
id -u  # Shows your current UID
id -g  # Shows GID of your primary group

Step 2: Configure containers with the same UID/GID

Modify your Dockerfiles for both containers (horizon and php-fpm) to use the same UID/GID:

dockerfile
# In Dockerfile for horizon
RUN groupadd -g 1000 laravel && \
    useradd -u 1000 -g laravel -s /bin/sh -m laravel
USER laravel

# In Dockerfile for php-fpm  
RUN groupadd -g 1000 laravel && \
    useradd -u 1000 -g laravel -s /bin/sh -m laravel
USER laravel

Step 3: Verify access rights

After configuring both containers with the same UID/GID, files created in one container will be accessible in the other:

bash
# Check access rights in the container
ls -la /path/to/shared/files

Dockerfile Setup for Shared User

For Laravel applications with php-fpm and horizon, it’s recommended to create a shared user in the Dockerfile.

Example Dockerfile for php-fpm:

dockerfile
FROM php:8.2-fpm

# Install dependencies
RUN apt-get update && apt-get install -y \
    git \
    curl \
    libpng-dev \
    libonig-dev \
    libxml2-dev \
    zip \
    unzip

# Install PHP extensions
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath

# Create user with specified UID/GID
RUN groupadd -g 1000 laravel && \
    useradd -u 1000 -g laravel -s /bin/sh -m laravel

# Set correct permissions for /var/www
RUN chown -R laravel:laravel /var/www && \
    chmod -R 755 /var/www

USER laravel

WORKDIR /var/www

Example Dockerfile for horizon:

dockerfile
FROM php:8.2-cli

# Install dependencies
RUN apt-get update && apt-get install -y \
    git \
    curl \
    libpng-dev \
    libonig-dev \
    libxml2-dev \
    zip \
    unzip

# Install PHP extensions
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath

# Create the same user
RUN groupadd -g 1000 laravel && \
    useradd -u 1000 -g laravel -s /bin/sh -m laravel

# Set correct permissions for /var/www
RUN chown -R laravel:laravel /var/www && \
    chmod -R 755 /var/www

USER laravel

WORKDIR /var/www

docker-compose.yml Configuration

In the docker-compose.yml file, you can specify the user for each service:

yaml
version: '3.8'

services:
  php-fpm:
    build:
      context: .
      dockerfile: docker/php/Dockerfile
    container_name: app-php
    user: '1000:1000'  # Specify UID/GID
    volumes:
      - ./:/var/www
    networks:
      - app-network

  horizon:
    build:
      context: .
      dockerfile: docker/horizon/Dockerfile
    container_name: app-horizon
    user: '1000:1000'  # Same UID/GID
    volumes:
      - ./:/var/www
    depends_on:
      - php-fpm
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

Important: Make sure the UID/GID in docker-compose.yml match those you used in the Dockerfile and on the host system.


Automating Permission Fixes

If you don’t want to change the UID/GID of containers, you can use scripts to fix access permissions.

Script for fixing permissions:

bash
#!/bin/bash
# fix-permissions.sh

# Path to shared directory
PROJECT_DIR="."

# UID and GID of your user on the host
HOST_UID=$(id -u)
HOST_GID=$(id -g)

# Set correct permissions
sudo chown -R ${HOST_UID}:${HOST_GID} ${PROJECT_DIR}
sudo find ${PROJECT_DIR} -type d -exec chmod 755 {} \;
sudo find ${PROJECT_DIR} -type f -exec chmod 644 {} \;

# Apply permissions to storage and bootstrap/cache
sudo chmod -R 775 ${PROJECT_DIR}/storage
sudo chmod -R 775 ${PROJECT_DIR}/bootstrap/cache

Usage in docker-compose.yml:

yaml
services:
  php-fpm:
    # ... other settings
    volumes:
      - ./:/var/www
    # Run permission fix script on startup
    entrypoint: ["./fix-permissions.sh"]
    command: ["php-fpm"]

Practical Examples for Laravel

Example configuration for Laravel with php-fpm:

yaml
services:
  php-fpm:
    image: php:8.2-fpm
    container_name: app-php
    user: 'www-data:www-data'  # Standard php-fpm user
    volumes:
      - ./:/var/www
    working_dir: /var/www
    environment:
      - APP_ENV=local
    entrypoint: ["/bin/sh", "-c", "chown -R www-data:www-data /var/www/storage && exec docker-php-entrypoint php-fpm"]

Example configuration for Horizon:

yaml
services:
  horizon:
    build:
      context: .
      dockerfile: docker/horizon/Dockerfile
    container_name: app-horizon
    user: 'www-data:www-data'  # Same user
    volumes:
      - ./:/var/www
    working_dir: /var/www
    command: ["php", "artisan", "horizon"]
    depends_on:
      - php-fpm

Using variables for UID/GID:

yaml
services:
  php-fpm:
    user: "${UID}:${GID}"
    environment:
      - UID=${UID}
      - GID=${GID}

Best Practices

1. Use the same UID/GID for all containers

This is the most reliable way to avoid permission issues:

dockerfile
# In both Dockerfiles
RUN groupadd -g 1000 appuser && \
    useradd -u 1000 -g appuser -s /bin/sh -m appuser
USER appuser

2. Use .env file for managing UID/GID

Create a .env file in the project root:

UID=1000
GID=1000

And use it in docker-compose.yml:

yaml
services:
  php-fpm:
    user: "${UID}:${GID}"

3. Configure correct permissions for Laravel

Make sure the storage and bootstrap/cache directories have the correct permissions:

bash
chmod -R 775 storage
chmod -R 775 bootstrap/cache

4. Use volume with correct options

In docker-compose.yml, you can specify the access mode for the volume:

yaml
volumes:
  - ./:/var/www:rw,cached

5. Regularly check access permissions

Add permission checking to your development process:

bash
# Check script
find . -type f -not -user ${UID} -exec echo "File {} has wrong owner" \;
find . -type d -not -group ${GID} -exec echo "Directory {} has wrong group" \;

Conclusion

The problem of sharing files between Docker containers can be solved in several ways:

  1. Main solution - mapping UID/GID between containers and the host system
  2. Dockerfile configuration - creating a shared user for both containers
  3. docker-compose.yml configuration - specifying the same users for services
  4. Automating permission fixes - using scripts to set the correct access permissions

For your specific situation with horizon and php-fpm containers in a Laravel application, we recommend:

  • Create a user with the same UID/GID (e.g., 1000:1000) in both Dockerfiles
  • Specify this user in docker-compose.yml for both services
  • Ensure that the storage and bootstrap/cache directories have permissions 775
  • Use environment variables to manage UID/GID in different environments

These measures will ensure proper file sharing between containers and prevent “Permission denied” errors.

Sources

  1. Avoiding Permission Issues With Docker-Created Files
  2. Permission denied on accessing host directory in Docker - Stack Overflow
  3. What is the (best) way to manage permissions for Docker shared volumes? - Stack Overflow
  4. Fixing permissions issues with Docker Compose and PHP
  5. Understanding file permissions - Docker PHP - Server Side Up
  6. Solve Permission Denied error while using a dockerized PHP environment
  7. File permissions when developing with Docker - Nicholas Tsim