quarkusio / quarkus

Quarkus: Supersonic Subatomic Java.
https://quarkus.io
Apache License 2.0
13.68k stars 2.65k forks source link

Redesign the multi-stage docker build #16881

Closed cescoffier closed 3 years ago

cescoffier commented 3 years ago

Description

Our documentation contains an example of a multi-stages docker file to build a container running a native executable. That example is on https://quarkus.io/guides/building-native-image#using-a-multi-stage-docker-build.

That example is using a Quarkus image as based that we would like to retire (quay.io/quarkus/centos-quarkus-maven:21.0.0-java11).

Implementation ideas

Here is another working variant that uses an image that we will continue to produce regularly:

## Stage 1 : build with maven builder image with native capabilities
FROM quay.io/quarkus/ubi-quarkus-native-image:21.0.0-java11 AS build
COPY pom.xml /project/
COPY mvnw /project/mvnw
COPY .mvn /project/.mvn
USER quarkus
WORKDIR /project
RUN ./mvnw -B org.apache.maven.plugins:maven-dependency-plugin:3.1.2:go-offline
COPY src /project/src
RUN ./mvnw package -Pnative

## Stage 2 : create the docker final image
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.3
WORKDIR /work/
COPY --from=build /project/target/*-runner /work/application

# set up permissions for user `1001`
RUN chmod 775 /work /work/application \
  && chown -R 1001 /work \
  && chmod -R "g+rwX" /work \
  && chown -R 1001:root /work

EXPOSE 8080
USER 1001

CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]

The idea is to rely on the maven wrapper instead of expecting Maven to be provided by the base image. First, it allows the user to decide which version of Maven should be used (3.6.3 vs. 3.8.1). It also makes the usage of Gradle straightforward. That new requirement demand the user to run mvn -N io.takari:maven:0.7.7:wrapper first to install the maven wrapper if not already there.

@maxandersen @n1hility @geoand @mkouba WDYT? (I didn't create a PR yet, because I want to discuss it first).

NOTE: The go-offline is used to provision in its own layer the required dependencies, meaning that if you change your code and re-build it will recover from the layer COPY src ...

geoand commented 3 years ago

I personally like it a lot!

cescoffier commented 3 years ago

Should we move forward?

mkouba commented 3 years ago

I'm not a big fan of maven wrapper but it sounds reasonable if we document this requirement properly.

maxandersen commented 3 years ago

I'm +1

I do think we will evolve this in future anyway if buildpack becomes viable.

But removing need for this monster of image is worth more than having mvn wrapper use imo.

Users who need/want that can customize as need.

cescoffier commented 3 years ago

Ok, I will open a PR tomorrow.

ThoSap commented 3 years ago

RHEL 8.4 was released on 2021-05-21 😉 Can we update the base image to registry.access.redhat.com/ubi8/ubi-minimal:8.4?

geoand commented 3 years ago

https://github.com/quarkusio/quarkus/pull/17764 should take care of it