Docker Compose构建报错:Go依赖模块缺失问题求助
[orders 7/7] RUN go build *.go:
0.359 main.go:9:2: no required module provides package github.com/dojeto/order-management-system/common; to add it:
0.359 go get github.com/dojeto/order-management-system/common
0.359 grpc_handler.go:7:2: no required module provides package github.com/dojeto/order-management-system/common/api; to add it:
0.359 go get github.com/dojeto/order-management-system/common/api
构建失败:进程"/bin/sh -c go build *.go"未成功完成,退出码:1
Dockerfile
FROM golang:1.22 WORKDIR /app COPY go.mod go.mod COPY go.sum go.sum RUN go mod download COPY . . RUN go build *.go ENTRYPOINT [ "./main" ]
Docker Compose文件
version: '3.8' services: mongodb: container_name: mongodb image: mongo networks: - my-network ports: - '27017:27017' volumes: - ./common:/app/common orders: container_name: orders build: context: ./orders dockerfile: Dockerfile networks: - my-network depends_on: - mongodb volumes: - ./common:/app/common gateway: container_name: gateway ports: - '8080:8080' build: context: ./gateway dockerfile: Dockerfile networks: - my-network volumes: - /home/dojeto/Projects/MicroServices/common:/app/common networks: my-network: driver: bridge volumes: dbdata6:
gateway和orders服务需使用common文件夹,但由于两个服务各自拥有独立Dockerfile,无法定位到common模块。请问该如何解决此问题?我希望在两个容器中都能使用common文件夹,确保服务正常运行。
解决方法
方法1:调整构建上下文,让Docker访问到common目录
当前orders和gateway的构建上下文是各自的子目录,导致构建时无法读取上级的common目录。修改Docker Compose中服务的build.context为项目根目录,同时指定子目录的Dockerfile:
# orders服务的build配置 build: context: . # 项目根目录作为构建上下文 dockerfile: orders/Dockerfile # gateway服务的build配置 build: context: . dockerfile: gateway/Dockerfile
然后修改对应服务的Dockerfile,适配根目录上下文:
FROM golang:1.22 WORKDIR /app # 复制当前服务的go.mod和go.sum COPY orders/go.mod orders/go.sum ./ RUN go mod download # 复制整个项目代码(包括common和当前服务) COPY . . # 进入服务目录执行构建 WORKDIR /app/orders RUN go build *.go ENTRYPOINT [ "/app/orders/main" ]
方法2:用Go模块replace指向本地common目录
在orders和gateway的go.mod文件中添加replace指令,将远程模块路径映射到本地common目录:
replace github.com/dojeto/order-management-system/common => ../common
这样go mod download会直接使用本地common代码,同时配合方法1的构建上下文调整,就能解决构建时的依赖问题。
方法3:多阶段构建,编译时打包common代码
如果不想调整构建上下文,可以用多阶段构建,在编译阶段把common目录复制到构建环境:
FROM golang:1.22 as builder WORKDIR /app # 复制当前服务的依赖文件 COPY orders/go.mod orders/go.sum ./ RUN go mod download # 复制当前服务代码和common代码 COPY orders/. . COPY common ../common # 编译二进制文件 RUN go build *.go # 用轻量镜像运行 FROM alpine:latest WORKDIR /app COPY --from=builder /app/main . ENTRYPOINT [ "./main" ]
这种方式会把common代码编译进二进制文件,运行时不需要挂载common目录,避免了运行时的依赖问题。
内容的提问来源于stack exchange,提问作者Dojeto

