我是Go的新手,对于如何用自己的多个模块构建一个项目并在docker compose
中使用它们感到困惑。该项目目前是一个包含两个模块的git仓库:一个API和一个处理器,用于长时间运行的工作,每个都运行在自己的容器中。RabbitMQ用作两者之间的工作队列,还有一个MySQL数据库。
项目结构的简化视图:
├── api
│ ├── Dockerfile
│ └── stuff.go
├── docker-compose.yml
├── go.work
└── processor
├── Dockerfile
└── stuff.go
API Dockerfile(除了“api”是“processor”之外,处理器文件是相同的):
FROM golang:1.20
WORKDIR /usr/src/app
COPY go.mod go.sum ./
RUN go mod download && go mod verify
COPY . .
RUN go build -v -o /usr/local/bin/ ./...
CMD [ "api" ]
简化的docker-compose.yml:
version: '3.8'
services:
api:
build:
context: ./api
...
processor:
build:
context: ./processor
...
rabbitmq:
image: rabbitmq:3.11-management
...
mysql:
image: mysql:8.0
...
我用docker compose up --build
运行它,它工作得很好。问题是两个模块中有一些属于共享模块的重复代码,但我不知道如何在仍然能够在本地构建和工作的情况下做到这一点。
通过研究,我得到的印象是,我的模块应该在自己的存储库中。如果我这样做,似乎我需要为docker-compose.yml
创建一个“项目”存储库,然后为共享模块创建另一个。然后我更新docker-compose.yml
上下文,以指向在本地工作时克隆API和处理器项目的位置。
问题是共享模块没有Dockerfile
,也不是docker-compose.yml
中的服务。我假设Docker在构建时会go get
共享模块的内容,但我仍然希望能够在本地处理该代码,而不必首先提交并将其推送到origin。
1条答案
按热度按时间ux6nzvsh1#
我会在这里忽略Docker。
按照普通Go应用程序的方式排列文件系统树,按照计划打包和分发文件系统树。你应该能够使用普通的
go test
和go build
命令进行开发。听起来你有多个顶级命令围绕着一个共享代码库;将它们放在一个存储库中是有意义的,但是请记住,每个顶级命令都需要自己的目录。如果你有一个这样的设置,并且你想在Docker中运行它,重要的细节是你需要传递整个源代码树作为构建上下文目录。每个应用程序的Dockerfile是可以的,并且有一个参数可以将它放在与其顶级应用程序相同的目录中。但是当你在Compose中声明它时,你必须告诉它项目根目录是构建上下文。
我将
docker-compose.yml
文件放在项目根目录下,紧挨着go.mod
文件。它可能看起来像:您的Dockerfiles看起来基本上与您已经展示的一样。由于构建上下文是项目根,因此所有
COPY
命令都相对于项目根启动;另一方面,无论构建哪个应用程序,你都需要复制整个源代码树。对于Go,我几乎总是使用多阶段构建,以避免在最终图像中包含工具链。