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

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

问题描述

基于官方 [php] [1] 图片,我具有以下Dockerfile用于php运行时。

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

我在运行<$ c $时遇到问题c> 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"

似乎要终止

是否可以执行以下操作:

Is there a way to:


  • 等待卷挂载

  • 使用挂载的 composer.json 运行 composer安装 c $ c>文件

  • 容器之后是否继续运行

  • wait for a volume to become mounted
  • run composer install using the mounted composer.json file
  • have the container keep running afters

推荐答案

我通常同意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 。您可以在 docker-compose.yml 中添加 composer 服务,类似于我在 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映像,可在需要时更新和管理依赖项。在本地需要SSH身份验证的GitHub上有私有依赖项之前,我已经在本地进行了类似的操作:

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中)。

  • 您构建的初始映像可运行且无需部署即可部署i ng将代码装入其中。在开发中,您只是使用本地卷覆盖 / var / www / root 文件夹。

  • Platform specific dependencies will be built correctly for the container (Linux architecture vs Windows or Mac).
  • No Composer or PHP is required on your local computer (it is all contained inside Docker and Docker Compose).
  • The initial image you built is runnable and deployable without needing to mount code into it. In development, you are just overriding the /var/www/root folder with a local volume.

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

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