Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ POSTGRES_PASSWORD=XXXXXXXXX
POSTGRES_DB=XXXXXXXXX
DATABASE_URL=XXXXXXXXX
REDIS_HOST=XXXXXXXXX
REDIS_PORT=XXXXXXXXX
REDIS_PORT=XXXXXXXXX
GRAFANA_ADMIN_USER=admin
GRAFANA_ADMIN_PASSWORD=admin
55 changes: 54 additions & 1 deletion .github/workflows/docker-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,15 @@ jobs:
push: true
tags: ghcr.io/${{ env.REPO_LOWER }}/user-service:latest

- name: Scan userService image with Trivy
uses: aquasecurity/trivy-action@0.28.0
with:
image-ref: ghcr.io/${{ env.REPO_LOWER }}/user-service:latest
format: table
severity: CRITICAL,HIGH
exit-code: '1'
ignore-unfixed: true

# Build authService
build-authService:
needs: detect-changes
Expand Down Expand Up @@ -104,6 +113,15 @@ jobs:
push: true
tags: ghcr.io/${{ env.REPO_LOWER }}/auth-service:latest

- name: Scan authService image with Trivy
uses: aquasecurity/trivy-action@0.28.0
with:
image-ref: ghcr.io/${{ env.REPO_LOWER }}/auth-service:latest
format: table
severity: CRITICAL,HIGH
exit-code: '1'
ignore-unfixed: true

# Build mailService
build-mailService:
needs: detect-changes
Expand Down Expand Up @@ -133,6 +151,15 @@ jobs:
push: true
tags: ghcr.io/${{ env.REPO_LOWER }}/mail-service:latest

- name: Scan mailService image with Trivy
uses: aquasecurity/trivy-action@0.28.0
with:
image-ref: ghcr.io/${{ env.REPO_LOWER }}/mail-service:latest
format: table
severity: CRITICAL,HIGH
exit-code: '1'
ignore-unfixed: true

# Build eureka
build-eureka:
needs: detect-changes
Expand Down Expand Up @@ -162,6 +189,15 @@ jobs:
push: true
tags: ghcr.io/${{ env.REPO_LOWER }}/eureka:latest

- name: Scan eureka image with Trivy
uses: aquasecurity/trivy-action@0.28.0
with:
image-ref: ghcr.io/${{ env.REPO_LOWER }}/eureka:latest
format: table
severity: CRITICAL,HIGH
exit-code: '1'
ignore-unfixed: true

# Build configServer
build-configServer:
needs: detect-changes
Expand Down Expand Up @@ -191,6 +227,15 @@ jobs:
push: true
tags: ghcr.io/${{ env.REPO_LOWER }}/config-server:latest

- name: Scan configServer image with Trivy
uses: aquasecurity/trivy-action@0.28.0
with:
image-ref: ghcr.io/${{ env.REPO_LOWER }}/config-server:latest
format: table
severity: CRITICAL,HIGH
exit-code: '1'
ignore-unfixed: true

