我正在寻找一种更好的解决方案,以在通过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 镜像,将composer.json挂载到其中进行安装,然后将完成的供应商从 Composer 容器复制到容器中的某个位置,并在需要的地方链接。像这样:
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"
但是对于这样一个普通的问题,仍然感觉有点变通方法。是否有更好的方法可以解决此问题或任何已知的良好做法?
最佳答案
我认为最佳实践以及我的专业工作是在这种情况下根本不使用卷。在构建时,我的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卷的几件事情:
docker-compose.yml
文件中的任何卷或环境变量之前,都会发生Dockerfile中的所有事情。如果您的目标是填充卷,则不能在Dockerfile中执行此操作(这在Docker中通常很尴尬;请改用本机宿主工具)。 /app
目录中起作用,然后在该目录上绑定(bind)挂载本地源代码树。基本上使Dockerfile成为无人操作。 VOLUME
指令,则无法再对该镜像中的该目录进行任何更改。 (在您的问题中,在composer
指令之后运行VOLUME
将无提示地无效。)VOLUME
。我建议您不要在Dockerfiles中声明VOLUME
,特别是对于包含代码的目录(尤其是当您删除并重新创建容器时,要使用新的图像代码更新它们)时尤其如此。 关于docker - 在构建时从docker访问composer/npm的已安装卷吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53998567/