【问题标题】:Accessing mounted volumes from docker for composer/npm installs on build time?在构建时从 docker 访问已安装的卷以进行 composer/npm 安装?
【发布时间】:2019-05-28 15:25:00
【问题描述】:

我正在寻找一个更好的解决方案来在通过 docker-compose 挂载的主机卷中安装 composer 或 npm 包。

在我的 docker-compose.yml 中,我有:

volumes:
  - ./app:/var/www/app
  ...

在我的 dockerfile 中,我想使用这个卷来安装东西:

VOLUME ["/var/www/app"]
RUN composer install -d /var/www/app

但据我了解,当从 dockerfile 构建容器时,安装在 docker-compose 中的卷尚不可用。

所以我的下一次尝试是在容器启动时这样做:

CMD bash -c "composer install -d /var/www/app && /usr/sbin/apache2ctl -DFOREGROUND"

这至少有效,但每次运行容器时都会调用 composer install,这是多余的。

所以我目前的想法是使用专用的作曲家映像,将 composer.json 挂载到其中进行安装,然后将完成的供应商从作曲家容器的某处复制到容器中并链接到需要的地方。像这样:

FROM composer as composer
COPY ./app/composer.json /app
COPY ./app/composer.lock /app
RUN composer install --ignore-platform-reqs --no-scripts

FROM library/ubuntu:jessie
# ... do other stuff with the main image ...

COPY --from=composer /app/vendor /var/www/composer/vendor
CMD bash -c "ln -s /var/www/composer/vendor /var/www/app/vendor  && /usr/sbin/apache2ctl -DFOREGROUND"

但是对于这样一个普通的问题,它仍然感觉有点解决方法。有没有更好的方法来解决这个问题或任何已知的良好做法?

【问题讨论】:

  • 我个人更喜欢直接在主机上执行 composer 命令,或者通过 docker 通过execrun 执行。并且仅在实际需要时才这样做。
  • 我也这样做了,但是您需要使用所有工具包之类的东西来污染您的主机系统。假设您为不同的版本开发,那将是完全混乱的。如果你执行它,你必须在每次重建容器时都这样做,这也会限制自动化测试的可能性......:/

标签: docker docker-compose composer-php dockerfile


【解决方案1】:

我认为最佳实践以及我的专业做法是在这种情况下根本不使用卷。构建时应用程序代码中的我的 Dockerfile COPYs。我有一个可用的主机开发设置(唯一真正的主机依赖项是 Node 本身;其他所有内容都在 node_modules 目录中),所以如果我有问题,我可以在本地环境中重现、调试和编写测试.只有当它有效时,我才会回到 Docker。

FROM ???
WORKDIR /var/www/app
COPY app/composer.json app/composer.lock ./
RUN composer install --ignore-platform-reqs --no-scripts
COPY app/ ./
...
CMD ["apache2ctl", "-DFOREGROUND"]

否则,这里需要记住一些关于 Docker 卷的事情:

  • Dockerfile 中的所有内容都发生在 docker-compose.yml 文件中的任何卷或环境变量之前。如果您的目标是填充卷,则不能在 Dockerfile 中完成(这在 Docker 中通常很尴尬;请改用本机主机工具)。

  • 如果将卷挂载到容器目录中,它会完全隐藏已经存在的内容。我看到很多关于 Dockerfile 的问题,这些问题只能在容器本地 /app 目录中工作,然后在其上绑定挂载本地源代码树;这基本上使 Dockerfile 成为空操作。

  • 如果您的 Dockerfile 中有 VOLUME 指令,则不能再对映像中的该目录进行任何更改。 (在您的问题中,在 VOLUME 指令之后运行 composer 将静默无效。)

  • 您可以将卷挂载到容器中的任何目录中,无论它是否被声明为VOLUME。我建议不要在 Dockerfiles 中声明 VOLUMEs,尤其是对于包含代码的目录(您希望在容器被删除和重新创建时使用新的图像代码更新这些目录)。 p>

【讨论】:

  • 感谢您的详细回答。因此,您正在主机上进行开发,并且 - 在某些时候 - 您构建具有该固定状态的容器。我的“目标”是隔离主机工具,以将我的应用程序从主机运行到容器中,同时仍然能够为正在进行的开发进行大量代码更改。
  • 当我看到这样的答案时,我总是很惊讶——如果你不使用卷,你实际上是如何开发的?你启动了容器,你看到一个错字——为了看到它,你必须在修复后重新创建容器。使用卷,您会立即看到它。效率不是提高了 100500 倍???
  • 我在日常开发过程中根本不使用 Docker,即使它是最终部署的关键部分。 Node 比 Docker 更容易安装,我不需要做任何神奇的配置来让我的 IDE 识别出解释器。
猜你喜欢
  • 2021-05-08
  • 2020-11-23
  • 2019-09-14
  • 2019-05-02
  • 2016-03-25
  • 2015-11-15
  • 1970-01-01
  • 2016-12-29
相关资源
最近更新 更多