在容器的每个构建中运行composer安装和npm安装



我试图创建一个安装了npm和composer的php-apache容器,并在每个构建中运行composer installnpm install,但我遇到了错误。

# 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

日志错误:

Action"-D FOREGROUNDD sh-c php/usr/local/bin/composer install"失败。

如果我尝试使用npm install,则会出现相同的错误。

我可以在docker中运行命令,但我想自动化

我认为您采用了一种不正确的方法。这些命令是图像构建过程的一部分,因此它们应该是Dockerfile的一部分。

生成过程发生在卷可用之前(容器未运行,因此不可能依赖于这些卷(。您需要做的是在运行composer install之前将必要的文件复制到正在构建的映像中。

利用多阶段构建码头文件的一种更明智的方法是:

## 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"]

这样,最终生成的图像就不包括任何开发依赖项。该图像主要用于生产,因此您可以构建和部署它。

要在开发过程中在本地运行它,只需使用所需的卷装载点在本地运行相同的映像即可。您只需要在依赖项更改或升级时重新生成映像。

您需要调整路径,使其与您想要的配置相匹配(我在/var/www/html上构建项目,并将Web服务器指向/var/www/html/public,但您可以轻松更改这些路径(。

由于您使用的图像同时包含Web服务器和PHP运行时,因此应该就是这样

您可以尝试将composer安装到入口点。

我通常会使用一个文件。你可能想试试这个。

入口点.sh

#!/bin/sh
set -e
php /usr/local/bin/composer install
exec "$@"

并且在你的档案中

# ...
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
CMD ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]

这会导致这样的结果。

/usr/local/bin/entrypoint.sh /usr/sbin/apache2ctl -D FOREGROUND

由于入口点的最后一行是exec "$@",它将接受传递到entrypoint.sh的所有参数并执行它

最新更新