Small end-to-end DevOps portfolio project built around a Spring Boot task management application and PostgreSQL.
The purpose of this repository is to show a practical delivery flow from local development to containerization, CI, Kubernetes deployment on kind, basic monitoring, and Terraform-based infrastructure management.
This project demonstrates:
- local application startup
- PostgreSQL integration
- Docker image build
- Docker Compose orchestration
- GitHub Actions CI
- Kubernetes deployment on kind
- Prometheus and Grafana monitoring
- Terraform-based infrastructure management
The application exposes a simple task management API built with Spring Boot.
Main application layers included in the project:
- REST controller layer
- service layer
- repository layer
- DTOs for create and update requests
- global exception handling
- persistence with Spring Data JPA and PostgreSQL
- health and metrics endpoints with Spring Boot Actuator
- Java 21
- Spring Boot
- Spring Data JPA
- Spring Boot Actuator
- PostgreSQL 16
- Docker
- Docker Compose
- GitHub Actions
- Kubernetes
- kind
- Prometheus
- Grafana
- Terraform
.
├── Dockerfile
├── HELP.md
├── README.md
├── docker-compose.yaml
├── docs/
│ ├── docker-compose.png
│ ├── grafana-dashboard.png
│ ├── k8s-pods.png
│ ├── local-run.png
│ └── prometheus-targets.png
├── k8s/
│ ├── app-configmap.yaml
│ ├── app-deployment.yaml
│ ├── app-secret.yaml
│ ├── app-service.yaml
│ ├── grafana-configmap.yaml
│ ├── grafana-deployment.yaml
│ ├── grafana-service.yaml
│ ├── postgres-deployment.yaml
│ ├── postgres-secret.yaml
│ ├── postgres-service.yaml
│ ├── prometheus-configmap.yaml
│ ├── prometheus-deployment.yaml
│ └── prometheus-service.yaml
├── src/
│ ├── main/
│ └── test/
├── terraform/
│ ├── app.tf
│ ├── main.tf
│ ├── outputs.tf
│ ├── postgres.tf
│ ├── providers.tf
│ ├── variables.tf
│ └── terraform.tfvars
├── mvnw
├── mvnw.cmd
└── pom.xml
flowchart TD
Dev[Developer]
GH[GitHub Repository]
GHA[GitHub Actions CI]
Docker[Docker Image]
subgraph Local[Local environment]
AppLocal[Spring Boot App]
PgLocal[(PostgreSQL)]
AppLocal --> PgLocal
end
subgraph K8s[kind Kubernetes Cluster]
AppSvc[Application Service]
AppPod[Spring Boot Pod]
PgSvc[PostgreSQL Service]
PgPod[PostgreSQL Pod]
Prom[Prometheus]
Graf[Grafana]
AppSvc --> AppPod
AppPod --> PgSvc
PgSvc --> PgPod
Prom -->|scrapes actuator metrics| AppPod
Graf --> Prom
end
Dev --> AppLocal
Dev --> GH
GH --> GHA --> Docker
Docker --> K8s
Start the application directly with Maven:
./mvnw spring-boot:runDefault local URL:
http://localhost:8080
Start application and database:
docker compose up --buildUseful endpoints:
- App:
http://localhost:8080 - Health:
http://localhost:8080/actuator/health - Prometheus metrics:
http://localhost:8080/actuator/prometheus
The CI workflow validates the project on push.
Current responsibilities:
- checkout source code
- set up Java
- run Maven build and tests
- verify the application builds successfully
Create the cluster:
kind create cluster --name spring-devops-labBuild the Docker image:
docker build -t spring-devops-lab-app:latest .Load the image into kind:
kind load docker-image spring-devops-lab-app:latest --name spring-devops-labApply Kubernetes manifests:
kubectl apply -f k8s/Verify resources:
kubectl get pods
kubectl get svc
kubectl get deploymentsAccess the application, depending on your chosen service setup, either through port-forwarding or through the configured local exposure.
The k8s/ folder also contains manifests for:
- Prometheus
ConfigMap,Deployment, andService - Grafana
ConfigMap,Deployment, andService
The application exposes these useful Actuator endpoints:
/actuator/health/actuator/health/liveness/actuator/health/readiness/actuator/prometheus
From the terraform/ folder:
terraform init
terraform validate
terraform applyTerraform files included in the project:
providers.tfvariables.tfmain.tfapp.tfpostgres.tfoutputs.tf
The k8s/ folder contains manifests for:
- application
ConfigMap - application
Secret - application
Deployment - application
Service - PostgreSQL
Secret - PostgreSQL
Deployment - PostgreSQL
Service - Prometheus
ConfigMap - Prometheus
Deployment - Prometheus
Service - Grafana
ConfigMap - Grafana
Deployment - Grafana
Service
The application reads database settings from environment variables:
SPRING_DATASOURCE_URLSPRING_DATASOURCE_USERNAMESPRING_DATASOURCE_PASSWORD
This keeps the application portable across local development, Docker Compose, and Kubernetes.
If local port 8080 is already occupied, stop the existing process or use a different local mapping.
Rebuild and reload the image into kind, then restart the deployment:
docker build -t spring-devops-lab-app:latest .
kind load docker-image spring-devops-lab-app:latest --name spring-devops-lab
kubectl rollout restart deployment/spring-devops-lab-appkubectl logs deployment/spring-devops-lab-app
kubectl logs deployment/postgres- Run application locally
- Run application with PostgreSQL
- Dockerize the application
- Add GitHub Actions CI
- Deploy on Kubernetes with kind
- Add monitoring with Prometheus and Grafana
- Add Terraform
- Add architecture diagram and screenshots
This repository includes a helper script to run Maven tests before each commit:
cp dev-tools/pre-commit-mvn-test.sh .git/hooks/pre-commit
chmod +x .git/hooks/pre-commitWith this in place, ./mvnw test will run automatically before each git commit.
If tests fail, the commit is aborted.
HELP.md is kept as the default Spring Boot helper file.
README.md is the main portfolio-oriented documentation for this repository.




