我正在寻找一种更好的解决方案,以在通过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"
但是对于这样一个普通的问题,它仍然感觉是一种解决方法。有没有更好的方法可以解决此问题或任何已知的良好做法?
答案 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
,尤其是对于包含代码的目录(尤其是当您删除并重新创建容器时,您希望它们使用新的映像代码进行更新)时尤其如此。