Issue
I'm trying to create a php-apache container with npm and composer installed and run composer install, npm install in every build, but I'm getting errors.
# Dockerfile
FROM php:7.4-apache
RUN apt-get -y update && apt-get upgrade -y
RUN apt-get update && apt-get install -y \
libfreetype6-dev \
libjpeg62-turbo-dev \
libpng-dev \
npm \
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install -j$(nproc) gd
# Composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
# Enable apache modules
RUN a2enmod rewrite headers
EXPOSE 80
#RUN composer install
#RUN npm install
ENTRYPOINT ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]
# docker-compose.yml
version: "3"
services:
painel-admin:
build:
context: ./bin/painel-admin
container_name: 'painel-admin'
command: >
sh -c "php /usr/local/bin/composer install"
restart: 'always'
ports:
- "81:80"
- "82:443"
volumes:
- ${DOCUMENT_ROOT-..}:/var/www/html
- ${PHP_INI-./config/php/php.ini}:/usr/local/etc/php/php.ini
- ${VHOSTS_DIR-./config/vhosts}:/etc/apache2/sites-enabled
- ${LOG_DIR-./logs/apache2}:/var/log/apache2
log error:
Action '-D FOREGROUND sh -c php /usr/local/bin/composer install' failed.
Same error if I try with npm install.
I can run the commands inside the docker, but I want to automate that
Solution
I think you are following you an incorrect approach. Those commands are part of the image building process, so they should be part of your Dockerfile.
And build process happens before volumes are available (the container is not running, so it's not possible to depend on those). What you need to do is copy the necessary files to the image you are building before you run composer install.
A more sensible approach, taking advantage of multi-stage build dockerfiles would be:
## First stage. Copy project files and run composer
FROM composer:2 as composer_stage
RUN rm -rf /var/www && mkdir -p /var/www/html
WORKDIR /var/www/html
COPY composer.json composer.lock symfony.lock .env ./
COPY public public/
RUN composer install --ignore-platform-reqs --prefer-dist --no-scripts --no-progress --no-suggest --no-interaction --no-dev --no-autoloader
RUN composer dump-autoload --optimize --apcu --no-dev
COPY bin bin/
COPY config config/
COPY src src/
RUN composer run-script $NODEV post-install-cmd; \
chmod +x bin/console;
## Second stage. Build NPM dependencies
FROM node:12 as npm_builder
COPY --from=composer_stage /var/www/html /var/www/html
WORKDIR /var/www/html
COPY yarn.lock package.json webpack.config.js ./
COPY assets ./assets
RUN yarn install
RUN yarn encore prod
# I'm using yarn here, but using npm would be similar, depending on how your project is setup
# RUN npm install
# RUN npm run build # if necessary and the command exists in your project
## Third stage, mostly copied from your original Dockerfile
FROM php:7.4-apache
RUN apt-get -y update && apt-get upgrade -y
COPY --from=npm_builder /var/www/html /var/www/html
RUN apt-get update && apt-get install -y \
libfreetype6-dev \
libjpeg62-turbo-dev \
libpng-dev \
npm \
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install -j$(nproc) gd
# Enable apache modules
RUN a2enmod rewrite headers
EXPOSE 80
ENTRYPOINT ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]
This way, your final resulting image does not include any of the development dependencies. The image is thought mostly for production, so you can build it and deploy it.
To run it locally during development, you just run the same image locally with your desired volume mount-points. You would only need to rebuild the image whenever your dependencies change or are upgraded.
You'll need to adjust the paths so it matches your desired configuration (I'm building the project on /var/www/html and I point the webserver to /var/www/html/public, but you can easily change those).
Since you are using an image that includes both a webserver and the PHP runtime, that should be it.
Answered By - yivi
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.