# Build gateway
build-gateway:
needs: detect-changes
Expand Down Expand Up @@ -218,4 +263,12 @@ jobs:
with:
context: ./gateway
push: true
tags: ghcr.io/${{ env.REPO_LOWER }}/gateway:latest
tags: ghcr.io/${{ env.REPO_LOWER }}/gateway:latest
- name: Scan gateway image with Trivy
uses: aquasecurity/trivy-action@0.28.0
with:
image-ref: ghcr.io/${{ env.REPO_LOWER }}/gateway:latest
format: table
severity: CRITICAL,HIGH
exit-code: '1'
ignore-unfixed: true
38 changes: 37 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ A production-ready Spring Boot 3 microservices template. Includes service discov
- [Kafka Topics](#kafka-topics)
- [Redis Caching](#redis-caching)
- [Health Checks](#health-checks)
- [Centralized Logging](#centralized-logging)
- [Adding a New Service](#adding-a-new-service)
- [Kubernetes](#kubernetes)
- [Common Issues](#common-issues)
Expand Down Expand Up @@ -116,7 +117,7 @@ A production-ready Spring Boot 3 microservices template. Includes service discov
| Messaging | Apache Kafka 7.5.0, Spring Kafka |
| Security | Spring Security, JWT (jjwt 0.12.5) |
| Resilience | Resilience4j Circuit Breaker, Spring Retry |
| Monitoring | Spring Boot Actuator |
| Monitoring | Spring Boot Actuator, Loki, Promtail, Grafana |
| Load Testing | Gatling 3.10.5 |
| Containerization | Docker, Docker Compose |
| Orchestration | Kubernetes (Deployments, StatefulSets, HPA) |
Expand Down Expand Up @@ -382,6 +383,39 @@ Startup order: `zookeeper` → `kafka` → `db` → `eureka` → `config-server`

---

## Centralized Logging

Logs are centralized with **Promtail → Loki → Grafana**.

- **Promtail** tails Docker container logs and forwards them to Loki.
- **Loki** stores and indexes logs.
- **Grafana** provides querying and visualization.

Start the stack (logging services are already included in compose):

```bash
docker compose -f compose.dev.yml up --build -d
```

Access:

- Grafana: `http://localhost:3000`
- Loki: `http://localhost:3100`

Default Grafana credentials are `admin/admin` (override in `.env` with `GRAFANA_ADMIN_USER` and `GRAFANA_ADMIN_PASSWORD`).

Example LogQL queries in Grafana Explore:

```logql
{compose_service="gateway"}
```

```logql
{compose_project="springboot_microservice"}
```

---

## Adding a New Service

**1. Create Spring Boot project** with dependencies: `web`, `actuator`, `eureka-client`, `spring-cloud-config`
Expand Down Expand Up @@ -505,6 +539,8 @@ Kafka container listens on `29092` internally. Host port `19092` maps to contain
| Redis | 6379 | 6379 |
| Kafka | 19092 | 29092 |
| Zookeeper | 2181 | 2181 |
| Grafana | 3000 | 3000 |
| Loki | 3100 | 3100 |

---

Expand Down
76 changes: 73 additions & 3 deletions compose.dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ services:
kafka:
condition: service_healthy
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:8084/actuator/health || exit 1"]
test: ["CMD-SHELL", "curl -f http://localhost:${MANAGEMENT_PORT}/actuator/health || exit 1"]
interval: 10s
timeout: 5s
retries: 5
Expand Down Expand Up @@ -123,6 +123,10 @@ services:
context: ./configServer
dockerfile: Dockerfile.dev
container_name: config-server
volumes:
- ./configServer/target:/app/target
- ./configServer/src:/app/src
- ~/.m2:/root/.m2
restart: always
ports:
- "8888:8888"
Expand All @@ -134,7 +138,7 @@ services:
interval: 10s
timeout: 5s
retries: 5
start_period: 40s
start_period: 50s
networks:
- micro-net
mem_limit: 300m
Expand All @@ -147,6 +151,10 @@ services:
context: ./gateway
dockerfile: Dockerfile.dev
container_name: gateway
volumes:
- ./gateway/target:/app/target
- ./gateway/src:/app/src
- ~/.m2:/root/.m2
restart: always
ports:
- "8080:8080"
Expand All @@ -155,8 +163,10 @@ services:
condition: service_healthy
config-server:
condition: service_healthy
redis:
condition: service_healthy
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:8080/actuator/health || exit 1"]
test: ["CMD-SHELL", "curl -f http://localhost:${MANAGEMENT_PORT}/actuator/health || exit 1"]
interval: 10s
timeout: 5s
retries: 5
Expand Down Expand Up @@ -260,6 +270,63 @@ services:
interval: 10s
timeout: 5s
retries: 5
loki:
image: grafana/loki:3.1.1
container_name: loki
restart: always
ports:
- "3100:3100"
command: [ "-config.file=/etc/loki/config.yml" ]
volumes:
- ./observability/loki-config.yml:/etc/loki/config.yml:ro
- loki-data:/loki
networks:
- micro-net
healthcheck:
test: [ "CMD-SHELL", "wget -qO- http://localhost:3100/ready || exit 1" ]
interval: 15s
timeout: 5s
retries: 5

promtail:
image: grafana/promtail:3.1.1
container_name: promtail
restart: always
command: [ "-config.file=/etc/promtail/config.yml" ]
depends_on:
loki:
condition: service_healthy
volumes:
- ./observability/promtail-config.yml:/etc/promtail/config.yml:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- /var/lib/docker/containers:/var/lib/docker/containers:ro
- promtail-data:/tmp
networks:
- micro-net

grafana:
image: grafana/grafana:11.2.2
container_name: grafana
restart: always
ports:
- "3000:3000"
depends_on:
loki:
condition: service_healthy
environment:
- GF_SECURITY_ADMIN_USER=${GRAFANA_ADMIN_USER:-admin}
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD:-admin}
- GF_USERS_ALLOW_SIGN_UP=false
volumes:
- grafana-data:/var/lib/grafana
- ./observability/grafana/datasources:/etc/grafana/provisioning/datasources:ro
networks:
- micro-net
healthcheck:
test: [ "CMD-SHELL", "wget -qO- http://localhost:3000/api/health | grep -q ok || exit 1" ]
interval: 15s
timeout: 5s
retries: 5

networks:
micro-net:
Expand All @@ -271,3 +338,6 @@ volumes:
zookeeper-logs:
kafka-data:
redis-data:
loki-data:
promtail-data:
grafana-data:
Loading
Loading