我有一个基于官方[php][1]
图像的php运行时的以下Dockerfile。
FROM php:fpm
WORKDIR /var/www/root/
RUN apt-get update && apt-get install -y \
libfreetype6-dev \
libjpeg62-turbo-dev \
libmcrypt-dev \
libpng12-dev \
zip \
unzip \
&& docker-php-ext-install -j$(nproc) iconv mcrypt \
&& docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
&& docker-php-ext-install -j$(nproc) gd \
&& docker-php-ext-install mysqli \
&& docker-php-ext-enable opcache \
&& php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
&& php -r "if (hash_file('SHA384', 'composer-setup.php') === '669656bab3166a7aff8a7506b8cb2d1c292f042046c5a994c43155c0be6190fa0355160742ab2e1c88d40d5be660b410') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" \
&& php composer-setup.php \
&& php -r "unlink('composer-setup.php');" \
&& mv composer.phar /usr/local/bin/composer
我无法运行composer install
。
我猜测Dockerfile在挂载卷之前运行,因为如果添加以下内容我收到composer.json
文件未找到错误:
...
&& mv composer.phar /usr/local/bin/composer \
&& composer install
以上。
但是,将以下属性添加到docker-compose.yml
:
command: sh -c "composer install && composer require drush/drush"
似乎在命令完成执行后终止容器。
有办法:
composer install
文件composer.json
答案 0 :(得分:5)
我普遍同意克里斯对当地发展的回答。我将提供一些与最近的Docker功能相结合的东西,它可以为同一图像设置本地开发和最终生产部署的路径。
让我们首先从可以用于包含代码和依赖项的本地开发或部署的方式构建的映像开始。在最新的Docker版本(17.05)中,我们可以利用新的多阶段构建功能。在这种情况下,我们可以首先将所有Composer依赖项安装到构建上下文中的文件夹,然后将它们复制到最终映像,而无需将Composer添加到最终映像。这可能看起来像:
FROM composer as composer
COPY . /app
RUN composer install --ignore-platform-reqs --no-scripts
FROM php:fpm
WORKDIR /var/www/root/
RUN apt-get update && apt-get install -y \
libfreetype6-dev \
libjpeg62-turbo-dev \
libmcrypt-dev \
libpng12-dev \
zip \
unzip \
&& docker-php-ext-install -j$(nproc) iconv mcrypt \
&& docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
&& docker-php-ext-install -j$(nproc) gd \
&& docker-php-ext-install mysqli \
&& docker-php-ext-enable opcache
COPY . /var/www/root
COPY --from=composer /app/vendor /var/www/root/vendor
这将从应用程序映像本身中删除所有Composer,而是使用第一个阶段在另一个上下文中安装依赖项,并将它们复制到最终映像。
现在,在开发过程中你有一些选择。根据您的docker-compose.yml
命令,您可能会将应用程序作为.:/var/www/root
安装到容器中。您可以向composer
添加docker-compose.yml
服务,类似于我在https://gist.github.com/andyshinn/e2c428f2cd234b718239的示例。在这里,当您需要在本地更新依赖项时,您只需执行docker-compose run --rm composer install
(这样可以在容器内部构建依赖项,这对于本机编译的扩展非常重要,特别是如果您要部署为容器并在Windows或Mac上进行开发)。 / p>
另一个选择是执行类似于Chris已经建议的操作,并使用官方的Composer镜像在需要时更新和管理依赖项。我之前在本地做了类似的事情,之前我在GitHub上有私有依赖,需要SSH身份验证:
docker run --rm --interactive --tty --volume $PWD:/app:rw,cached --volume $SSH_AUTH_SOCK:/ssh-auth.sock --env SSH_AUTH_SOCK=/ssh-auth.sock --volume $COMPOSER_HOME:/composer composer:1.4 install --ignore-platform-reqs --no-scripts
回顾一下,使用外部容器/服务构建映像和安装Composer依赖项的方法的原因是:
/var/www/root
文件夹。答案 1 :(得分:1)
如果这是针对一般开发环境的,那么意图并不理想,因为它将应用程序与Docker配置耦合。
只需通过其他方式单独运行composer install
(在dockerhub上有可用的图像,这样您就可以(docker run -it --rm -v $(pwd):/app composer/composer install
)。
但是,您可能需要Dockerfile
中的最后一行为bash -c "composer install && php-fpm"
。
不,在docker构建过程中无法装入卷。虽然您可以复制源代码。
不,见上述回复。
是的,您需要执行php-fpm --nodaemonize
(这是一个长时间运行的进程,因此它不会终止。
答案 2 :(得分:1)
我在这个兔子洞里呆了5个小时,那里的所有解决方案都太复杂了。最简单的解决方案是exclude vendor or node_modules and similar directories from volume。
#docker-compose.yml
volumes:
- .:/srv/app/
- /srv/app/vendor/
因此,这将映射当前项目目录,但不包括其供应商子目录。不要忘记斜杠!
因此,现在您可以轻松地在dockerfile中运行composer install,当docker装载您的卷时,它将忽略供应商目录。
答案 3 :(得分:0)
在将卷装入Docker容器后执行命令
假设您正在从公共存储库中获取依赖项
docker run --interactive -t --privileged --volume ${pwd}:/xyz composer /bin/sh -c 'composer install'
要从私有git存储库中获取依赖项,您需要复制/创建ssh密钥,我想这应该不在这个问题的范围之内。