简体   繁体   中英

How to use go mod with local package and docker?

I have two go modules github.com/myuser/mymainrepo and github.com/myuser/commonrepo

Here is how i have the files in my local computer

- allmyrepos  
 - mymainrepo
   - Dockerfile
   - go.mod
 - commonrepo
   - go.mod

mymainrepo/go.mod

...
require (
  github.com/myuser/commonrepo
)

replace (
  github.com/myuser/commonrepo => ../commonrepo
)

It works well i can do local development with it. Problem happens when i'm building docker image of mymainrepo

mymainrepo/Dockerfile

...
WORKDIR /go/src/mymainrepo

COPY go.mod go.sum ./
RUN go mod download


COPY ./ ./
RUN go build -o appbinary
...

Here replace replaces github.com/myuser/commonrepo with ../commonrepo but in Docker /go/src/commonrepo does not exists.

I'm building the Docker image on CI/CD which needs to fetch directly from remote github url but i also need to do local development on commonrepo . How can i do both?

I tried to put all my files in GOPATH so it's ~/go/src/github.com/myuser/commonrepo and go/src/github.com/myuser/mymainrepo . And i removed the replace directive. But it looks for commonrepo inside ~/go/pkg/mod/... that's downloaded from github.

Create two go.mod files: one for local development, and one for your build. You can name it go.build.mod for example.

Keep the replace directive in your go.mod file but remove it from go.build.mod .

Finally, in your Dockerfile :

COPY go.build.mod ./go.mod
COPY go.sum ./

I still can't find other better solution even the voted answer doesn't work for me. Here a trick I've done that workaround for me. This is an example structure for doing this:

|---sample
|   |---...
|   |---go.mod
|   |---Dockerfile
|---core
|   |---...
|   |---go.mod
  1. We know that docker build error when it can't find our local module. Let's make one in the builder process:
# Use the offical golang image to create a binary.
# This is based on Debian and sets the GOPATH to /go.
# https://hub.docker.com/_/golang
FROM golang:1.16.3-buster AS builder

# Copy core library
RUN mkdir /core
COPY core/ /core

# Create and change to the app directory.
WORKDIR /app

# Retrieve application dependencies.
# This allows the container build to reuse cached dependencies.
# Expecting to copy go.mod and if present go.sum.
COPY go.* ./
RUN go mod download

# Copy local code to the container image.
COPY . ./

# Build the binary
RUN go build -o /app/sample cmd/main.go
...
...

Ok, our working dir is /app and our core lib placed next to it /core .

  1. Let's make a trick when build a docker image, Yeah. you know it.
cp -R ../core . && docker build --tag sample-service . && rm -R core/

Update A way better, create a Makefile next to Dockerfile , with content below:

build:
    cp -R ../core .
    docker build -t sample-service .
    rm -R core/

Then command, make build in the sample directory.

You can create make submit or make deploy commands as you like to.

=> Production ready!

Be aware that if there's an error occurs during docker build process, it won't delete back the core folder we have copied to sample .

Pls let me know if you find any better solution. ;)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM