Docker

Docker and the host filesystem owner matching problem

On the desktop, containers are now employed on servers and in CLI apps or development environments, indicating a growing trend. Containerized apps frequently create files your local machine’s user account does not own. After that, you can not access files on the host machine. The main problem is mismatching filesystem owners.

There are two primary strategies to solve the host filesystem owner matching problem:

  1. Matching the container’s UID/GID with the host’s UID/GID.
  2. Remounting the host path in the container using BindFS.

Today, we will look at the first strategy, “matching the container’s UID/GID with the host’s UID/GID.

Here we have a simple example of PHP 8.3 apache container example:

Dockerfile example

FROM php:8.3-apache

ENV TZ=Europe/Vilnius
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

RUN apt update \
        && apt install -y \
            g++ \
            libicu-dev \
            libpq-dev \
            libzip-dev \
            zip \
            zlib1g-dev \
            cron \
            nano \
        && docker-php-ext-install \
            intl \
            opcache \
            pdo \
            sockets \
            pdo_mysql;

RUN mv /etc/apache2/apache2.conf /etc/apache2/apache2.conf.dist
COPY docker/apache.conf /etc/apache2/apache2.conf

ENV PHP_INI_DIR /usr/local/etc/php
COPY docker/local/php.ini $PHP_INI_DIR/php.ini
RUN mkdir -p $PHP_INI_DIR/conf.d

COPY docker/apache2-foreground /usr/local/bin/

RUN chmod +x /usr/local/bin/apache2-foreground

RUN	mkdir -p /var/www/storage/logs && touch /var/www/storage/logs/laravel.log
RUN chmod -R 0755 /var/www/storage

WORKDIR /var/www

RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

docker-compose.yaml example

version: '3.0'
services:
  docker-test:
    container_name: docker-test
    build:
      context: .
      dockerfile: docker/local/Dockerfile
    networks:
      - docker-test
    ports:
      - '8080:80'
    volumes:
      - ./:/var/www
networks:
  docker-test: {}

Step 1. Identify your host machine UID/GID

For validation, you can use the id command to check the user and group IDs before and after the modification.

id d4d

Your host machine will output something like this one.

uid=1001(d4d) gid=1001(d4d) groups=1001(d4d),100(users),994(docker)

Step 2. Identify your docker container UID/GID.

id www-data

Your docker container will output something like this one.

uid=33(www-data) gid=33(www-data) groups=33(www-data)

Step 3. Change the group ID for an existing group.

To change the group ID for an existing group in a Unix-like system, you can use the groupmod command. Here’s an example.

groupmod -g 1001 www-data

Step 4. Change the user ID and group ID of an existing user.

To change the user ID and group ID of an existing user in a Unix-like system, you can use the usermod command. Here’s an example:

usermod -u 1001 -g 1001 www-data

Following this, you’ll be able to effectively utilize Docker with the standard www-data inside the container, while maintaining a separate d4d user outside the container.

docker exec -u www-data -ti docker-test bash

Sources:

1. https://www.joyfulbikeshedding.com/blog/2021-03-15-docker-and-the-host-filesystem-owner-matching-problem.html