A demonstration project showing how to deploy Spring Cloud microservices on HashiCorp's Nomad orchestrator with Consul service discovery.
For a comprehensive guide, visit: Deploying Spring Cloud Microservices on Hashicorp's Nomad
This project demonstrates a microservices architecture using Spring Cloud components deployed on Nomad:
graph TB
subgraph NomadCluster ["Nomad Cluster"]
subgraph CallerServiceInstances ["Caller Service Instances"]
CS1[caller-service:8090]
CS2[caller-service:8090]
end
subgraph CallmeServiceInstances ["Callme Service Instances"]
CMS1[callme-service:8091]
CMS2[callme-service:8091]
end
end
subgraph ServiceDiscovery ["Service Discovery"]
CONSUL["Consul Agent\n192.168.99.100:8500"]
end
CLIENT[HTTP Client] --> CS1
CLIENT --> CS2
CS1 -.->|Service Discovery| CONSUL
CS2 -.->|Service Discovery| CONSUL
CS1 -->|Load Balanced Calls| CMS1
CS1 -->|Load Balanced Calls| CMS2
CS2 -->|Load Balanced Calls| CMS1
CS2 -->|Load Balanced Calls| CMS2
- Purpose: Demonstrates service-to-service communication and load balancing
- Technology Stack: Spring Boot, Spring Cloud Consul Discovery, RestTemplate
- Port: 8090 (configurable via
NOMAD_HOST_PORT_http) - Functionality:
- Exposes
/caller/pingendpoint - Makes load-balanced calls to
callme-service - Uses Consul for service discovery
- Returns combined response with build information
- Exposes
- Purpose: Simple REST service that responds to calls
- Technology Stack: Spring Boot Web
- Port: 8091 (configurable via
NOMAD_HOST_PORT_http) - Functionality:
- Exposes
/callme/pingendpoint - Returns service name and version information
- Lightweight service for demonstration purposes
- Exposes
- Java: 21
- Spring Boot: 3.5.0
- Spring Cloud: 2025.0.0
- Build Tool: Maven 3.x
- Orchestrator: HashiCorp Nomad
- Service Discovery: HashiCorp Consul
- CI/CD: CircleCI
- Code Quality: SonarCloud
Before running this project locally, ensure you have:
- Java 21 or higher
- Maven 3.6+ for building the project
- HashiCorp Consul for service discovery
- HashiCorp Nomad for container orchestration (for deployment)
- Git for cloning the repository
git clone https://github.com/piomin/sample-nomad-java-services.git
cd sample-nomad-java-services# Build all modules
mvn clean install
# Or build individual services
mvn clean install -pl caller-service
mvn clean install -pl callme-servicedocker run -d --name consul \
-p 8500:8500 \
-p 8600:8600/udp \
consul:latest agent -server -ui -node=server-1 -bootstrap-expect=1 -client=0.0.0.0- Download Consul from HashiCorp's website
- Start Consul in development mode:
consul agent -dev -client=0.0.0.0Consul UI will be available at: http://localhost:8500
If using a virtual machine or different network setup, update the Consul host in:
caller-service/src/main/resources/application.ymlcallme-service/src/main/resources/application.yml
spring:
cloud:
consul:
host: localhost # Change from 192.168.99.100 to localhost
port: 8500cd callme-service
mvn spring-boot:run
# Or using Java directly:
# java -jar target/callme-service-1.0.0-SNAPSHOT.jarcd caller-service
mvn spring-boot:run
# Or using Java directly:
# java -jar target/caller-service-1.0.0-SNAPSHOT.jarcurl http://localhost:8091/callme/ping
# Expected response: callme-service:1.0.0-SNAPSHOTcurl http://localhost:8090/caller/ping
# Expected response: caller-service:1.0.0-SNAPSHOT. Calling... callme-service:1.0.0-SNAPSHOT- Nomad Cluster: Running Nomad cluster with Java driver enabled
- Consul Integration: Nomad integrated with Consul for service discovery
- Built Artifacts: JAR files built and accessible by Nomad agents
- Build the services:
mvn clean package-
Update JAR paths in Nomad job files:
- Edit
caller-service/job.nomad - Edit
callme-service/job.nomad - Update the
jar_pathto reflect your local build path
- Edit
-
Deploy callme-service first:
nomad job run callme-service/job.nomad- Deploy caller-service:
nomad job run caller-service/job.nomad- Verify deployment:
nomad job status caller-service
nomad job status callme-service| Key | Description | Default |
|---|---|---|
NOMAD_HOST_PORT_http |
Host port mapping for HTTP | 8090/8091 |
spring.cloud.consul.host |
Consul host | localhost |
spring.cloud.consul.port |
Consul port | 8500 |
| Service | Endpoint | Method | Description |
|---|---|---|---|
| caller-service | /caller/ping |
GET | Ping endpoint; returns own info and calls callme |
| callme-service | /callme/ping |
GET | Ping endpoint; returns own service and version |
- Metrics: Exposed via Spring Boot Actuator (
/actuator/metrics,/actuator/prometheus) - Tracing: Configurable Zipkin integration
- Logging: Default Logback configuration, customizable via
logback.xml
- Use Spring profiles (
dev,prod) for environment-specific configs - Enable hot reloading with
spring-boot-devtools - Run individual modules using
mvn -pl caller-service spring-boot:run - Use your IDEβs built-in Docker and Nomad plugins for local testing
Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch (
git checkout -b feature/your-feature) - Commit your changes (
git commit -m "feat: add your feature") - Push to branch (
git push origin feature/your-feature) - Open a Pull Request
This project is licensed under the MIT License. See LICENSE for details.
For questions or feedback, please open an issue on GitHub or reach out on Twitter @piotr_minkowski.