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

2021-06-18 16:48:11 +08:00
 SimbaPeng

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

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 引入。

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

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

1797 次点击
所在节点    Go 编程语言
10 条回复
lance86
2021-06-18 17:31:22 +08:00
十几分钟也太久了,先问下你有没有做 build 时的缓存。也就是每个 app 的构建过程中的 go build 有没有都重新下载所有依赖。
sunny352787
2021-06-18 17:34:13 +08:00
为啥要打成镜像之后再用呢?直接用 golang 镜像然后映射 volumes 再修改 entrypoint 不就行了?
SimbaPeng
2021-06-18 17:36:49 +08:00
@lance86 COPY 所有代码之前会先 COPY go.mod 然后 go mod download,依赖是有缓存的
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
2021-06-18 17:42:26 +08:00
@sunny352787 额...格式...凑合看吧...
hellodudu86
2021-06-18 17:49:29 +08:00
你的目录结构和我的基本差不多,不过我不是开 golang 的容器来编译,要不就是本地交叉编译然后打包 docker 镜像,要不就是用代码托管的 ci 来跑打包,每次都 copy 进去感觉确实没有必要,挂载 volumn 把文件都映射进容器里面会比较好吧。
Vegetable
2021-06-18 17:58:41 +08:00
微服务翻车现场 /狗头

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

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

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

如果没有拆容器的必要个人肯定倾向于全在一个容器里跑,毕竟开发的时候容器的意义只是隔离一下 build toolchain,数据临时文件都是全部用外面挂进去的。而且我的开发容器一般用定制的,里面会多塞一些调试工具,只有发行版和 toolchain 版本会和生产环境保持一致。这个环境跑起来就拿它当虚拟机用基本上不停下来的,像你这种情况我尝试会让其它的 app build & run,然后单独 go run 在改的那个 app
JackyCDK
2021-06-20 15:08:24 +08:00
为啥不本机 GOOS=linux 然后 copy binary 进去呢(
loveuer
2021-06-20 22:00:58 +08:00
蹲一蹲,学习一下大家的做法

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

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

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

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

© 2021 V2EX