Docker - 挂载卷后执行命令 [英] Docker - Execute command after mounting a volume

查看:32
本文介绍了Docker - 挂载卷后执行命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下基于官方 [php][1] 映像的 php 运行时 Dockerfile.

I have the following Dockerfile for a php runtime based on the official [php][1] image.

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 时遇到问题.

I am having trouble running composer install.

我猜测 Dockerfile 在安装卷之前运行,因为如果添加,我收到 composer.json 文件未找到错误:

I am guessing that the Dockerfile runs before a volume is mounted because I receive a composer.json file not found error if adding:

...
&& mv composer.phar /usr/local/bin/composer 
&& composer install

以上.

但是,将以下属性添加到 docker-compose.yml:

But, adding the following property to docker-compose.yml:

command: sh -c "composer install && composer require drush/drush"

似乎在命令执行完成后终止容器.

seems to terminate the container after the command finishes executing.

有没有办法:

  • 等待卷挂载
  • 使用安装的 composer.json 文件运行 composer install
  • 让容器在之后继续运行

?

推荐答案

我基本同意 Chris 对本地开发的回答.我将提供一些与最近的 Docker 功能相结合的东西,它可能会为使用同一映像进行本地开发和最终生产部署设置路径.

I generally agree with Chris's answer for local development. I am going to offer something that combines with a recent Docker feature that may set a path for doing both local development and eventual production deployment with the same image.

让我们首先从我们可以构建的镜像开始,该镜像可以用于本地开发或包含代码和依赖项的某个地方的部署.在最新的 Docker 版本 (17.05) 中,我们可以利用一个新的多阶段构建功能.在这种情况下,我们可以首先将所有 Composer 依赖项安装到构建上下文中的文件夹中,然后将它们复制到最终映像中,而无需将 Composer 添加到最终映像中.这可能看起来像:

Let's first start with the image that we can build in a manner that can be used for either local development or deployment somewhere that contains the code and dependencies. In the latest Docker version (17.05) there is a new multi-stage build feature that we can take advantage of. In this case we can first install all your Composer dependencies to a folder in the build context and then later copy them to the final image without needing to add Composer to the final image. This might look like:

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,而是使用第一阶段在另一个上下文中安装依赖项并将它们复制到最终映像.

This removes all of Composer from the application image itself and instead uses the first stage to install the dependencies in another context and copy them over to the final image.

现在,在开发过程中,您有一些选择.根据您的 docker-compose.yml 命令,听起来您正在将应用程序作为 .:/var/www/root 安装到容器中.您可以将 composer 服务添加到您的 docker-compose.yml 类似于我在 https://gist.github.com/andyshinn/e2c428f2cd234b718239.在这里,当您需要在本地更新依赖项时,您只需执行 docker-compose run --rm composer install (这会将依赖项构建在容器内,这对于本机编译的扩展可能很重要,特别是如果您正在部署作为容器并在 Windows 或 Mac 上开发).

Now, during development you have some options. Based on your docker-compose.yml command it sounds like you are mounting the application into the container as .:/var/www/root. You could add a composer service to your docker-compose.yml similar to my example at https://gist.github.com/andyshinn/e2c428f2cd234b718239. Here, you just do docker-compose run --rm composer install when you need to update dependencies locally (this keeps the dependencies build inside the container which could matter for native compiled extensions, especially if you are deploying as containers and developing on Windows or Mac).

另一种选择是只做一些类似于 Chris 已经建议的事情,并在需要时使用官方 Composer 映像来更新和管理依赖项.在我对 GitHub 有私有依赖项之前,我在本地做过类似的事情,需要 SSH 身份验证:

The other option is to just do something similar to what Chris has already suggested, and use the official Composer image to update and manage dependencies when needed. I've done something like this locally before where I had private dependencies on GitHub which required SSH authentication:

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 依赖项的方法的原因:

To recap, the reasoning for this method of building the image and installing Composer dependencies using an external container / service:

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

这篇关于Docker - 挂载卷后执行命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