A production-ready microservices architecture built with Spring Boot 3.5, Spring Cloud 2025.0.0, and GraalVM native image support.
This project implements a microservices architecture with API gateway and multiple business services:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β API Gateway (8080) β
β traefik β
ββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββββββ
β
ββββββββββββββββ¬βββββββββββββββ¬ββββββββββββββ
β β β β
βββββββββΌβββββββββ ββββΌββββββββββββ ββΌβββββββββββ ββΌβββββββββββββ
β user-service β βproduct-serviceβ βorder-serviceβ β ...more β
β (8081) β β (8082) β β (8083) β β services β
ββββββββββββββββββ βββββββββββββββββ ββββββββββββββ βββββββββββββββ
- gateway-server (8080): API Gateway with routing and load balancing
- user-service (8081): User management service
- product-service (8082): Product catalog service
- order-service (8083): Order processing service with circuit breaker
Note
This template does not include a config-server. Services use environment variables and embedded configuration files for simplicity.
.
βββ .github/
β βββ workflows/
β βββ native-build.yml # CI/CD for native image builds
βββ gateway-server/ # API Gateway
βββ user-service/ # User management
βββ product-service/ # Product catalog
βββ order-service/ # Order processing
βββ k8s/ # Kubernetes manifests
β βββ namespace.yaml
β βββ gateway-server.yaml
β βββ user-service.yaml
β βββ product-service.yaml
β βββ order-service.yaml
βββ tests/ # Test suites
β βββ functional-tests/ # Postman collections
β βββ performance-tests/ # JMeter tests
βββ Containerfile # Generic native image build
βββ pom.xml # Parent POM with native profile
βββ Makefile # Build automation
βββ run-all.sh # Start all services locally
βββ stop-all.sh # Stop all services
βββ populate_data.py # Test data population
- Java 21 (Temurin or similar)
- Maven 3.9+
- Buildah (for native image builds)
- k0s (for Kubernetes deployment)
- GraalVM (optional, for local native builds)
Option 1: Run all services with Maven
# Start all services with local profile
./run-all.sh
# Stop all services
./stop-all.shOption 2: Run individual services
# Build all services
mvn clean package -DskipTests
# Start all services
cd user-service && mvn spring-boot:run &
cd product-service && mvn spring-boot:run &
cd order-service && mvn spring-boot:run &
cd gateway-server && mvn spring-boot:run &Option 3: Using Makefile
make build # Build all services (Maven)
make deploy # Deploy to k0s (local images)
make deploy-remote # Deploy to k0s (remote images from ghcr.io)
make pull-images # Pre-pull remote images
make update-images # Update running deployments
make undeploy # Remove from k0s
make logs # View logs (default: gateway-server)
make status # Check pod status
make k8s-status # Detailed k8s status- API Gateway: http://localhost:8080
- Users API: http://localhost:8080/users
- Products API: http://localhost:8080/products
- Orders API: http://localhost:8080/orders
This project supports GraalVM native image compilation for faster startup and lower memory footprint.
The project includes automated CI/CD for native image builds:
- Workflow:
.github/workflows/native-build.yml - Triggers: Push to
mainor pull requests - Output: Native images pushed to
ghcr.io - Build time: ~5-10 minutes per service
Build with Maven native profile:
# Build native executable for a specific service
mvn -Pnative native:compile -pl user-service -DskipTests
# Run the native executable
./user-service/target/user-service- Startup Time: ~0.1s vs ~3-5s (JVM)
- Memory Usage: ~50-100MB vs ~200-400MB (JVM)
- Image Size: ~100-150MB vs ~300-500MB (JVM)
- Parallel Maven Builds: Uses Maven's parallel build mode (
-T 1C) for faster multi-service compilation - CI Pipeline Caching: GitHub Actions caches Maven dependencies and Docker layers for faster builds
- Buildah Support: Rootless container builds with efficient layer caching
- Incremental Builds: Only rebuilds changed services in multi-module setup
python3 populate_data.pymake postman-testmake perf-testPerformance Tests (JMeter):
# 1. Create ConfigMap with test plan and data
k0s kubectl create configmap jmeter-tests -n ms \
--from-file=tests/performance-tests/test-plan.jmx \
--from-file=tests/performance-tests/data/
# 2. Run the Job
k0s kubectl apply -f k8s/jmeter-job.yaml
# 3. View logs/results
k0s kubectl logs -n ms job/jmeter-test -f
# Cleanup (to run again)
k0s kubectl delete job jmeter-test -n ms
k0s kubectl delete configmap jmeter-tests -n msFunctional Tests (Newman):
# 1. Create ConfigMap with collection and environment
k0s kubectl create configmap newman-tests -n ms \
--from-file=tests/functional-tests/api-tests.postman_collection.json \
--from-file=tests/functional-tests/api-environment.postman_environment.json
# 2. Run the Job
k0s kubectl apply -f k8s/newman-job.yaml
# 3. View logs/results
k0s kubectl logs -n ms job/newman-test
# Cleanup (to run again)
k0s kubectl delete job newman-test -n ms
k0s kubectl delete configmap newman-tests -n msThe easiest way to deploy is using prebuilt native images from GitHub Container Registry:
# Deploy using remote images from ghcr.io/bikram054/ms
make deploy-remoteThis will:
- Pull native images from
ghcr.io/bikram054/ms - Deploy all microservices to k0s
- Wait for all pods to be ready
- Display service endpoints
Available commands:
make deploy-remote # Deploy using remote images
make pull-images # Pre-pull all images to k0s nodes
make update-images # Update deployments with latest images
make status # Check pod status
make logs # View logs (default: gateway-server)
make undeploy # Remove all servicesIf you've built images locally:
# Deploy to k0s
make deployManual deployment:
# Create namespace and deploy
sudo k0s kubectl apply -f k8s/namespace.yaml
sudo k0s kubectl apply -f k8s/
# Verify deployment
sudo k0s kubectl logs -n ms -l app=gateway-server -fNative Images (Recommended):
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "300m"JVM Images:
resources:
requests:
memory: "256Mi"
cpu: "200m"
limits:
memory: "512Mi"
cpu: "500m"- default: Local development with H2 database
- prod: Production configuration (used in native builds)
# Spring profiles
SPRING_PROFILES_ACTIVE=prod# Check service health
curl http://localhost:8080/actuator/health# Quick status
make status
# Detailed status
make k8s-status
# View all services
sudo k0s kubectl get all -n ms
# Check pod status
sudo k0s kubectl describe pod <pod-name> -n ms
# View logs
make logs SERVICE=gateway-server
# Resource usage
sudo k0s kubectl get pods -n msIssue: ImagePullBackOff or ErrImagePull
# Check pod events
sudo k0s kubectl describe pod <pod-name> -n ms
# Verify image exists
docker pull ghcr.io/bikram054/ms/gateway-server:latest
# For private registries, ensure image pull secret is created
./setup-image-pull-secret.shIssue: Images not updating
# Force pull latest images
make update-images
# Or manually restart deployments
sudo k0s kubectl rollout restart deployment --all -n msIssue: Missing reflection configuration
# Add to native-image.properties or use @RegisterReflectionForBindingIssue: Out of memory during build
# Increase Docker memory limit to 8GB+# Check events
sudo k0s kubectl describe pod <pod-name> -n ms
# View logs
sudo k0s kubectl logs <pod-name> -n ms --previous
# Common fixes:
# 1. Increase initialDelaySeconds in liveness probe
# 2. Verify image pull secrets (if using private registry)- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License.
Built with β€οΈ using Spring Boot and GraalVM