Go 1.14 Modules Build Command Ignoring Vendor Dir in Docker

2k Views Asked by At

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

1

There are 1 best solutions below

0
DjH On BEST ANSWER

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: