Welcome to the penultimate post in this continuous journey about continuous integration and continuous deployment. So far in this blog series, we have gone over a copious amount of topics related to building and automated testing and deploying of a microservice using many popular tools in the Java and open-source ecosystem. Here’s what we have covered so far.
Honestly, there is not much left to talk about as it relates to the basics of continuous integration and deployment of microservices. There is however one more topic that we would be remiss to not mention and that is building and deploying our microservice as a Docker container onto a Kubernetes Cluster. It’s not terribly complicated to do this, but we’ll break this last topic up into two separate blog posts. In this post, we’ll focus on building our Docker container.
If you’ve followed along with this series, you may or may not have noticed that way back in part one when we generated our Micronaut application there was a file named
Dockerfile created in the root of the project. Let’s open that up and take a look at it. It should look very similar to this (unless you’ve used a different name for your project):
We’re going to need a Docker Registry to store our Docker images. You can use Docker Hub if you’d like, but a great option for hosting Docker Images in the Oracle Cloud is the Oracle Cloud Infrastructure Registry (OCIR). If you have not yet configured OCIR for your tenancy, do so now before we move forward.
Tip! Check out The Complete Guide To Getting Up And Running With Docker And Kubernetes On The Oracle Cloud for help getting prepared for Docker & Kubernetes!
If we were to have built and run this
Dockerfile way back before we added our dependencies it would have worked just fine. But since our DB connection requires a wallet for our Autonomous DB connection we’d have a problem if we tried to run it right now. Let’s make one simple modification to it to
COPY in our wallet directory.
This will copy the wallet contents from the root of our project into our Docker container. You can drop your wallet into the root of the project and give it a shot.
Note: Do not check your wallet into version control. Make sure you add an entry to your
.gitignore file to prevent accidental check-in!
To build our image, first make sure your JAR file is built locally with
./gradlew assemble and then run:
To test it out locally, export your configuration variables:
Take note of the URL above - you must use a local IP address instead of ‘localhost’ inside the Docker container!
Run it with:
Now that we’ve changed our
Dockerfile and tested that it builds properly, we need to modify our GitHub Actions workflow to automate these tasks and then push the resulting Docker image to our OCIR repo. The first step is to modify to write out our Wallet to disk in the runner VM so when we run our Docker build it can be copied in. If you’ve followed along with this series, you should already have secrets in your GitHub repo for the wallet files, so modify the step we added before to write our configuration files to also write our wallet files to the runner’s workspace directory:
Next create two more secrets in GitHub, one for our
OCIR_USERNAME (in the tenancy/username format) and one for the token called
Hint: If you don’t have a need for anything related to deploying to a VM and would only like to deploy to Docker, you can remove all of the previous steps related to that deployment now.
Next, add a step to login to OCIR. This step will use the
actions-hub/docker/login@master action to perform the login. Substitute your appropriate URL if you are not using the PHX region!
Now let’s do the same docker build command that we tested locally from our pipeline:
And finally, push that image to OCIR:
Observe your build on GitHub and it should complete successfully:
And we can confirm this by checking our OCIR registry:
In this post, we modified our GitHub Actions workflow to build a Docker image that contains our microservice and pushed that image to our OCIR registry.
In the next post, we’ll deploy our microservice Docker image to a Kubernetes cluster in the Oracle Cloud.
For this post can be found at https://github.com/recursivecodes/cicd-demo/tree/part-9
A while back, I blogged about using Oracle Advanced Queuing (AQ) for messaging within your applications. It's a great option for durable and reliable...
I’ve written about messaging many, many times on this blog. And for good reason, too. It’s a popular subject that developers can’t seem to get enough of...
When working in the cloud, there are often times when your servers and services are not exposed to the public internet. Private virtual cloud networks ...