从docker访问composer / npm的已安装卷是否在构建时安装?

时间:2019-01-01 20:05:55

标签: docker docker-compose composer-php dockerfile

我正在寻找一种更好的解决方案,以在通过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安装,这是多余的。

所以我目前的想法是使用专用的作曲家映像,将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"

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

1 个答案:

答案 0 :(得分:0)

我认为最佳实践以及我的专业经验是在这种情况下根本不使用卷。构建时,我的Dockerfile COPY在应用程序代码中。我有一个有效的主机开发设置(唯一的主机依赖项是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指令,则无法再对该映像中的该目录进行任何更改。 (在您的问题中,在composer指令后运行VOLUME不会产生任何影响。)

  • 您可以将卷装载到容器中的任何目录中,而不管其是否被声明为VOLUME。我建议不要在Dockerfiles中声明VOLUME,尤其是对于包含代码的目录(尤其是当您删除并重新创建容器时,您希望它们使用新的映像代码进行更新)时尤其如此。