recursive.codes


The Personal Blog of Todd Sharp

Adventures in CI/CD [#9]: Deploying A Microservice As A Docker Container

Posted By: Todd Sharp on 5/18/2020 12:00 GMT
Tagged: Cloud, Containers, Microservices, APIs, Integration, Java, Open Source

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.

The Dockerfile

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):

Preparing To Build The Docker Image

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! 

Building The Docker Image

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:

Running The Docker Build Locally

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:

Modifying The Build

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 OCIR_PASSWORD.

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:

TL;DR

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.

Next

In the next post, we’ll deploy our microservice Docker image to a Kubernetes cluster in the Oracle Cloud.

Source Code

For this post can be found at https://github.com/recursivecodes/cicd-demo/tree/part-9

Photo by Walter Sturn on Unsplash



Related Posts

Instance and Resource Principal Authentication With The OCI TypeScript/JavaScript SDK

Instance and Resource Principal Authentication With The OCI TypeScript/JavaScript SDK

In June, we launched the Oracle Cloud Infrastructure (OCI) SDK for TypeScript & JavaScript to enable you to work with all of your favorite cloud...

The Complete Guide To Invoking Serverless Oracle Functions

The Complete Guide To Invoking Serverless Oracle Functions

I have blogged quite a bit about serverless Oracle Functions here on this blog, including several various examples about function invocation. But, I've...

Building Cross Platform Native Images With GraalVM

Building Cross Platform Native Images With GraalVM

A few weeks ago, I blogged about a utility that I created that helps you debug your serverless functions in the Oracle Cloud. The code behind that project...

Note: Comments are currently closed on this blog. Disqus is simply too bloated to justify its use with the low volume of comments on this blog. Please visit my contact page if you have something to say!