2017-07-01 100 views
2

根据官方[php][1]图像,我有以下Dockerfile用于php运行时。Docker - 安装卷后执行命令

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文件
  • 有容器保持运行afters

+1

Dude随着Composer的每一个新版本的移除,经常更换哈希检查。顺便说一下,您希望让您的自定义入口点在容器启动时进行安装。另外,您应该将您的应用程序数据移动到仅限数据的容器,以便您可以分解责任。然后,您的应用程序可以独立于Web服务器的基础架构进行部署。祝你好运 –

+0

@mike你能提供一个使用数据专用容器的例子,以及它如何与docker-compose一起使用?或者,提供一个你认为很好地描述这个概念的资源?或两者? :-) cheers –

+1

在网上有很多例子可以找到,只需查找'data only container'或'docker persistence strategy'。你所做的只是构建你的应用程序(作曲家安装/文档/资产等),然后获得最小的图像(144字节图像可用!),并将所有内容复制到它。使用docker-compose中的'volumes_from'指令将该数据装载到php映像中的apache根目录。所有这些都可以通过Jenkins,Gitlab等任何CI/CD系统来实现。 –

回答

2

我大体上同意克里斯的回答当地的发展。我将提供一些与最近的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 

这将删除所有来自应用程序图像本身作曲的,而是使用第一阶段安装的依赖在另一种情况下,并在将它们复制到最终图像。

现在,在开发过程中你有一些选择。根据您的docker-compose.yml命令,它听起来像是将应用程序安装到容器中的.:/var/www/root。您可以添加composer服务到您的docker-compose.yml类似于我的示例https://gist.github.com/andyshinn/e2c428f2cd234b718239。在这里,当你需要在本地更新依赖关系时,你只需要做docker-compose run --rm composer install(这样可以在容器内部建立依赖关系,这对于本机编译的扩展很重要,特别是在部署容器和在Windows或Mac上开发时)。

另一种选择是做一些类似于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 

回顾一下,推理使用外部容器/服务建设中的形象和安装作曲家依赖这种方法:

  • 平台特定依赖关系将针对容器(Linux架构与Windows或Mac)正确构建。
  • 否您的本地计算机上需要Composer或PHP(它全部包含在Docker和Docker Compose中)。
  • 您创建的初始图像是可运行和可部署的,无需在其中安装代码。在开发中,您只是用本地卷覆盖/var/www/root文件夹。
1

如果这是针对一般开发环境的,那么它的意图就不是很理想,因为它将应用程序与Docker配置耦合在一起。

只需运行composer install通过其他方式(在dockerhub上有一个可用于此的图像,它允许您仅执行(docker run -it --rm -v $(pwd):/app composer/composer install)。


但是是有可能,你需要在Dockerfile的最后一行是bash -c "composer install && php-fpm"


  • 等待卷成为安装

没有,体积不能在泊坞窗构建过程来进行安装。尽管可以在复制源代码。

  • 运行作曲家安装使用安装composer.json文件

没有见上响应。

  • 具有容器保持后

是的运行,将需要执行php-fpm --nodaemonize(这是一个长期运行的进程,因此它不会终止。

+1

您可以争辩说,所有'composer install'都会添加应该包含在图像中的应用程序的_are_dependencies。通过外部操作,可能会在部署期间或环境之间丢失或错误匹配这些依赖关系。 –

+0

好点。在这种情况下,源代码也必须添加,这听起来不像OP的意图。 –

+0

我同意。我认为开发你的答案确实有意义,我喜欢你通过使用'composer'图像将它修改为更多的“Docker方式”。我也试图在最终将应用程序部署到生产环境时提前考虑,在这种情况下,答案可能会有所不同。 –