Reputation: 147
How can I add local dependencies from a folder within the same Go project?
I have the following directory structure:
.
├── backend
│ ├── Dockerfile
│ ├── conduit
│ │ └── get_data.go
│ ├── main.go
│ ├── main_test.go
│ ├── storage
│ │ ├── create_client.go
│ │ └── read_data.go
├── cron_job
│ ├── Dockerfile
│ ├── main.go
│ └── main_test.go
And Dockerfile:
FROM golang:1.10.1 as builder
ADD . github.com/dalderman77/phacts/backend/conduit
ADD . github.com/dalderman77/phacts/backend/storage
WORKDIR /go/src/github.com/dalderman77/phacts/cron_job
# Get dependencies
RUN go get -d -v cloud.google.com/go/datastore golang.org/x/net/context
COPY . .
# Compile Go binary
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .
# Create smaller lightweight container
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
# Copy binary from previous stage
COPY --from=builder /go/src/github.com/dalderman77/phacts/cron_job/main .
CMD ["./main"]
What I have so far is based on Use multi-stage builds
The issue is that compiled binary is dependent on code from the backend directory. It compiles fine locally but I am unsure how to correctly add these dependencies so they can be compiled within the container:
main.go:9:2: cannot find package "github.com/dalderman77/phacts/backend/conduit" in any of:
/usr/local/go/src/github.com/dalderman77/phacts/backend/conduit (from $GOROOT)
/go/src/github.com/dalderman77/phacts/backend/conduit (from $GOPATH)
main.go:10:2: cannot find package "github.com/dalderman77/phacts/backend/storage" in any of:
/usr/local/go/src/github.com/dalderman77/phacts/backend/storage
Upvotes: 0
Views: 1683
Reputation: 51
In Dockerfile this command is used to compile your code:
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .
This will make your binary static, allowing you to perform second step of your build, since you can now start with tiny image (alpine in your case, but you can even try using empty image) without relying on any dependency inside your container.
In your example, you're adding ca-certificates to the final image:
RUN apk --no-cache add ca-certificates
You may need this in case you're making HTTPS requests in your application, since alpine container doesn't have any certificates inside its file system. In general, any static assets required for your application (e.g. images, html/email templates, scripts etc.) must be added to resulting image via COPY or ADD command.
Also please have a look at this outstanding guide on how to build minimal docker containers.
Edit: Your problem with the build happens because cron_job
can't locate packages from backend
, since you don't copy backend
to the container in the correct $GOPATH folder. To solve this problem, you need to vendor your dependencies using dependency manager tool. The current official one is dep.
Restoring dependencies for cron_job
(locally on your machine, NOT inside your container) will create vendor
subfolder, where every needed dependency for your project will be stored. Now when you copy cron_job
to the container, build will also look at vendor
folder to check for missing dependencies.
Upvotes: 2