Search code examples
dockergodockerfile

How to use the same dockerfile for dev and prod


I have 2 Dockerfile, 1 for dev, and 1 for prod:

PROD:

FROM golang AS builder
WORKDIR /go/src/gitlab.com/company/project
COPY . .
RUN go build -o ./release/api .

FROM scratch
EXPOSE 9999
COPY --from=builder /go/src/gitlab.com/company/project/release/api .
CMD ["./api"]

and DEV:

FROM golang
WORKDIR /go/src/gitlab.com/company/PROJECT
COPY . .
RUN go build -o ./release/api .
CMD ["./release/api"]

I would like to merge those two into a single one, as maintaining 2 Dockerfile is a bad practice

The main difference is that in dev, I work on golang image, which is practical, and in prod, I work with scratch image, which reduce a lot the size of my binary.

It seems that I can use multiple stages in a Dockerfile, and specify stage name at build time:

docker build . --target=builder

But If I do this, I don't know how to conditionally run my app in the first stage = [ If I am in dev, run the app in the first stage, otherwise, run the app in the second stage]

How should I do it ?


Solution

  • What about something like this? I didn't test it and didn't think through your example deeply, but maybe is somewhere close to what you need/helps you finding out the final solution?

    FROM golang:alpine AS base
    WORKDIR /go/src/gitlab.com/company/project
    COPY . .
    RUN go build -o ./release/api .
    
    FROM base AS dev
    CMD ["./release/api"]
    
    FROM scratch AS prod
    EXPOSE 9999
    COPY --from=base /go/src/gitlab.com/company/project/release/api .
    CMD ["./api"]
    

    Depending on the value specified in target docker build --target=prod or docker build --target=dev, a different image will get built.