V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
dream4ever
V2EX  ›  Docker

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

  •  
  •   dream4ever · 2023-09-03 09:13:52 +08:00 · 2141 次点击
    这是一个创建于 445 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

    谢谢先。

    20 条回复    2023-09-06 18:54:06 +08:00
    thomaspaine
        1
    thomaspaine  
       2023-09-03 09:30:11 +08:00
    docker compose up 本来就可以滚动更新的啊

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

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

    不行,我这里镜像那边有更新,得先执行 docker-compose pull ,才会拉去最新镜像。
    thomaspaine
        7
    thomaspaine  
       2023-09-03 11:35:59 +08:00
    @daisyfloor 镜像如果是推送到 docker registery 的,确实要先 pull 一下,如果是本地 build 的那就不需要
    mritd
        8
    mritd  
       2023-09-03 11:55:23 +08:00
    1 、如果这个容器不那么重要, 或者说数据都有备份可以容忍一定时间的 down 机, 那么你可以用上面 V 友说的 `containrrr/watchtower` 来实现自动更新
    2 、容器内的日志你可以通过挂外部物理文件的形式实现保存
    3 、如果你对容器稳定性要求比较高, 最好考虑在 docker compose 中固定版本号, 并由自己手动升级; 因为上游更新有没有不兼容变动啥的都得你自己确认才行, 无脑更新有一定概率导致数据损坏和 down 机.
    4 、一般情况下, 生产环境都会交由 CI 工具来实现自动化, 楼主可以考虑用一些免费 CI 来实现一些自动化
    mikaelson
        9
    mikaelson  
       2023-09-03 12:05:22 +08:00
    @jaoyina #3 你们是根据提交来触发自动构建的吗?然后直接发布启动?不需要测试吗?我一直不太理解 jenkins 的流程,如果是捕捉 git 提交自动触发的话,那测试呢?万一提交的代码有问题,又自动构建下发部署下去了。。。所以这中间是不是还会有其他步骤?比如测试?测试完后,人工发布之类的?
    289396212
        10
    289396212  
       2023-09-03 12:29:10 +08:00
    Strapi 用起来怎么样?是真的全免费嘛?还是说哪个角落的功能暗戳戳得不给用
    zhleonix
        11
    zhleonix  
       2023-09-03 13:04:48 +08:00
    @mikaelson 都是要测试完成后再发布啊。测试环境的话你可以发布后再运行自动化测试,有问题自动回滚到上一次的版本。
    dayeye2006199
        12
    dayeye2006199  
       2023-09-03 13:49:41 +08:00
    日志土鳖点就挂个 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
        13
    dream4ever  
    OP
       2023-09-03 14:56:46 +08:00
    @289396212 Strapi 分社区版和企业版,就我这一个多月的使用印象来看,社区版提供的所有功能都是直接可用的。
    mikaelson
        14
    mikaelson  
       2023-09-03 15:42:50 +08:00
    @zhleonix #11 你的意思是,本地或者其他环境先测试,然后在提交触发 jenkins 自动部署吗?我好像还是没绕过来
    289396212
        15
    289396212  
       2023-09-03 15:45:05 +08:00
    @dream4ever 不会有用了多久等你依赖了就不让免费用的情况吗?然后社区版好像是只能创建三个还是几个角色,我可以通过改源码来解决这个限制吗?
    dream4ever
        16
    dream4ever  
    OP
       2023-09-03 16:22:51 +08:00
    @289396212 #15 第一个问题,社区版是可以部署在自己的服务区上的,即使它从某个版本开始完全不免费,那也可以使用它最后一个免费的社区版。

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

    如果在单独的测试环境,测试通过后,那是怎么触发到目标环境的?
    zhleonix
        20
    zhleonix  
       2023-09-06 18:54:06 +08:00
    @mikaelson Jenkins 或者其他工具都是由多个 Steps 组成的。添加一个部署任务指向目标环境就可以了啊。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2875 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 00:33 · PVG 08:33 · LAX 16:33 · JFK 19:33
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.