Reputation: 1085
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
...
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
...
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.
Upvotes: 7
Views: 7870
Reputation: 1736
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
# 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
.
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. ;)
Upvotes: 5
Reputation: 2262
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 ./
Upvotes: 5