Docker compose 容器的更新及日志持久化问题

253 天前
 dream4ever

最近在阿里云的 Ubuntu 服务器上成功配置了在 Docker 中运行的 Strapi ,对我这个全干工程师来说很方便,常见的 CRUD 需求都能满足,节省了很多写后端代码的时间。

由于对 Docker 不太熟悉,现在遇到了两个问题:

  1. Strapi 的代码有更新的时候,让 Docker 编译新镜像、运行新容器的最佳实践是什么?我目前是在项目目录下执行 docker compose down,然后再执行 docker compose up,这样能够确保新生成的镜像是基于最新的代码。有没有别的更简洁优雅的方式,让 Docker 自己删除旧的镜像、生成新的镜像,然后启动容器?
  2. 用上面的 docker compose down + docker compose up 的方式删除旧的镜像、生成新的镜像之后,用旧镜像启动的容器的日志就没有了,有什么好的方式,能够把容器的镜像持久化保存下来?

谢谢先。

1866 次点击
所在节点    Docker
20 条回复
thomaspaine
253 天前
docker compose up 本来就可以滚动更新的啊

日志你可以用 volume 参数映射出来
seth19960929
253 天前
服务用 docker 有两种运行方式.
1. 脚本语言, python, node, php. 直接把代码 volumn 挂载到容器里面. 你直接照常写日志. 容器≈环境
. 只有当需要新的扩展, 比如要安装 redis 扩展之类的. 每次更新只有 git pull, 然后看重启容器就可以

2. 编译语言, 直接便于成二进制文件到容器里运行. 容器≈可执行文件
jaoyina
253 天前
第一个问题我们项目上一般是结合 jenkins ,有代码改动提交,自动建镜像再发布,启动。
第二个问题把日志目录挂载出来就持久化了,可以在 docker-compose.yml 配置。
lsk569937453
253 天前
1.更新镜像后,直接 docker compose up -d 就能更新服务了(镜像没变的不会重启)。docker compose down 是关闭所有的服务。
2.使用 volume 把磁盘目录和容器目录映射一下就行了。
volumes:
- ./logs:/home/logs
把容器的/home/logs 映射到当前的 logs 目录
fanxasy
252 天前
一次性更新所有容器:
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower --cleanup --run-once --include-stopped
daisyfloor
252 天前
@thomaspaine

不行,我这里镜像那边有更新,得先执行 docker-compose pull ,才会拉去最新镜像。
thomaspaine
252 天前
@daisyfloor 镜像如果是推送到 docker registery 的,确实要先 pull 一下,如果是本地 build 的那就不需要
mritd
252 天前
1 、如果这个容器不那么重要, 或者说数据都有备份可以容忍一定时间的 down 机, 那么你可以用上面 V 友说的 `containrrr/watchtower` 来实现自动更新
2 、容器内的日志你可以通过挂外部物理文件的形式实现保存
3 、如果你对容器稳定性要求比较高, 最好考虑在 docker compose 中固定版本号, 并由自己手动升级; 因为上游更新有没有不兼容变动啥的都得你自己确认才行, 无脑更新有一定概率导致数据损坏和 down 机.
4 、一般情况下, 生产环境都会交由 CI 工具来实现自动化, 楼主可以考虑用一些免费 CI 来实现一些自动化
mikaelson
252 天前
@jaoyina #3 你们是根据提交来触发自动构建的吗?然后直接发布启动?不需要测试吗?我一直不太理解 jenkins 的流程,如果是捕捉 git 提交自动触发的话,那测试呢?万一提交的代码有问题,又自动构建下发部署下去了。。。所以这中间是不是还会有其他步骤?比如测试?测试完后,人工发布之类的?
289396212
252 天前
Strapi 用起来怎么样?是真的全免费嘛?还是说哪个角落的功能暗戳戳得不给用
zhleonix
252 天前
@mikaelson 都是要测试完成后再发布啊。测试环境的话你可以发布后再运行自动化测试,有问题自动回滚到上一次的版本。
dayeye2006199
252 天前
日志土鳖点就挂个 volume ,写到这个位置上。高级点,就弄个 fluentd ,然后就可以随便导出到各种地方。

docker compose 其实不擅长做你说的那种滚动。你需要的是类似 swarm ,k8s 这样的容器编排软件。
docker compose 强行弄的话大致是
1. docker pull 最新的版本
2. docker-compose up -d --scale backend=2 --no-recreate 增加一个新的副本(用的新版本)
3. docker stop 旧 的容器。
4. docker-compose up -d --scale backend=1 --no-recreate 回到刚才的副本数目
dream4ever
252 天前
@289396212 Strapi 分社区版和企业版,就我这一个多月的使用印象来看,社区版提供的所有功能都是直接可用的。
mikaelson
252 天前
@zhleonix #11 你的意思是,本地或者其他环境先测试,然后在提交触发 jenkins 自动部署吗?我好像还是没绕过来
289396212
252 天前
@dream4ever 不会有用了多久等你依赖了就不让免费用的情况吗?然后社区版好像是只能创建三个还是几个角色,我可以通过改源码来解决这个限制吗?
dream4ever
252 天前
@289396212 #15 第一个问题,社区版是可以部署在自己的服务区上的,即使它从某个版本开始完全不免费,那也可以使用它最后一个免费的社区版。

第二个问题我 Google 了一下,这是 4.8 版本之前才有的限制,在这之后社区版已经没有创建角色数量的限制了,可以看这里: https://strapi.io/blog/custom-roles-and-permissions-available-for-free-in-strapi-v4-8
zhleonix
250 天前
@mikaelson 本地的测试应该是在 CI 部分完成了。部署阶段的测试是对应用的集成测试甚至 E2E 的测试。一般会有两种选择:
- 有单独的测试环境,那就可以部署到单独测试环境中测试后再部署到目标环境。
- 需要在目标环境中直接测试,这时候要在测试失败情况下回滚版本。
jaoyina
249 天前
@mikaelson 也不是完全根据代码提交就触发,提交后还要更新下版本配置才会触发重新发布。
mikaelson
249 天前
@zhleonix #17
- 有单独的测试环境,那就可以部署到单独测试环境中测试后再部署到目标环境。

如果在单独的测试环境,测试通过后,那是怎么触发到目标环境的?
zhleonix
249 天前
@mikaelson Jenkins 或者其他工具都是由多个 Steps 组成的。添加一个部署任务指向目标环境就可以了啊。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/970468

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX