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
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.