docker-composedockerfilecomposer-phpdocker-container

Automatically running "composer install" after container is built


setting up a web development stack with NGinX, PHP and composer. My docker file looks like this:

FROM php:fpm

# Install dependencies and PHP extensions
RUN apt-get update && apt-get upgrade -y && \
    apt-get install -y libzip-dev zip nano && \

    docker-php-ext-install pdo pdo_mysql && \
    pecl install xdebug && docker-php-ext-enable xdebug && \
    apt-get install -y libfreetype6-dev libjpeg62-turbo-dev libpng-dev && \
    docker-php-ext-configure gd --with-freetype --with-jpeg && \
    docker-php-ext-install -j$(nproc) gd && \
    docker-php-ext-install zip

# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*

# Install Composer
COPY --from=composer/composer:latest-bin /composer /usr/bin/composer

# Set the COMPOSER_ALLOW_SUPERUSER environment variable
ENV COMPOSER_ALLOW_SUPERUSER 1

# Copy the code into the container
COPY . /app

# Set the working directory to /app
WORKDIR /app/

# Install PHPMailer
RUN composer require phpmailer/phpmailer

# Run composer Install
RUN composer install --no-interaction
RUN composer dump-autoload

my compose.yml looks like this:

version: '3.8'

services:
    NGinX:
        image: nginx:latest
        container_name: NGinX
        hostname: NGinX
        security_opt:
            - no-new-privileges:true
        ports:
            - 80:80/tcp
            - 443:443/tcp
        dns:
            - 8.8.8.8
            - 1.1.1.1
        environment:
            - PUID=1000
            - PGID=100
            - TZ=Europe/London
            - UMASK=022
        volumes:
            - /volume1/docker/WebDev/NGinX/nginx.conf:/etc/nginx/conf.d/nginx.conf
            -  /volume1/docker/WebDev/WWW:/app
        restart: unless-stopped

        depends_on:
            - php


    php:
        build:
            context: .
            dockerfile: PHP.dockerfile
#        image: php:fpm
        container_name: PHP
        hostname: PHP
        security_opt:
            - no-new-privileges:true
        environment:
            - PUID=1000
            - PGID=100
            - TZ=Europe/London
            - UMASK=022
        volumes:
            - /volume1/docker/WebDev/WWW:/app
            - /volume1/docker/WebDev/WWW:/app/vendor
            - /volume1/docker/WebDev/PHP/local-php.ini:/usr/local/etc/php/conf.d/local.ini
        # Run composer install command  here instead of in the dockerfile to avoid volume  mounting overwriting the  vendor folder
        command: composer install --no-interaction

If I "run composer install" from the docker file, the container is created with no errors but when the compose.yml file mounts the volumes it overwrites the vendor folder

If I comment out the "run composer install" in the dockerfile and use "command: composer install" to my compose.yml file. The vendor folder and autoload and composer lock files are created. However the PHP container exits as soon as the build has finished. I've also read online that I can also leave the "run composer install" in the dockerfile and instead in the compose.yml file add command: "php -S 0.0.0.0:80 /app/index.php" not sure if I've got the command completely right but this doesn't work either no vendor folder or autoload file is generated. Can anyone suggest how to automatically run composer install after the volumes have been mounted so the vendor folder is not overwritten? Thanks


Solution

  • Use a composer script to install the dependencies and serve your application afterwards.

    In your composer.json under the scripts key add something like this:

    {
      "scripts": {
        "serve": [
          "@putenv COMPOSER_ALLOW_SUPERUSER=1",
          "Composer\\Config::disableProcessTimeout",
          "@composer install --no-interaction",
          "@php -S 0.0.0.0:80 /app/index.php"
        ]
      }
    }
    

    Then use the script as your command in docker-compose.yml as follows:

    services:
      php:
        # Run the composer "serve" script
        command: composer run-script serve
    

    Warning

    Your php.Dockerfile and compose configuration both run PHP commands during build and the container itself as user root.

    Please note that this is a security risk.