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/ping
endpoint - 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/ping
endpoint - 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-service
docker 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.0
Consul 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.yml
callme-service/src/main/resources/application.yml
spring:
cloud:
consul:
host: localhost # Change from 192.168.99.100 to localhost
port: 8500
cd callme-service
mvn spring-boot:run
# Or using Java directly:
# java -jar target/callme-service-1.0.0-SNAPSHOT.jar
cd caller-service
mvn spring-boot:run
# Or using Java directly:
# java -jar target/caller-service-1.0.0-SNAPSHOT.jar
curl http://localhost:8091/callme/ping
# Expected response: callme-service:1.0.0-SNAPSHOT
curl 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_path
to 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.