HashiCorp Nomad

Run Java Spring Boot Application Using Nomad with Mysql

Nomad is an orchestration tool that enables us to deploy, manage any containerized or legacy application using a single, unified workflow. Nomad can run a diverse workload of Docker, non-containerized, micronomad-service, and batch applications.

Intro to HashiCorp Nomad

In this example we will see how to run containerized spring-boot application using Nomad.

Nomad Installation


$ curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -$ sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"$ sudo apt-get update && sudo apt-get install nomad


$ sudo yum install -y yum-utils
$ sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
$ sudo yum -y install nomad


$ sudo dnf install -y dnf-plugins-core
$ sudo dnf config-manager --add-repo https://rpm.releases.hashicorp.com/fedora/hashicorp.repo
$ sudo dnf -y install nomad

Verify Installation

$ nomad

Nomad with Consul Connect Integration

Nomad integrates with Consul to provide secure service-to-service communication between Nomad jobs and task groups. In order to support Consul Connect, Nomad adds a new networking mode for jobs that enables tasks in the same task group to share their networking stack.

Consul Installation

$ mkdir nomad
$ cd nomad
$ wget https://releases.hashicorp.com/consul/1.8.5/consul_1.8.5_linux_amd64.zip
$ unzip consul_1.8.5_linux_amd64.zip

Run Consul

$ ./consul agent -server -client -advertise -data-dir /tmp/consul -ui -bootstrap

Verify that Consul is up and running by on your browser:

This shows an overview of running services and should so far only include Consul itself.

Running Nomad Cluster

Next, in another screen, we run Nomad with server and client mode which is also a cluster.

You can read the official docs to create a HCL file from here


log_level= "DEBUG"bind_addr = ""
data_dir= "/tmp/server"
server {
enabled = true
consul {
address= ""


#increase log verbosity
log_level = "DEBUG"
# Setup data dir
data_dir = "/tmp/client"
# Give the agent a unique name. Defaults to hostname
name = "client"
# Enable the client
client {
enabled = true
# For demo assume we are talking to server. For production,
# this should be like "nomad.service.consul:4647" and a system
# like Consul used for service discovery.
servers = [""]
# Modify our port to avoid a collision with server
ports {
http = 6666
# Disable the dangling container cleanup to avoid interaction with other clients
plugin "docker" {
config {
gc {
dangling_containers {
enabled = false

Now lets run the configurations:

For Server:

$ nomad agent -config server.hcl

For Client:

$ nomad agent -config client.hcl

Check the nomad interface from the browser using:

We can now go back to the Consul UI and see that both Nomad (the component keeping state and making scheduling decisions), and nomad-client (the component running the actual jobs) have been registered.

Our Nomad cluster is ready to accept jobs now. Jobs are specified in .nomad files and sent to the Nomad server to be placed in the cluster.

In this example we will run a spring-boot application with

  • Mysql
  • Spring-boot application talking to db driver (via Consul)

Nomad Job

Nomad job specification defines schema for Nomad. The job is broken down into smaller pieces which can be expanded with the following hierarchy for a job:

|_ group
|_ task

Each job file has only a single job, however a job may have multiple groups, and each group may have multiple tasks. Groups contain a set of tasks that are co-located on a machine.

Configuration of the job uses the following syntax:


job "springboot" {
datacenters = ["dc1"]
group "mysql-server" {
count = 1
task "mysql-server" {
driver = "docker"
env {
config {
image = "mysql:8"
port_map {
db = 3306
resources {
memory = 1024
cpu = 1000
network {
port "db" {}
service {
name = "db"
port = "db"
group "springboot" {
count = 2
task "serverapp" {
driver = "docker"
config {
image = "shashwot/springboot-app:200919-eb762c8"
port_map {
app = 8090
data = <<EOH
SPRING_DATASOURCE_URL= "jdbc:mysql://{{ range service "db" }}{{ .Address }}:{{ .Port }}{{ end }}/task?allowPublicKeyRetrieval=true"
destination = "mysql-server.env"
env = true
resources {
memory = 1024
cpu = 1000
network {
port "app" {}

Running the job

We are now ready to schedule jobs to our local scheduler. Nomad will register these services with consul.

$ nomad run springbootOR if you have a different server using nomad server$ nomad run -address=http://<ip>:4646 springboot

Production Settings

This is an example only, and when running a similar setup in production, the following issues should be addressed:

  • Consul should be a cluster (i.e. three or five instances)
  • Nomad should be a cluster (i.e. three or five server instances and a dynamic number of client instances)
  • Networking should be planned with respect to both security and routing/proxying
  • Backup for MySQL data (before considering any kind of container deployment for MySQL we strongly recommend to have both backups and restore processes in place)
  • Proper risk assessment and evaluation of your storage/volume requirements





Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

How I used Google Cloud Platform to start investing in stocks

Creating sites with Tableau Server’s REST API

Windows Networking Troubleshooting 7: Network Connectivity Debugging (TrackNblOwner Principle)

Microservices Vocabulary: Services as They Are

How To Download Office 365 For Mac

Deploying WSO2 APIM into Kubernetes

PostMaster (Part 4) Integrating LinkedIn in mobile apps

Intelligent Version Control for Data Scientists

Two students studying together in a library

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
Shashwot Risal

Shashwot Risal


More from Medium

Getting your Vault Secrets into Kubernetes

How to Build a Kubernetes Environment & Scale Production

Improve your productivity with Kubernetes using aliases

NGINX Ingress? Kubernetes Ingress?