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

docker 如何更便捷的更新容器

  •  
  •   echooo0 · 2022-11-13 20:24:36 +08:00 · 3393 次点击
    这是一个创建于 742 天前的主题,其中的信息可能已经有所发展或是发生改变。

    版本迭代快的时候,docker 构建推送镜像很麻烦,下载上传整个镜像的数据很耗时间,

    实际上改动的就是核心系统代码那一块,其他外部依赖没有动

    所以,想把更新代码的步骤放到启动脚本里面去做,然后通过参数来设定,在 docker 启动的时候判断是否执行更新代

    码的步骤,不知道这样是否可行

    试了下 CMD 和 ENTRYPOINT , 在 docker run image_name -k (启动参数) 这样添加参数后,好像启动参数被固定了,

    docker start 的时候不能灵活的修改,是否添加启动参数了

    15 条回复    2022-11-15 10:44:25 +08:00
    shiny
        1
    shiny  
       2022-11-13 20:31:32 +08:00
    换个思路,让外部依赖能被缓存。比如 nodejs 使用 multi-stage build 后,package.json 如果没动过,这部分就会直接缓存。
    beginor
        2
    beginor  
       2022-11-13 21:08:47 +08:00 via Android
    搭 registry 私服,先推一个基础镜像上去, 比如 nodejs ,java spring , 然后再基于基础镜像编译 app 镜像
    chiuan
        3
    chiuan  
       2022-11-13 22:44:39 +08:00
    程序镜像一般都不大吧。。。推送一下还能费几秒?
    julyclyde
        4
    julyclyde  
       2022-11-14 09:18:12 +08:00
    建议参考一下“immutable”这个概念,别在容器内做运行时更新

    docker image 本身是分层的。你在 build 的时候安排一下顺序,把变动的放在最上层就能减少很多浪费了
    palytoxin
        5
    palytoxin  
       2022-11-14 09:24:38 +08:00
    之前离线部署过个 2g 的 ruby python 加一些依赖 c++库的混合镜像,镜像基本不变,部署时候把目录挂进去就行,你要多机部署就搞个 nfs
    ragnaroks
        6
    ragnaroks  
       2022-11-14 09:31:53 +08:00
    #4 说得对,你打包镜像应当最后一步才是 copy 编译产物,那么当你的业务机器有上一次的镜像时,拉取最新镜像只会拉取最终不同的那一层,基本上也就是你的编译产物的体积
    ragnaroks
        7
    ragnaroks  
       2022-11-14 09:34:09 +08:00
    FROM builder
    ......
    COPY builder/artifact /app
    WORKDIR /app
    ENTRYPOINT /app/file

    一般保持 CMD 空白用于运行时提供不同的参数
    simonlu9
        8
    simonlu9  
       2022-11-14 09:34:50 +08:00
    可以把依赖库和核心代码分离出来,比如 sprintboot 可以把 lib 不打包到镜像,只打包核心代码就可以
    Latin
        9
    Latin  
       2022-11-14 10:12:34 +08:00
    @julyclyde 针对需要依赖安装类的镜像 COPY 应放置最下层
    libook
        10
    libook  
       2022-11-14 11:20:59 +08:00
    有些镜像比如 TTRSS 是在镜像内部的启动脚本更新代码,镜像本身就是个壳子,但每次启动都更新代码时间有点长,如果你不需要启动即可快速使用的话就可以考虑。

    另外现在通常配合容器都会使用 CI 自动构建和自动部署,镜像规划好 Layer 也可以省很多时间和空间。
    baleeny
        11
    baleeny  
       2022-11-14 12:19:26 +08:00
    4 楼+1
    echooo0
        12
    echooo0  
    OP
       2022-11-14 12:43:27 +08:00
    @libook #10 所以我想的是,通过参数来指定,是否启动的时候执行更新代码的步骤。

    但是 docker run image_name -k (启动参数) 这样添加参数后,启动参数好像被固定了,docker start 不能改变是否添加这个参数
    julyclyde
        13
    julyclyde  
       2022-11-14 14:47:46 +08:00
    @echooo0 是啊,你的程序应该适应无监管启动的场景
    sdwgyzyxy
        14
    sdwgyzyxy  
       2022-11-15 08:48:00 +08:00
    核心应该是编译+部署分开,例如 golang ,编译环境非常大,而项目真实运行的就是 build 之后的那个文件,很小很小。
    rainfd
        15
    rainfd  
       2022-11-15 10:44:25 +08:00
    容器不复杂的可以用 ko 编译构建,或者直接使用 skaffold 本地 Ci
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3613 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 11:02 · PVG 19:02 · LAX 03:02 · JFK 06:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.