In this medium, we will be talking about fully dockerizing Quarkus. Luckily for us, Quarkus usually generates the DockerFile for us. We only have to do some modification to establish full dockerization. Afterwards, we will move our application properties to a secure environment file. Finally, we will talk about the remote developing with Quarkus.

The DockerFile

What we have

Lucking for us, Quarkus creates not 1, not 2, but 3 DockerFiles for us to use at our leisure. For this example, we will be using the ‘DockerFile.fast-jar’ file. Unfortunately for us, the dockers provided for us requires Java and Maven (Or we can simply use ./mvnw) to be present on our local machine, and this defeats the purpose of Docker. The changes we want to add involves the docker multi-stage builds. As of writing, the current Quarkus latest final version is 1.11.3, and they provide us with the following DockerFile.

Easy enough, this simply informs docker to get the image that is present in the “FROM“ keyword, execute a couple of commands to prepare the environment, and lastly copy the generated jars that were built into the docker container. For more on the docker syntax check this link here. Please note that in order for this docker build to execute correctly, we have to execute the following command prior to building the docker container:

We may add the argument “-DskipTests=true” to skip running test for time purposes.

What we need to do

This defeats the purpose of docker and forces anyone who simply just wants to build and run our container to install maven and java. To change that, we have to add a new stage which we will call the “builder stage“ before the running stage which is shown below.

As you noticed, we will be getting a docker image that has both java and maven. Afterwards, we copy our “pom.xml” and “src” into our container. Finally, we set our working directory to that where everything is copied and build the project.

Again, we may add the argument “-DskipTests=true” to skip running test for time purposes.

We added the argument “dependency:go-offline” for us to keep all downloaded maven repositories and not re-download them each time we want to build our project.

Afterwards we want to copy the generated build into the deployment directory instead of copying the build from our local machine. This can be done by replace the 4 copy commands with the following:

With these updated, we simply stated to get the files from the previous stage and we set the directory they were generated in.

Finally we will get our docker file looking like this:

In this way, we guarantee that anyone who wants to use run our project in docker, can build and run it easily without downloading any dependency to their machine.

Property Changes

The Security

In this section, we want to be able to secure our properties. We can do so using the “.env” file which we will place in our root project directory. This file will house environment variables that have this form:

For our properties file we will simply reference them as properties file as such:

In this manner, for any change we want to do for our properties like increasing the log level, we simple edit the .env file, and restart our container.

I also want to note that we can completely move to the .env file because Quarkus support property and environment mapping which can be seen here. As such, we would not have to create an environment reference inside the properties file.

The Connections

If we are using docker-compose and we want to connect to other containers, we might have to change a few things. For connections that our outside our services, we keep them as they are. On the other hand, for connections that are to our services like database connection or internal API calls, they should be referenced as containers. For example, we have the following MySQL connection JDBC string:

This will unable to connect to the MySQL database because with respect to the container it is not running in it, but on a different container. To fix this, we simply have to replace the hostname with the container name and the port with internal container port and not the external one. As a result, we will have something like this:

The Docker Compose

At this point, we might want to add our container to the tribe of containers that houses all our applications from different teams. Our container might seem alone at this point, but it can be easily added and directly be one with the tribe.

The Composition

At this point, we can add our project to the docker-composition to be a part the integration tribe. This docker composition file is named ‘docker-compose.yml’, we will add this beside our Quarkus project. This file is yaml file and as such we have to take care of our spacing. Our structure should follow this format:

The ${project-name} is the directory to our Quarkus project.

The ‘depends_on’ is a handy operation which informs that our container requires other containers for it to run like a mysql and mongodb databases for instance. This will make sure that these services run before our application does.

In the ‘build’, we have to specify the context which is the project directory, and the location of the dockerfile we wish to use.

In the ‘env_file’, we simply map it to the properties file that it will copy and use in the container.

Lastly, we will define the listening ports for our application. By default, the Quarkus project will run our application on port 8080. We may keep it like that because this is running on its own local container. We simply have to map it to an external port of our choosing.

For example, we can have the following docker compose file that contains our application, mongodb, and mysql.

The Building

To build our container, we simply execute the following command:

This will build our container and all of its container dependencies.

The Running

After we successfully build our container and its dependencies, we can run them using the following command:

This will build and run our container in real time. In other words, we can view live logs in our terminal for debugging purpposes. We can simply use ctrl+c to exit, but keep the container. Afterwards, we can run it without viewing the logs using the following command:

The Stopping

After we successfully run our containers, We can stop our docker using the ‘ctrl+c’ if we ran is using the ‘up’ argument. Otherwise, we have to stop it using the following command:

The Destruction

We can tear down our containers using the following command:

This will destroy our containers and anything inside them. If we want to preserve anything, we can use docker volumes to preserve data and load them into our containers. Please also note that once we destroy and rebuild a container, we will have to redownload all dependencies.

The Remote Development

One of the great features of Quarkus is that it allows us to develop without having to run the application on IDE. In other words, we connect to a running service and modify it in real time. To do so, we have to enable remote development for docker, and in this section we will show you how. Remote development in Quarkus wants us to package our application using ‘mutable-jar’.

The Application Properties

In our application properties, we have to add the following arguments.

To enable debugging, we have to expose the port 5005 along with the default one provided in our DockerFile.

The .env

In the .env file, we have to enable it using the environment variables.

The Running

After completing the previous step, you can check in the logs that remote development has been enabled, and that the project is running using the development profile.

The Remote Connection

Now all we have to do is connect to the service using the following maven command:

In this command, we execute it using the installed maven project. We specify the url to connect to and the external port, and we should specify the password which we set when we build the container.

Get Coding

Now you get coding and see your changes live on the server or container as it hot reloads!

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store