I am newbie to docker and trying to explore multistage build. I want to run a specific stage on docker docker build -t build-stage-tag --target build
I expect it to run the following stages dependencies --> compile --> build
and skip the test
. But it so happens that it runs the test stage as well.
Let me know if my understanding of multistage build --target
is wrong or there is some error in my docker file.
What I want to do is run the build
stage without running the test
and vice-versa.
This is how my Dockerfile looks :
# Pull base image
FROM openjdk:8u171 as dependencies
# Install Scala
## Piping curl directly in tar
// do some stuff
# Copy source into container
COPY . /usr/src/app
FROM dependencies as compile
WORKDIR /usr/src/app
# Test and build the jar in the same step to save time
RUN sbt -Dsbt.log.noformat=true compile
RUN sbt -Dsbt.log.noformat=true assembly
FROM compile as test
WORKDIR /usr/src/app
RUN sbt -Dsbt.log.noformat=true -Dtest_db_user=root -Dtest_db_password=password -Dtest_db_host=localhost coverage test coverageReport
FROM compile as build
# Define working directory
WORKDIR /root
COPY --from=compile /usr/src/push/target/scala-2.12/app-assembly-?*.?*.?*.jar ./push.jar
COPY --from=compile /usr/src/push/config/jvm.config ./jvm.config
COPY --from=compile /usr/src/push/entrypoint.sh /bin/entrypoint.sh
RUN chmod +x /bin/entrypoint.sh
ENTRYPOINT ["/bin/entrypoint.sh"]
CMD ["docker", "blah"]
With multi-stage builds, you use multiple FROM statements in your Dockerfile. Each FROM instruction can use a different base, and each of them begins a new stage of the build. You can selectively copy artifacts from one stage to another, leaving behind everything you don't want in the final image.
Introduction. Docker is a handy tool for containerization. It's so useful that sometimes, we want to have more than one Dockerfile in the project. Unfortunately, this goes against the straightforward convention of naming all Dockerfiles just “Dockerfile”.
You only need to build the image once, and use it until the installed dependencies (like Python packages) or OS-level package versions need to be changed. Not every time your code is modified. Just because you're mounting the code directory, does not mean you can't ADD code to the image.
Set DOCKER_BUILDKIT=1
environment variable to use buildkit like this:
DOCKER_BUILDKIT=1 docker build -t build-stage-tag --target build -<<EOF
FROM alpine as base
RUN echo "running BASE commands"
FROM base AS test
RUN echo "running TEST commands"
FROM base AS build
RUN echo "running BUILD commands"
EOF
output:
[+] Building 4.4s (7/7) FINISHED
=> [internal] load .dockerignore 0.5s
=> => transferring context: 2B 0.0s
=> [internal] load build definition from Dockerfile 0.3s
=> => transferring dockerfile: 204B 0.0s
=> [internal] load metadata for docker.io/library/alpine:latest 0.0s
=> [base 1/2] FROM docker.io/library/alpine 0.1s
=> => resolve docker.io/library/alpine:latest 0.0s
=> [base 2/2] RUN echo "running BASE commands" 1.4s
=> [build 1/1] RUN echo "running BUILD commands" 1.5s
=> exporting to image 0.7s
=> => exporting layers 0.6s
=> => writing image sha256:c6958c8bb64b1c6d5a975d8fa4b68c713ee5b374ba9a9fa00f8a0b9b5b314d5e 0.0s
=> => naming to docker.io/library/build-stage-tag 0.0s
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With