【问题标题】:Docker multi-stage build not copying between stagesDocker多阶段构建不在阶段之间复制
【发布时间】:2019-01-02 05:45:56
【问题描述】:

我正在尝试创建一个多阶段构建,其中第一阶段为主题安装纱线,第二阶段为 Drupal 设置 PHP 环境。

当我查看输出时,看起来 yarn install 正在运行,但底部附近的 COPY 命令不会将其复制到 PHP 映像中。如果我是对的,那么应该在我的本地计算机上创建 node_modules 目录吗?

docker-compose.yml:

version: '3.7'
services:
  web:
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ./:/var/www/html:cached
    env_file:
      - ./local-development.env
    ports:
      - "8888:80"
  db:
    image: mysql:5.7
    env_file:
      - ./local-development.env
    ports:
      - "3306:3306"

Dockerfile:

FROM node:latest as yarn-install
WORKDIR /app
COPY ./web/themes/material_admin_mine ./
RUN yarn install --verbose --force;

# from https://www.drupal.org/docs/8/system-requirements/drupal-8-php-requirements
FROM php:7.2-apache

# Install & setup Xdebug
RUN yes | pecl install xdebug \
&& echo "zend_extension=$(find /usr/local/lib/php/extensions/ -name xdebug.so)" > /usr/local/etc/php/conf.d/xdebug.ini \
&& echo "xdebug.remote_enable=1" >> /usr/local/etc/php/conf.d/xdebug.ini \
&& echo 'xdebug.remote_connect_back=0' >> /usr/local/etc/php/conf.d/xdebug.ini \
&& echo 'xdebug.remote_host=docker.for.mac.localhost' >> /usr/local/etc/php/conf.d/xdebug.ini \
&& echo 'xdebug.remote_port=9000' >> /usr/local/etc/php/conf.d/xdebug.ini \
&& echo 'xdebug.remote_handler=dbgp' >> /usr/local/etc/php/conf.d/xdebug.ini \
&& echo 'xdebug.remote_mode=req' >> /usr/local/etc/php/conf.d/xdebug.ini \
&& echo 'xdebug.remote_autostart=1' >> /usr/local/etc/php/conf.d/xdebug.ini \
&& echo 'xdebug.idekey=PHPSTORM' >> /usr/local/etc/php/conf.d/xdebug.ini

# Install git & mysql-client for running Drush
RUN apt update; \
apt install -y \
git \
mysql-client

# install the PHP extensions we need
RUN set -ex; \
\
if command -v a2enmod; then \
    a2enmod rewrite; \
fi; \
\
savedAptMark="$(apt-mark showmanual)"; \
\
apt-get update; \
apt-get install -y --no-install-recommends \
    libjpeg-dev \
    libpng-dev \
    libpq-dev \
    unzip \
    git \
; \
\
curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer; \
\
docker-php-ext-configure gd --with-png-dir=/usr --with-jpeg-dir=/usr; \
docker-php-ext-install -j "$(nproc)" \
    gd \
    opcache \
    pdo_mysql \
    pdo_pgsql \
    zip \
; \
\
# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies
apt-mark auto '.*' > /dev/null; \
apt-mark manual $savedAptMark; \
ldd "$(php -r 'echo ini_get("extension_dir");')"/*.so \
    | awk '/=>/ { print $3 }' \
    | sort -u \
    | xargs -r dpkg-query -S \
    | cut -d: -f1 \
    | sort -u \
    | xargs -rt apt-mark manual; \
\
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
rm -rf /var/lib/apt/lists/*

# set recommended PHP.ini settings
# see https://secure.php.net/manual/en/opcache.installation.php
RUN { \
    echo 'opcache.memory_consumption=128'; \
    echo 'opcache.interned_strings_buffer=8'; \
    echo 'opcache.max_accelerated_files=4000'; \
    echo 'opcache.revalidate_freq=60'; \
    echo 'opcache.fast_shutdown=1'; \
    echo 'opcache.enable_cli=1'; \
} > /usr/local/etc/php/conf.d/opcache-recommended.ini

# Various packages required to run Gulp in the theme directory
# gnupg is require for nodejs
RUN apt update; \
apt install gnupg -y; \
apt install gnupg1 -y; \
apt install gnupg2 -y; \
cd ~; \
curl -sL https://deb.nodesource.com/setup_10.x -o nodesource_setup.sh; \
bash nodesource_setup.sh; \
apt install nodejs -y; \
npm install gulp-cli -g -y; \
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - ;\
echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list; \
apt update && apt install yarn -y;

WORKDIR /var/www/html
COPY --from=0 /app ./web/themes/material_admin_mine

【问题讨论】:

  • COPY 将文件从阶段 0 复制到阶段 1(php 图像),而不是您的主机。
  • @Siyu 谢谢,但由于 docker-compose 中有一个卷设置,它不应该将这些复制的文件同步到我的本地机器吗?无论哪种方式,当我 bash 进入容器时,它似乎都没有复制它们。

标签: docker docker-compose dockerfile docker-multi-stage-build


【解决方案1】:

当您的 Dockerfile 以以下结尾时:

WORKDIR /var/www/html
COPY --from=0 /app ./web/themes/material_admin_mine

这实际上应该将数据从第一个构建阶段复制到最终映像。但是当你用

启动容器时
volumes:
  - ./:/var/www/html:cached

/var/www/html 目录树中的所有内容,包括最后的 COPY 步骤,都被隐藏并替换为主机上当前目录中的内容。如果你把它想象成一个副本,它是一个单向副本到容器中;以后的更改将被复制回主机,但没有任何东西可以将映像中的内容与您之前在启动时目录中的内容同步。

Dockerfile 本质上不会影响主机文件系统的内容。在您的情况下,听起来主机内容对于您的应用程序来说是次要的。鉴于进入第一阶段的情况,我只需在主机上运行yarn install 步骤并完成它(您甚至可能已经拥有可用的 Node 和 Yarn)。否则,您将需要一个更具选择性的volumes: 部分,仔细尝试避免覆盖该目录;你也许可以挂载类似./web/src:/var/www/html/web/src 的东西来只包含你的应用程序代码并避免隐藏.../web/themes 树。

【讨论】:

  • 感谢您的回复,这解释了正在发生的事情以及为什么我的方法没有达到我想要达到的效果。我的想法是在容器构建中运行所有设置步骤,因此开发人员只需构建容器,他们需要的一切都会自动为他们设置,但看起来这不是一个简单的,甚至可能是正确的方法。
猜你喜欢
  • 2020-01-14
  • 2019-03-25
  • 2020-12-15
  • 2019-04-16
  • 2020-07-13
  • 2022-11-25
  • 1970-01-01
  • 2021-12-16
  • 1970-01-01
相关资源
最近更新 更多