V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
SimbaPeng
V2EX  ›  Go 编程语言

关于 docker-compose 搭建 golang 本地开发环境的问题

  •  
  •   SimbaPeng · 2021-06-18 16:48:11 +08:00 · 1912 次点击
    这是一个创建于 1277 天前的主题,其中的信息可能已经有所发展或是发生改变。

    目前公司的项目结构大致如下:

    project
    ├── Makefile
    ├── README.md
    ├── apps
    │   ├── app1
    │   ├── app2
    │   ├── app3
    │   ├── app4
    │   ├── app5
    │   └── app6
    ├── conf
    ├── config
    ├── mods
    ├── db
    ├── docker-compose.dev.yml
    ├── docker-compose.yml
    ├── go.mod
    ├── go.sum
    ├── helper
    ├── message
    └── utils
    

    多个 app 共用一个 go.mod 管理,也共享外面的公共类库。

    每个 app 目录下只包含一个简单 main 函数启动服务,大部分的业务逻辑都写在 mods 目录下的对应的模块 package 下,每个模块 package 可能会被多个 app 导入。

    整个项目需要所有的 app 服务都启动,目前我是用 docker-compose 把每个 app 都单独打入一个镜像编译并运行。 每个镜像我都把整个项目 COPY 进去编译,只忽略了 apps 目录。

    现在问题是,当我修改 mods 或其他共享 package 的代码时,再 docker-compose build 会导致所有镜像都从 COPY 开始缓存失效,导致所有 app 都重新编译,不管我修改的地方有没有被这个 app 引入。

    一个很小的改动都需要十几分钟才能看效果,真是太难受了。。。

    不知道大家都是怎么搭建本地开发环境的?

    10 条回复    2021-06-20 22:00:58 +08:00
    lance86
        1
    lance86  
       2021-06-18 17:31:22 +08:00
    十几分钟也太久了,先问下你有没有做 build 时的缓存。也就是每个 app 的构建过程中的 go build 有没有都重新下载所有依赖。
    sunny352787
        2
    sunny352787  
       2021-06-18 17:34:13 +08:00
    为啥要打成镜像之后再用呢?直接用 golang 镜像然后映射 volumes 再修改 entrypoint 不就行了?
    SimbaPeng
        3
    SimbaPeng  
    OP
       2021-06-18 17:36:49 +08:00
    @lance86 COPY 所有代码之前会先 COPY go.mod 然后 go mod download,依赖是有缓存的
    sunny352787
        4
    sunny352787  
       2021-06-18 17:41:55 +08:00
    version: '3'
    services:
    app1:
    image: golang:latest
    ports:
    - "81:80"
    expose:
    - "80"
    restart: always
    environment:
    TZ: "Asia/Shanghai"
    volumes:
    - "./:/project"
    working_dir: /project
    entrypoint: ["/bin/bash", "/project/run1.sh"]

    app2:
    image: golang:latest
    ports:
    - "82:80"
    expose:
    - "80"
    restart: always
    environment:
    TZ: "Asia/Shanghai"
    volumes:
    - "./:/project"
    working_dir: /project
    entrypoint: ["/bin/bash", "/project/run2.sh"]


    类似这种写法
    sunny352787
        5
    sunny352787  
       2021-06-18 17:42:26 +08:00
    @sunny352787 额...格式...凑合看吧...
    hellodudu86
        6
    hellodudu86  
       2021-06-18 17:49:29 +08:00
    你的目录结构和我的基本差不多,不过我不是开 golang 的容器来编译,要不就是本地交叉编译然后打包 docker 镜像,要不就是用代码托管的 ci 来跑打包,每次都 copy 进去感觉确实没有必要,挂载 volumn 把文件都映射进容器里面会比较好吧。
    Vegetable
        7
    Vegetable  
       2021-06-18 17:58:41 +08:00
    微服务翻车现场 /狗头

    为什么你编译要这么久,时间花在哪了啊。十几分钟也太久了,我 java 项目从头开始 maven install 都没这么久。

    我的经验是,ci 里边的 go 项目使用 vendor,避免容器 go get 浪费时间。然后打包的话用 volume,这样修改代码镜像不受影响了
    GeruzoniAnsasu
        8
    GeruzoniAnsasu  
       2021-06-18 19:28:53 +08:00
    emmm 本地环境从来都是挂代码进去在里面编译的

    不知道你们的微服务怎么起要不要 etcd 还是能一个 standalone 的 binary 自交(

    如果没有拆容器的必要个人肯定倾向于全在一个容器里跑,毕竟开发的时候容器的意义只是隔离一下 build toolchain,数据临时文件都是全部用外面挂进去的。而且我的开发容器一般用定制的,里面会多塞一些调试工具,只有发行版和 toolchain 版本会和生产环境保持一致。这个环境跑起来就拿它当虚拟机用基本上不停下来的,像你这种情况我尝试会让其它的 app build & run,然后单独 go run 在改的那个 app
    JackyCDK
        9
    JackyCDK  
       2021-06-20 15:08:24 +08:00
    为啥不本机 GOOS=linux 然后 copy binary 进去呢(
    loveuer
        10
    loveuer  
       2021-06-20 22:00:58 +08:00
    蹲一蹲,学习一下大家的做法
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1212 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 23:53 · PVG 07:53 · LAX 15:53 · JFK 18:53
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.