英文:
Is there a way to set up multiple Local Go Modules, so they can run inside one Docker container without pulling from Github?
问题
所以我的目标是在多个Docker容器中设置一个本地开发环境,其中包含多个独立的Go服务(作为独立模块),以及一个所有服务都可以使用的Go模块,用于启动一个新的服务并连接到数据库等,而不需要在每个模块/服务中重复这段代码。
所以我的目录结构看起来像这样(在$GOPATH/src/github.com/name/backend/中):
|--services
| |--service1
| |--Dockerfile
| |--main.go
| |--go.mod
| |--service2
| |--Dockerfile
| |--main.go
| |--go.mod
|--serviceHelper
| |--serviceHelper.go
| |--go.mod
我的Dockerfile目前只是一个普通的Go Dockerfile:
FROM golang:alpine AS build-env
WORKDIR /backend
ADD . /backend
RUN cd /backend && go build -o service1
FROM alpine
RUN apk update && \
apk add ca-certificates && \
update-ca-certificates && \
rm -rf /var/cache/apk/*
WORKDIR /backend
COPY --from=build-env /backend/service1 /backend
EXPOSE 8080
ENTRYPOINT ["./service1"]
我的go.mod文件也只是:
module github.com/name/backend/services/service1
go 1.17
然而,我现在遇到的问题是,你要么必须从GitHub存储库中拉取一个模块,这是我不想要的,要么必须将serviceHelper代码放在每个服务的每个模块中,这也是我不想要的。
我使用VSCode工作,并且已经了解到你必须将单个模块放入单个工作区文件夹中。但是,我无法成功地在本地配置模块,以便在一个服务中同时导入普通包(如github.com/gorilla/mux
)和我的本地包。我使用的是Apple M1,希望这也不会引起问题。
我需要如何配置go.mod文件、Docker文件和Go导入,以便我可以在编辑器中正常调试Go(即serviceHelper模块不仅仅直接加载到Docker容器中),并且在本地运行所有内容而不必从github获取serviceHelper?
更新:
我已经尝试了很多变体,但是对于这个变体(谢谢你的回答colm.anseo),我得到了最少的错误消息,但它仍然尝试连接到github,这是我不想要的。
所以更新后的go.mod文件如下:
module github.com/name/backend/services/service1
go 1.17
require (
github.com/name/backend/serviceHelper v1.0.0
github.com/gorilla/mux v1.8.0
)
replace github.com/name/backend/serviceHelper => ../../serviceHelper
然后,当我尝试使用go mod tidy
构建一个新的go.sum时,会出现以下错误(这就是我所说的“并且在本地运行所有内容而不必从github获取serviceHelper”的错误,因为我之前就遇到过这个错误):
github.com/name/backend/servicehelper: cannot find module providing package github.com/name/backend/servicehelper: module github.com/name/backend/servicehelper: git ls-remote -q origin in /Users/myName/go/pkg/mod/cache/vcs/...: exit status 128:
ERROR: Repository not found.
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
我不希望它连接到github,我只想在本地运行它。在colm.anseo的回答的帮助下,我认为我知道如何创建一个可工作的Dockerfile,所以这不再是一个问题。
英文:
So my goal is to set up a local development environment with multiple Go services (all as independent modules) running in multiple docker containers and one Go module, which all services can use to start a new service with connection to the database etc. without repeating this code in every module/service.
So my structure would look something like that (in $GOPATH/src/github.com/name/backend/):
|--services
| |--service1
| |--Dockerfile
| |--main.go
| |--go.mod
| |--service2
| |--Dockerfile
| |--main.go
| |--go.mod
|--serviceHelper
| |--serviceHelper.go
| |--go.mod
My Dockerfile currently is just a plain Dockerfile for Go:
FROM golang:alpine AS build-env
WORKDIR /backend
ADD . /backend
RUN cd /backend && go build -o service1
FROM alpine
RUN apk update && \
apk add ca-certificates && \
update-ca-certificates && \
rm -rf /var/cache/apk/*
WORKDIR /backend
COPY --from=build-env /backend/service1 /backend
EXPOSE 8080
ENTRYPOINT ["./service1"]
My go.mod file also is just:
module github.com/name/backend/services/service1
go 1.17
The problem I'm having now though is that you either have to pull a module from a github repository, which I don't want to do, or put the serviceHelper code in every single module for the services, which I don't want to do either.
I work with VSCode and have since learned that you have to put single modules into single workspace folders. Still I can't manage to configure the modules locally to import both normal packages like github.com/gorilla/mux
and also my local package in one service. I work with an Apple M1, I hope that might not cause problems as well.
How do I need to configure the go.mod files, the Docker files and the Go imports so that I can both debug Go normally in the editor (i.e. that the serviceHelper module is not just loaded into the Docker container directly), and also run everything locally without having to source the serviceHelper from github?
Update:
I already tried a lot of variants, but with this one (thank you for your answer colm.anseo), I got the least error messages but it still tries to connect to github, which I don't want.
So the updated go.mod file looks like:
module github.com/name/backend/services/service1
go 1.17
require (
github.com/name/backend/serviceHelper v1.0.0
github.com/gorilla/mux v1.8.0
)
replace github.com/name/backend/serviceHelper => ../../serviceHelper
When I then try to build a new go.sum with go mod tidy
, this error occures (and that's the error I meant with "and also run everything locally without having to source the serviceHelper from github", because I got this error before):
github.com/name/backend/servicehelper: cannot find module providing package github.com/name/backend/servicehelper: module github.com/name/backend/servicehelper: git ls-remote -q origin in /Users/myName/go/pkg/mod/cache/vcs/...: exit status 128:
ERROR: Repository not found.
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
I don't want it to connect to github, I just want it to run locally. With the help of the answer from colm.anseo I think I know how to create a working Dockerfile, so that's not a concern anymore.
答案1
得分: 2
替换 github.com/name/backend/serviceHelper
为 ../../serviceHelper
。
...
github.com/name/backend/servicehelper
:找不到模块。
导入是区分大小写的。我建议在导入、替换语句和要导入的包的 go.mod 文件中都使用小写。
英文:
replace github.com/name/backend/serviceHelper => ../../serviceHelper
...
github.com/name/backend/servicehelper: cannot find module
Imports are case sensitive. I'd recommend making everything lower case, in your import, the replace statement, and the go.mod file of the package you're importing.
答案2
得分: 0
如果你还没有准备好将代码发布到互联网的git仓库(比如github.com
),你可以在你的go.mod
文件中使用replace指令:
module github.com/me/my_app
go 1.17
require (
github.om/gorilla/handlers v1.5.1
github.com/me/my_srv1
)
replace github.com/me/my_srv1 => ./my_srv1
在你的Go代码中,你可以像导入来自互联网的代码一样导入这段代码:
// go代码
import (
"github.om/gorilla/handlers"
"github.com/me/my_srv1"
)
在Docker环境中,你需要确保./my_srv1
目录被复制并且在与go build
相同的相对路径下可访问。
go build
结合go.mod
将从互联网上拉取gorilla/mux
包,但会使用本地开发目录作为(尚未发布的)仓库的替代品。
英文:
If you are not ready to publish your code to an internet git repo (like github.com
) you can use the replace directive in your go.mod
:
module github.com/me/my_app
go 1.17
require (
github.om/gorilla/handlers v1.5.1
github.com/me/my_srv1
)
replace github.com/me/my_srv1 => ./my_srv1
in your Go code you can import this code as if it came from the internet:
// go code
import (
"github.om/gorilla/handlers"
"github.com/me/my_srv1"
)
In your Docker context you will have to make sure the directory ./my_srv1
is copied and accessible in the same relative path as your go build
.
go build
in conjunction with the go.mod
will then pull the gorilla/mux
package from the internet - but use the local development directory as a substitute for your (yet to be published) repo.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论