tilt-dev / tilt

Define your dev environment as code. For microservice apps on Kubernetes.
https://tilt.dev/
Apache License 2.0
7.66k stars 301 forks source link

Multi-stage docker build fails within Tilt #3146

Closed MadOtis closed 4 years ago

MadOtis commented 4 years ago

When trying to on-board Tilt to an existing project with a Multi-stage Docker build, Tilt seems to be unaware of the current directory, causing the Docker build to fail. The following Dockerfile works exactly as it should when used to build from CLI, script file, Gitlab pipeline, etc, but fails within Tilt:

FROM golang:1.13-buster as build
WORKDIR /go/src/app
ADD ./src/ /go/src/app

RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o bin/app

FROM gcr.io/distroless/base-debian10

COPY --from=build /go/src/app/bin/app /
ENV OTHERAPP_URL=https://otherapp.mycompany.net/api/v1
ENV OTHERAPP_TOKEN=HARD_CODED_TOKEN
CMD ["/app"]

results in (within Tilt environment)

STEP 1/3 — Building Dockerfile: [app/app]
Building Dockerfile:
  FROM golang:1.13-buster as build
  WORKDIR /go/src/app
  ADD ./src/ /go/src/app

  RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o bin/app

  FROM gcr.io/distroless/base-debian10

  COPY --from=build /go/src/app/bin/app /
  ENV OTHERAPP_URL=https://otherapp.mycompany.net/api/v1
  ENV OTHERAPP_TOKEN=HARD_CODED_TOKEN
  CMD ["/app"]

     Tarring context…
     Building image
     copy /context / [done: 115ms]
     [stage-1 1/2] FROM gcr.io/distroless/base-debian10
     [build 1/4] FROM docker.io/library/golang:1.13-buster
     [build 2/4] WORKDIR /go/src/app [cached]
     [build 3/4] ADD ./src/ /go/src/app

     ERROR IN: [build 3/4] ADD ./src/ /go/src/app

Build Failed: ImageBuild: "/src" not found

versus via CLI:

❯ docker build -t app/app .
Sending build context to Docker daemon  50.04MB
Step 1/9 : FROM golang:1.13-buster as build
 ---> 6586e3d10e96
Step 2/9 : WORKDIR /go/src/app
 ---> Using cache
 ---> 6906ce9364bf
Step 3/9 : ADD ./src/ /go/src/app
 ---> Using cache
 ---> f3f164552609
Step 4/9 : RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o bin/app
 ---> Using cache
 ---> 57634e157a24
Step 5/9 : FROM gcr.io/distroless/base-debian10
 ---> d48fcdd54946
Step 6/9 : COPY --from=build /go/src/app/bin/app /
 ---> Using cache
 ---> 9de6021ded31
Step 7/9 : ENV OTHERAPP_URL=https://otherapp.mycompany.net/api/v1
 ---> Using cache
 ---> d47cfa7ba932
Step 8/9 : ENV OTHERAPP_TOKEN=HARD_CODED_TOKEN
 ---> Using cache
 ---> f233e19dcca4
Step 9/9 : CMD ["/app"]
 ---> Using cache
 ---> dbe0d5466c85
Successfully built dbe0d5466c85
Successfully tagged app/app:latest
landism commented 4 years ago

Hi!

I unfortunately wasn't able to repro this - Tilt built your Dockerfile successfully on my machine. Is it possible your Tiltfile's docker_build is using ignore or only to filter out src? We've seen some people using those parameters unaware that they affect what goes into the docker build context.

MadOtis commented 4 years ago

I started from a working K8S project that does deploy and build from CLI or via a GitLab CI/CD pipeline; the goal was to learn about Tilt and see how it would help local development; so, basically, my Tiltfile really only contains mostly what the 15 minute tutorial starts you off with. However, here is my full Tiltfile:

print('My App Tiltfile')
k8s_yaml(['deploy/service-account.yaml','deploy/operator.yml'])
docker_build('app/app', 'app', dockerfile="./Dockerfile")

A few particulars, just in case they might be relevant: Docker version 19.03.8, build afacb8b MacOS Catalina 10.15.4 Tilt v0.12.10, built 2020-03-26

nicks commented 4 years ago

It's worth pointing out that if your Tiltfile has:

docker_build('app/app', 'app', dockerfile="./Dockerfile")

The second argument is the Docker context. So that corresponds to the CLI invocation:

docker build -t app/app -f Dockerfile ./app

is that what you intended? From the CLI repro step in your first comment, it sounds like you intended:

docker_build('app/app', '.')
MadOtis commented 4 years ago

Perhaps I need to RTFM a little more thoroughly... Yep, that was the solution. For some reason I interpreted the second argument as the actual name of the container itself and not the directory to look for the Dockerfile in. Closing this.

nicks commented 4 years ago

No worries...Tilt should also do a better job about communicating what's in the docker context instead of making people guess :)

Jleagle commented 1 year ago

Hi!

I unfortunately wasn't able to repro this - Tilt built your Dockerfile successfully on my machine. Is it possible your Tiltfile's docker_build is using ignore or only to filter out src? We've seen some people using those parameters unaware that they affect what goes into the docker build context.

Thanks! This was it for me. The docs make it sounds like only are the files that can trigger the live_update.