skip to Main Content

I am not a really experienced user on Docker, and I am faced with a weird issue I cannot solve.

What I try to do, is to run three services using a docker-compose.yml. The three services are a MySQL Server, a PHP-FPM and an nGinx server.

So far, I have achieve to run the services, and I can do all the operation I want, like running the migration files inside the container, add fixtures data in the database, etc.

The only problem I have using the following configuration is that the changes I do on my host machine files, it is not reflected in the running containers.

If I stop the docker-compose, and restart it, then I can see my host machine changes, but I cannot see the changes while the containers are running.

In the following files, do you see any errors in my configuration? I have searched a lot, but unfortunately, I cannot find any solution.

My docker-compose.yml file looks like that:

version: "3.9"

services:
    mysql:
        image: mysql:8.0
        volumes:
            - ./docker/mysql/init:/docker-entrypoint-initdb.d
            - .data:/var/lib/mysql
        environment:
            MYSQL_ROOT_PASSWORD: root
            MYSQL_DATABASE: api

    php:
        build:
            context: .
        env_file:
            - .env
        ports:
            - "9000:9000"
        volumes:
            - ./:/srv/api

    web:
        image: nginx:latest
        ports:
            - "8080:80"
        volumes:
            - ./:/srv/api
            - ./docker/nginx/site.conf:/etc/nginx/conf.d/default.conf

For the PHP the Dockerfile is the following:

# the different stages of this Dockerfile are meant to be built into separate images
# https://docs.docker.com/develop/develop-images/multistage-build/#stop-at-a-specific-build-stage
# https://docs.docker.com/compose/compose-file/#target


# https://docs.docker.com/engine/reference/builder/#understand-how-arg-and-from-interact
ARG PHP_VERSION=8.0.9

# "php" stage
FROM php:${PHP_VERSION}-fpm-alpine AS api_platform_php

# persistent / runtime deps
RUN apk add --no-cache 
        acl 
        fcgi 
        file 
        gettext 
        git 
        gnu-libiconv 
    ;

# install gnu-libiconv and set LD_PRELOAD env to make iconv work fully on Alpine image.
# see https://github.com/docker-library/php/issues/240#issuecomment-763112749
ENV LD_PRELOAD /usr/lib/preloadable_libiconv.so

ARG APCU_VERSION=5.1.19
RUN set -eux; 
    apk add --no-cache --virtual .build-deps 
        $PHPIZE_DEPS 
        icu-dev 
        libzip-dev 
        mysql-dev 
        zlib-dev 
    ; 
    
    docker-php-ext-configure zip; 
    docker-php-ext-install pdo pdo_mysql; 
    docker-php-ext-install -j$(nproc) 
        intl 
        zip 
    ; 
    pecl install 
        apcu-${APCU_VERSION} 
    ; 
    pecl clear-cache; 
    docker-php-ext-enable 
        apcu 
        opcache 
    ; 
    
    runDeps="$( 
        scanelf --needed --nobanner --format '%n#p' --recursive /usr/local/lib/php/extensions 
            | tr ',' 'n' 
            | sort -u 
            | awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' 
    )"; 
    apk add --no-cache --virtual .api-phpexts-rundeps $runDeps; 
    
    apk del .build-deps

###> recipes ###
###< recipes ###

COPY --from=composer:2 /usr/bin/composer /usr/bin/composer

RUN ln -s $PHP_INI_DIR/php.ini-production $PHP_INI_DIR/php.ini
COPY docker/php/conf.d/api-platform.prod.ini $PHP_INI_DIR/conf.d/api-platform.ini

VOLUME /var/run/php

# https://getcomposer.org/doc/03-cli.md#composer-allow-superuser
ENV COMPOSER_ALLOW_SUPERUSER=1
ENV PATH="${PATH}:/root/.composer/vendor/bin"

WORKDIR /srv/api

# build for production
ARG APP_ENV=prod

# prevent the reinstallation of vendors at every changes in the source code
COPY composer.json composer.lock symfony.lock ./
RUN set -eux; 
    composer install --prefer-dist --no-dev --no-scripts --no-progress; 
    composer clear-cache

# copy only specifically what we need
COPY .env ./
ADD bin bin/
COPY config config/
COPY migrations migrations/
COPY public public/
COPY src src/
COPY templates templates/
COPY ./ ./


COPY docker/php/docker-healthcheck.sh /usr/local/bin/docker-healthcheck
RUN chmod +x /usr/local/bin/docker-healthcheck

HEALTHCHECK --interval=10s --timeout=3s --retries=3 CMD ["docker-healthcheck"]

COPY docker/php/docker-entrypoint.sh /usr/local/bin/docker-entrypoint
RUN chmod +x /usr/local/bin/docker-entrypoint

ENV SYMFONY_PHPUNIT_VERSION=9

CMD ["php-fpm"]

WORKDIR /srv/api

EXPOSE 9000

and finally my local file system is like that:

/bin
/config
/docker
    /mysql
        /init
            init-script.sql
    /nginx
        site.conf
    /php
        /conf.d
            api-platform.dev.ini
            api-platform.prod.ini
        /php-fpm.d
            zz-docker.conf
        docker-entrypoint.sh
        docker-healthcheck.sh
/migrations
/public
    /bundles
    [...]
    index.php
    [...]
/src
    /Controller
    /DataFixtures
    /Entity
    /EventSubscriber
    /Exception
    /OpenApi
    /Repository
    /Security
    /Serializer
    /Validation
    Kernel.php
/templates
/tests
/var
/vendor
.env
[...]
docker-compose.yml
Dockerfile
[...]

2

Answers


  1. It should have nothing to do with your Dockerfile.

    Perhaps for some reason your mounts default to :delegated mode.

    Try adding :consistent to your volume specification, as in:

    - ./docker/nginx/site.conf:/etc/nginx/conf.d/default.conf:consistent
    

    From the docs:

    • consistent: perfect consistency (host and container have an identical view of the mount at all times)
    • cached: the host’s view is authoritative (permit delays before updates on the host appear in the container)
    • delegated: the container’s view is authoritative (permit delays before updates on the container appear in the host)

    EDIT:
    Check out this (long) thread: https://github.com/docker/for-win/issues/5530 (it has started as a Windows issue, but Ubuntu users report the same issue in the thread).

    It has a lot of things in common with your issue, including PHP and more than one container using the same host folder as a volume. It seems a bug related to very frequent file updates and the caching system. For some, adding :consistent worked, for some not. The bug report is now closed – it seems fixed, even tough I do not see a very obvious explanation at the end. I do recommend to make sure your Docker / docker-compose deployment is up to date.

    Login or Signup to reply.
  2. I had similar issues on my Mac – and this turned out to be related to the option in Docker Desktop which was enabled to "Use gRPC FUSE for file sharing". Once I disabled this option I was able to add and edit files on the host and see the updates reflected in the container without having to stop and start the containers.

    Docker Preferences

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search