Is there a way to set up multiple Local Go Modules, so they can run inside one Docker container without pulling from Github?

huangapple go评论98阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2021年9月5日 07:04:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/69059470.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定