Docker - Create new files as www-data and not root

Rooneyl picture Rooneyl · Sep 5, 2017 · Viewed 18.7k times · Source

I have a basic docker container which I build using docker-compose (version 3) to bring up a basic LAMP stack.
The issue I am having is that files created inside the docker container are always owned by root, so I am unable to edit them locally.
I have tried setting the container www-data user to have the same uid as my local user, which works, but new files are still created by root.
How do I create file in the container that I can edit locally?

My compose file;

version: "3"

services:
    webserver:
        build: 
            context: ./docker/containers/webserver
        container_name: 'apache7.1-webserver'
        restart: 'always'
        ports:
            - "80:80"
            - "443:443"
        links: 
            - mysql
        volumes: 
            - ${DOCUMENT_ROOT}:/var/www/html
            - ${PHP_INI}:/usr/local/etc/php/php.ini
            - ${VHOSTS_DIR}:/etc/apache2/sites-enabled
            - ${APACHE_LOG_DIR}:/var/log/apache2
    mysql:
        build: ./docker/containers/mysql
        container_name: 'apache7.1-mysql'
        restart: 'always'
        ports:
            - "3306:3306"
        volumes: 
            - ${MYSQL_DATA_DIR}:/var/lib/mysql
            - ${MYSQL_LOG_DIR}:/var/log/mysql
        environment:
            MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
            MYSQL_DATABASE: ${MYSQL_DATABASE}
            MYSQL_USER: ${MYSQL_USER}
            MYSQL_PASSWORD: ${MYSQL_PASSWORD}
    redis:
        container_name: 'apache7.1-redis'
        image: redis:latest
        ports:
            - "6379:6379"

My webserver Dockerfile;

FROM php:7.1-apache

# Get any build argument overrides
ARG APP_UID
ARG APP_GID

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

RUN apt-get clean -y \
    && apt-get update -y \
    && apt-get install -y \
        g++ \
        locales \
        libxml2-dev \
        php-soap \
        zlib1g-dev \
        libicu-dev \
        libfreetype6-dev \
        libjpeg62-turbo-dev \
        libpng12-dev \
        libmcrypt-dev \
        libpng12-dev \
        libcurl4-openssl-dev \
        libxml2-dev \
        nano \
    && apt-get clean -y

RUN docker-php-ext-install mysqli mbstring zip intl mcrypt curl json
RUN docker-php-ext-install iconv xml xmlrpc 

RUN docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
    && docker-php-ext-install -j$(nproc) gd

# Add any required locales here and restart php-fpm, note that some locales do not include currencies such as EURO, if
# this is the case then they will need to be generated in addition to main locale
RUN sed -i -e 's/# en_GB.UTF-8 UTF-8/en_GB.UTF-8 UTF-8/' /etc/locale.gen \
    && sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen \
    && sed -i -e 's/# pt_BR.UTF-8 UTF-8/pt_BR.UTF-8 UTF-8/' /etc/locale.gen \
    && sed -i -e 's/# de_AT.UTF-8 UTF-8/de_AT.UTF-8 UTF-8/' /etc/locale.gen \
    && sed -i -e 's/# de_AT@euro ISO-8859-15/de_AT@euro ISO-8859-15/' /etc/locale.gen \
    && sed -i -e 's/# de_DE.UTF-8 UTF-8/de_DE.UTF-8 UTF-8/' /etc/locale.gen \
    && sed -i -e 's/# fr_FR.UTF-8 UTF-8/fr_FR.UTF-8 UTF-8/' /etc/locale.gen \
    && dpkg-reconfigure --frontend=noninteractive locales \
    && kill -USR2 1

RUN pecl install redis-3.1.2 \
    && pecl install xdebug-2.5.0 \
    && docker-php-ext-enable redis xdebug

# Enable apache modules
RUN a2enmod rewrite headers

# Change www-data user to match the host system UID and GID and chown www directory
RUN usermod --non-unique --uid 1000 www-data \
  && groupmod --non-unique --gid 1000 www-data \
  && chown -R www-data:www-data /var/www

Answer

Chris Stryczynski picture Chris Stryczynski · Sep 5, 2017

You can set the user with the USER directive https://docs.docker.com/engine/reference/builder/#user.

So you would need to for example add USER 1000 or USER www-data in the Dockerfile.