Creating a container for a Vert.x app packaged as an executable uber-jar
What you will create
You will create a container for a Vert.x app packaged as an executable uber-jar.
The how-to consists in a couple of files:
-
the
docker-maven/Dockerfile
, for Maven users, or -
the
docker-gradle/Dockerfile
, for Gradle users.
Using Maven
Generate the project
First, generate the project from https://start.vertx.io:
-
Select the
Maven
build type -
Set the
artifactId
tocontainer-uber-jar
-
Select the
JDK 11
JDK version -
Click on generate and extract the content somewhere on your disk
Alternatively, open a terminal and run:
curl -G https://start.vertx.io/starter.zip -d "artifactId=container-uber-jar" -d "jdkVersion=11" -d "buildTool=maven" --output container-uber-jar.zip
unzip container-uber-jar.zip
Or, with HTTPie:
http https://start.vertx.io/starter.zip artifactId==container-uber-jar jdkVersion==11 buildTool==maven --output container-uber-jar.zip
unzip container-uber-jar.zip
Configuring the Docker build
At the root of the project, create a docker-maven/Dockerfile
build file:
# 1st Docker build stage: build the project with Maven
FROM maven:3.6.3-openjdk-11 as builder
WORKDIR /project
COPY . /project/
RUN mvn package -DskipTests -B
# 2nd Docker build stage: copy builder output and configure entry point
FROM adoptopenjdk:11-jre-hotspot
ENV APP_DIR /application
ENV APP_FILE container-uber-jar.jar
EXPOSE 8888
WORKDIR $APP_DIR
COPY --from=builder /project/target/*-fat.jar $APP_DIR/$APP_FILE
ENTRYPOINT ["sh", "-c"]
CMD ["exec java -jar $APP_FILE"]
The Docker build has two stages:
-
Building the Maven project inside a
maven:3.6.3-openjdk-11
container -
Copying the output of the build in a
adoptopenjdk:11-jre-hotspot
container and configuring the entry point
The benefits of this approach are:
-
reproducible build: no matter who in the team runs the Docker build, it will always use the same Maven version and JDK version (both at build-time and run-time)
-
small container image size: the final container will be based on a slim JDK image and will only add the uber-jar file
To build the container, open a terminal at the root of the project and run:
docker build -t com.example/container-uber-jar -f docker-maven/Dockerfile .
Using Gradle
Generate the project
First, generate the project from https://start.vertx.io:
-
Select the
Gradle
build type -
Set the
artifactId
tocontainer-uber-jar
-
Select the
JDK 11
JDK version -
Click on generate and extract the content somewhere on your disk
Alternatively, open a terminal and run:
curl -G https://start.vertx.io/starter.zip -d "artifactId=container-uber-jar" -d "jdkVersion=11" -d "buildTool=gradle" --output container-uber-jar.zip
unzip container-uber-jar.zip
Or, with HTTPie:
http https://start.vertx.io/starter.zip artifactId==container-uber-jar jdkVersion==11 buildTool==gradle --output container-uber-jar.zip
unzip container-uber-jar.zip
Configuring the Docker build
At the root of the project, create a docker-gradle/Dockerfile
build file:
# 1st Docker build stage: build the project with Gradle
FROM gradle:6.8.3-jdk11 as builder
WORKDIR /project
COPY . /project/
RUN gradle assemble --no-daemon
# 2nd Docker build stage: copy builder output and configure entry point
FROM adoptopenjdk:11-jre-hotspot
ENV APP_DIR /application
ENV APP_FILE container-uber-jar.jar
EXPOSE 8888
WORKDIR $APP_DIR
COPY --from=builder /project/build/libs/*-fat.jar $APP_DIR/$APP_FILE
ENTRYPOINT ["sh", "-c"]
CMD ["exec java -jar $APP_FILE"]
The Docker build has two stages:
-
Building the Gradle project inside a
gradle:6.8.3-jdk11
container -
Copying the output of the build in a
adoptopenjdk:11-jre-hotspot
container and configuring the entry point
The benefits of this approach are:
-
reproducible build: no matter who in the team runs the Docker build, it will always use the same Gradle version and JDK version (both at build-time and run-time)
-
small container image size: the final container will be based on a slim JDK image and will only add the uber-jar file
To build the container, open a terminal at the root of the project and run:
docker build -t com.example/container-uber-jar -f docker-gradle/Dockerfile .
Running the application
Now that you have built the container image, it is time to try it out!
Open a terminal and run:
docker run -p 8888:8888 com.example/container-uber-jar
You should see messages like these on the console output:
HTTP server started on port 8888 Mar 16, 2021 2:45:57 PM io.vertx.core.impl.launcher.commands.VertxIsolatedDeployer INFO: Succeeded in deploying verticle
Then browse to http://localhost:8888 and get your greeting from the Vert.x app running in the container!