Search code examples
dockergoimportmodulelocal

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


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.


Solution

  • 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.