How do I get go build
command in Docker to use module cache or vendor directory on every build unless the dependencies have changed?
I've tried both of these approaches with inconsistent results:
How can I persist go 1.11 modules in a Docker container? ^ this doesn't work, I believe because I'm using the Docker "builder" pattern.
https://medium.com/@monirz/golang-dependency-solution-with-go-module-and-docker-8967da6dd9f6 ^ this should work, but just doesn't for some reason...
I'm working on a server and for every little change I make to the go source code it makes sense that I need to recompile, but it does not make sense that that step should then also have to re-download all the dependencies again, every time.
I am building this server as a go module
, here is my current Dockerfile:
FROM golang:1.14 AS builder
# Add the source
WORKDIR /app
COPY . .
# Statically compile our app for use in a distroless container
RUN CGO_ENABLED=0 go build -mod vendor -ldflags="-w -s" -v -o app .
# A distroless container image with some basics like SSL certificates
# https://github.com/GoogleContainerTools/distroless
FROM gcr.io/distroless/static
# Copy over binary and words dir
COPY --from=builder /app/app /app
ENTRYPOINT ["/app"]
I've also tried adding the -mod=vendor
flag to the go command and it doesn't alter the behavior... which it should already be using that flag automatically anyway if 1.14 detects vendor dir in the module path (which is there).
The vendor file was being used, it just didn't seem like it because although it was not re-downloading all modules on build it was re-building them on every build. The issue appears to be trying to use the builder pattern, I have altered my development compose file to handle everything in the compose yaml and will reserve the builder pattern Dockerfile for production (where it only really matters anyway).
Now using the following my development builds are way faster and don't appear to recompile every module on every build:
docker-compose.yaml
version: "3.7"
services:
nginx:
container_name: nginx
image: nginx:alpine
restart: unless-stopped
ports:
- 8000:80
depends_on:
- api
volumes:
- ./container_spec/nginx.conf:/etc/nginx/nginx.conf
- ./container_spec/cors_support:/etc/nginx/cors_support
api:
image: golang:1.14
container_name: api
restart: always
working_dir: /app
volumes:
- .:/app
- cache:/go
expose:
- 8080
command: go run main.go
volumes:
cache: