Simple Java local application development with Spring, Rancher Desktop and CircleCI.

Rafał Kuszneruk
6 min readNov 25, 2021

--

Welcome to my next article related to My cloud try-outs. The wider series aim is to provide some technical deep-dives into various aspects of modern application development and release chain.

I hope you will find it useful. Feel free to provide a feedback either by contacting me or just simply leaving a comment below.

In this article, we will focus on the local development path. Let me refer to a “bigger picture” view just to level set on a context.

TL’DR: Run things locally on your desktop “almost” the same way as on a real deployment environment.

  • We will develop a simple Java Spring application
  • We will test/run it locally from IDE
  • We will test/run it locally leveraging local CircleCI
  • We will build a Docker container and run it of local K8s (Rancher-Desktop).

I explained in detail setting up all required tools in a previous article: https://medium.com/@kuszner/setting-up-local-development-environment-with-rancher-desktop-wsl-ubuntu-and-vscode-3ae00b5aefc

Simple “Hello Cloud Crusader” Java Spring app

There isn’t really anything fancy here.

With JavaSDK installed on your desktop you can easily validate pure Java by compiling/running it from shell using:

mvn clean install spring-boot:run

This will run perform a clean install / package of your spring application, run a test (assuming you have one defined) and then run application on a desired port. Once done, you should be able to see the result by accessing localhost:port in your browser (note post 3000 was defined in application-properties of my code)

From now on, we will now try to make a similar result thru various development loops that bring us closer to running “in prod”.

Running your CI pipeline … locally

As mentioned before in a few places I’m using CircleCI (circleci.io) for my Continuous Integration (CI). A few reasons are:

  • It’s part of recommended CNCF SDLC toolset
  • I like the way you can define pipelines as part of your code
  • circleci CLI gives you an ability to run your pipeline locally (per pipeline job)
  • You can have same pipeline behavior with enabled tests, as with the full development loop cycle while going thru vcs (GitHub) and CI loop.
  • You can also define local-only conditional steps to orchestrate your local dev better

I’m planning on playing with some other CI systems like Tekton or GitLab, but I’ll leave it for another cloud try-outs ;)

To begin your local setup, all you need to do is to have circleci CLI installed in your Ubuntu, and then define your pipeline in .circleci/config.yml pipeline configuration file in your app repo.

I’m not going to go into circleci config structure too deep since there are great how-to articles on their site: https://circleci.com/docs/

Overall you structure your pipeline by giving a reference to jobs each having its definition of executor (circleci Docker image), steps and tasks.

Once the .circleci/config.yml file is defined in your application folder you can then run it locally from CLI with following command. Here important point is that locally you can only run separate pipeline jobs, not the entire pipeline.

circleci local execute --job [job name]

TIP: for Java maven builds to avoid maven plugin downloads in your circleci pipeline maven build step, you can mount your ~/.m2 directory with caching plugins to the pipeline docker image. This should save a great deal of your dev time when running tests frequently. Otherwise, app build step would download it each time given the pipeline execution is done on an immutable image.

circleci local execute -v /root/.m2:/home/circleci/.m2:rw --job build-and-test

With that, we are now ready to build our app image and run it on k8s cluster… shall we?

Building and running application on local K8s cluster with kim and Rancher-desktop

Right now we will focus more on the application deployment part. There a are few key concepts we will follow:

  • We will use helm for managing deployment artefacts. I hope I don’t have to introduce it, as this is a standard for containerized apps. Helm is a backbone to our CD as well.
  • Rancher-Desktop uses kim (https://github.com/rancher/kim) as its image builder. It’s mimicking docker for building and publishing images, but you won’t run your image with kim. Why would you, if you are deploying to local k8s cluster anyway :) You can read more details on GitHub if needed.
  • To use kim, you need to have your Rancher-desktop in running state. Make sure it’s up and running, and validate you can connect to it with kubectl. You can also validate kim by listing available images.

Building app image

To build an app image you need to have your Dockerfile ready in your app folder. We are using a super simple one, nothing fancy.

From your app folder, run kim image build to build and image. Please note the tag used, which will and image tag in docker repos (local as well as DockerHub).

kim image build --tag kuszner/rafal-app:0.5 .

You can validate the results of the build by listing images in your rancher-desktop, or listing images via kim.

Running application in a local cluster

With the image cached in local k8s cluster, we have all prerequisites to run our application on it. For this, we will use helm.

First, we need to define helm charts for deployment. There are many approaches to managing and placing helm charts. The route I’m following is to define separate helm charts for each environment the app will run on. Such an approach allows me to keep everything in one repo, and still point ArgoCD to env charts when running locally or in prod (to be explained in subsequent sections). Another alternative is to further overlay helm with kustomize or keep charts in separate repos / branches. For now, I tend to choose simplicity (KISS, right ?).

Once you have your local chart defined, deploying to a cluster is relatively easy from CLI with helm install (1st deployment) or helm upgrade for upgrading already running configuration:

helm upgrade rafal-app helm/rafal-app-local/

Right now we should have an application running on a cluster:

To get access to it, you need to perform port-forwarding from rancher-desktop (in Windows at least).

Once done you can access it in your browser via localhost:50674(as per the port that was generated)

That’s it! You can now embrace your Kubernetes experience on a local desktop. In the next articles, we will focus on leaving local development loop (with a small plot twist), and pushing application code thru a full CI/CD flow. This will introduce us to a full CI platform and modern approach to CD with Argo. We will demonstrate the outer-inner loop with ArgoCD running our local cluster. Will be fun !

You can read on next steps via My Cloud try outs

Rafał Kuszneruk

--

--