我有两个容器: nginx 和角度。 angular 容器包含代码,并且在有新版本(带有with望塔)时会自动从注册表中拉出。
我在 angular 和 nginx 之间设置了共享卷,以将代码从 angular 共享到 nginx 。
### Angular #########################################
angular:
image: registry.gitlab.com/***/***:staging
networks:
- frontend
- backend
volumes:
- client:/var/www/client
### NGINX Server #########################################
nginx:
image: registry.gitlab.com/***/***/***:staging
volumes:
- client:/var/www/client
depends_on:
- angular
networks:
- frontend
- backend
volumes:
client:
networks:
backend:
frontend:
当我第一次构建并运行环境时,一切正常。 问题是,当有新版本的 client 客户端,图像被拉出,容器被重新构建并且新的代码版本位于 angular 容器内时,但是在 nginx 容器中,它仍然是 client 的旧代码版本。
共享卷不允许我做我想做的事情,因为我们无法指定谁是主机,是否可以将一个卷从一个容器装载到另一个容器?</ p>
谢谢。
编辑
角度容器仅在此处提供文件。我们可以将已构建的应用程序同步到主机上的服务器,然后将其卷装到容器(主机-> guest虚拟机)上,但这将违反我们的CI流程: build app -> build图片-> 推送到注册表-> watch望塔获取新图片
答案 0 :(得分:1)
Docker卷不打算共享代码,建议您重新考虑此工作流程。
第一次启动具有空卷的容器,第一次 ,如果卷已经为空,则 ,Docker将populate it with contents from the container 。由于卷旨在保存 data ,并且应用程序可能会更改将要保留的数据,因此,如果容器重新启动,Docker不会覆盖应用程序数据。卷目录中的内容保持不变。
在您的设置中,这意味着会发生这种情况:
angular
容器,并且由于client
命名卷为空,因此Docker将内容复制到其中。nginx
容器。angular
容器;但是由于client
命名的卷为空,因此Docker将旧内容保留在那里。nginx
容器仍然可以看到旧内容。对于典型的浏览器应用程序,实际上并不需要运行“程序”:一旦您通过Typescript / Webpack / ...序列运行,输出便是完全静态文件的集合。对于Angular,有一个Ahead-of-Time compiler会生成这些静态文件。我在这里建议的顺序是:
ng serve
或npm start
单独开发浏览器应用程序。由于所有这些都在本地运行,因此您无需与特定于Docker的任何内容(文件系统映射,权限,端口映射等)作斗争。这是一个完全正常的Javascript开发序列。您所需的系统组件仅仅是Node;绝对比安装和配置Docker容易。npm build
将应用程序编译为静态文件。nginx
容器中;或将它们构建为自定义图像。在最后一种情况下,您将不使用命名的Docker卷。相反,您可以将本地文件系统挂载到容器中。这种情况下的完整docker-compose.yml
文件如下所示:
version: '3'
services:
nginx:
image: registry.gitlab.com/***/***/***:staging
volumes:
- ./client:/var/www/client
ports:
- '8000:80'
答案 1 :(得分:1)
根据您的评论:
没有为客户端运行的程序,CI会编译应用程序并构建自定义映像,该映像
COPY
中的应用程序文件位于/var/www/client
中。然后,watch望塔拉出这个新图像并重新启动容器。容器仅在带有({tail -f /dev/null & wait
)的守护进程中运行。
从高层次看,我根本不需要两个容器或两个卷。只需使用多阶段构建来构建您的应用程序,该构建会生成具有所需内容的nginx图像:
FROM your_angular_base AS build
COPY src /src
RUN steps to compile your code
FROM nginx_base as release
...
COPY --from=build /var/www/client/ /var/www/client/
...
然后将撰写文件简化为:
...
### NGINX Server #########################################
nginx:
image: registry.gitlab.com/***/***/***:staging
networks:
- frontend
- backend
networks:
backend:
frontend:
如果确实遇到需要在两个正在运行的容器之间共享卷,并且每次部署其中一个映像都需要更新该卷的情况,那么最好的方法是入口点脚本将文件从一个位置复制到卷中。我的docker-base中有一个使用save-volume
和load-volume
脚本的例子。