Docker - 安装卷后执行命令

Rap*_*nah 11 docker dockerfile docker-compose

我有一个基于官方[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
Run Code Online (Sandbox Code Playgroud)

我跑步时遇到了麻烦composer install.

我猜测Dockerfile在挂载卷之前运行,因为composer.json如果添加以下内容我收到一个找不到文件的错误:

...
&& mv composer.phar /usr/local/bin/composer \
&& composer install
Run Code Online (Sandbox Code Playgroud)

以上.

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

command: sh -c "composer install && composer require drush/drush"
Run Code Online (Sandbox Code Playgroud)

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

有办法:

  • 等待卷安装
  • composer install使用已安装的composer.json文件运行
  • 让容器继续运行

Buk*_*ksy 6

我已经在这个兔子洞里呆了 5 个小时,所有的解决方案都太复杂了。最简单的解决方案是从 volume 中排除 vendor 或 node_modules 和类似目录

#docker-compose.yml
volumes:
      - .:/srv/app/
      - /srv/app/vendor/
Run Code Online (Sandbox Code Playgroud)

所以这将映射当前项目目录但排除其供应商子目录。不要忘记尾部斜线!

所以现在您可以轻松地在 dockerfile 中运行 composer install 并且当 docker 挂载您的卷时,它将忽略供应商目录。


And*_*inn 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
Run Code Online (Sandbox Code Playgroud)

这将从应用程序映像本身中删除所有Composer,而是使用第一个阶段在另一个上下文中安装依赖项,并将它们复制到最终映像.

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

另一个选择是执行类似于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
Run Code Online (Sandbox Code Playgroud)

回顾一下,使用外部容器/服务构建映像和安装Composer依赖项的这种方法的原因如下:

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