在Dockerfile中运行composer安装

JBx*_*ine 17 composer-php docker docker-compose

我正在尝试Dockerize我的laravel应用程序.该应用程序已经构建并在git中,但我.gitignore我的供应商文件夹.我添加了一个Dockerfile,如下所示:

FROM php:7.1-fpm-alpine

RUN apk update && apk add curl && \
  curl -sS https://getcomposer.org/installer | php \
  && chmod +x composer.phar && mv composer.phar /usr/local/bin/composer

RUN apk --no-cache add --virtual .build-deps $PHPIZE_DEPS \
  && apk --no-cache add --virtual .ext-deps libmcrypt-dev freetype-dev \
  libjpeg-turbo-dev libpng-dev libxml2-dev msmtp bash openssl-dev pkgconfig \
  && docker-php-source extract \
  && docker-php-ext-configure gd --with-freetype-dir=/usr/include/ \
                                   --with-png-dir=/usr/include/ \
                                   --with-jpeg-dir=/usr/include/ \
  && docker-php-ext-install gd mcrypt mysqli pdo pdo_mysql zip opcache \
  && pecl install mongodb redis xdebug \
  && docker-php-ext-enable mongodb \
  && docker-php-ext-enable redis \
  && docker-php-ext-enable xdebug \
  && docker-php-source delete \
  && apk del .build-deps

WORKDIR /var/www/html

COPY composer.json composer.lock ./
RUN composer install --no-scripts --no-autoloader

COPY . .
RUN chmod +x artisan

RUN composer dump-autoload --optimize && composer run-script post-install-cmd

CMD php artisan serve --host 0.0.0.0 --port 5001
Run Code Online (Sandbox Code Playgroud)

当我建立时,这似乎很有效.我看到依赖项被下载了,我看到输出中生成了自动加载文件.但是,一旦构建完成,供应商文件夹实际上就不存在了.我猜它是在一个中间容器中完成的,然后被移除了?因此,当我运行docker-compose时,我得到:致命错误:require():未能打开所需的'/var/www/html/bootstrap/../vendor/autoload.php'

这个线程似乎指出了问题 - 可能 - 但并没有真正提供解决方案:在Dockerfile中运行时,Composer安装不会安装软件包

JBx*_*ine 22

这需要大量挖掘Docker的新人:)感谢@ iurii-drozdov指出我正确的方向与docker-compose.yml的评论.

在我的docker-compose.yml中,我将我的主机工作目录安装到/ var/www/html中.这发生在构建之后.因此,composer运行安装,在构建时正确安装了所有依赖项,然后,当运行docker-compose时,我将我的主机目录挂载到容器中并擦除所有这些更改.

解决方案是安装卷运行composer install .通过简单地在启动它之后执行容器 - 运行作曲家和任何其他包管理器 - 然后最终运行Web服务器,这是直截了当的.

但是,我找到了一个更整洁的解决方案.我将Dockerfile中的最终CMD更改为:

CMD bash -c "composer install && php artisan serve --host 0.0.0.0 --port 5001"
Run Code Online (Sandbox Code Playgroud)

这将运行composer install并将web服务器作为docker-compose的最后一部分.

感谢这里的解决方案:Docker - 安装卷后执行命令

  • 您还可以在 docker-compose 中的容器声明下添加 command 关键字,如下所示: command:composer install && php artisanserve --host 0.0.0.0 --port 5001 (4认同)
  • 如果是 Lumen,没有 `php artisan serve`,CMD 会触发容器以状态 0 退出。有什么解决方案吗? (2认同)
  • 是的,但请记住,在 CMD 中安装依赖项的版本是不同的解决方案,其中依赖项不是 DOCKER 映像的一部分。现在,它们将在部署期间的每个 docker 运行中被拉取,这可能会导致部署错误。 (2认同)

Phi*_*hil 21

您还可以使用官方的 dockerhub composer镜像。

这是一个多阶段构建的示例,其中 Composer 首先在单独的容器中运行。结果/app/vendor将复制到最终图像中您想要的任何位置。

FROM composer as builder
WORKDIR /app/
COPY composer.* ./
RUN composer install
...
FROM php:7.1-fpm-alpine
...
COPY --from=builder /app/vendor /var/www/vendor
Run Code Online (Sandbox Code Playgroud)


Kie*_*ran 16

如果您不想在 Dockerfile 中包含该命令,我们发现最简单的方法是将其添加到我们的 docker-compose 文件中:

composer_installation:
  container_name: composer_installation
  image: composer
  volumes:
    - ./:/app
  command: composer install --ignore-platform-reqs
Run Code Online (Sandbox Code Playgroud)

更新有点慢,可能是因为它正在与 PHP 容器同步。


jau*_*ust 8

我使用这个命令,它会生成供应商:)

docker run --rm -it --volume $(pwd):/app prooph/composer:7.2 install --ignore-platform-reqs
Run Code Online (Sandbox Code Playgroud)

  • 这是无关紧要的,要求 Dockerfile 实现,而不是命令行。 (2认同)

jon*_*tro 6

根据https://hub.docker.com/_/composer的建议

WORKDIR /your/base/path
COPY --from=composer /usr/bin/composer /usr/bin/composer
RUN composer install
Run Code Online (Sandbox Code Playgroud)