Deploying Spring Petclinic Microservices with Docker Compose, Prometheus, Grafana, and Zipkin

Introduction
As part of the DevOps Micro Internship (DMI) Cohort 2 Final Assessment, I deployed the Spring Petclinic Microservices application locally using Docker Compose and validated its observability stack using Prometheus, Grafana, and Zipkin.
Spring Petclinic is a sample cloud-native application built with Spring Boot and Spring Cloud. Unlike a traditional monolithic application, it is composed of multiple microservices that work together to provide functionality such as customer management, veterinarian management, visit tracking, service discovery, centralized configuration, monitoring, and distributed tracing.
The goal of this deployment was to understand how microservices are deployed, how services communicate with one another, and how observability tools help engineers monitor application health and performance.
Prerequisites
Before starting the deployment, I ensured the following tools were installed on my machine:
Docker Desktop
Docker Compose
Git
Web Browser (for accessing dashboards)
To verify the installation, I ran:
git --version
docker --version
docker compose version
docker ps
docker info
All tools were successfully installed and operational.
Cloning the Repository
The first step was to clone the project repository.
mkdir -p ~/dmi-petclinic
cd ~/dmi-petclinic
git clone https://github.com/Petcare-Clinic/petcareClinic-cloudops.git
cd petcareClinic-cloudops
After cloning the repository, I located the Docker Compose configuration file:
find . -name "docker-compose*" -o -name "compose.yml" -o -name "compose.yaml"
The compose file was located inside the upstream directory.
cd upstream
To verify the services included in the deployment:
docker compose config --services
This showed multiple services including:
Config Server
Discovery Server
API Gateway
Customers Service
Visits Service
Vets Service
Admin Server
GenAI Service
Prometheus
Grafana
Zipkin
Deploying the Application
To start all services, I executed:
docker compose up -d
Docker automatically:
Pulled required images
Built custom monitoring images
Created the Docker network
Started all containers
To verify deployment status:
docker compose ps
All containers were successfully running.
Verifying Application Access
After deployment, I validated that every service was accessible through the browser.
Spring Petclinic
http://localhost:8080
Eureka Discovery Server
http://localhost:8761
Spring Boot Admin
http://localhost:9090
Zipkin
http://localhost:9411
Prometheus
http://localhost:9091
Grafana
http://localhost:3030
All dashboards loaded successfully, confirming a healthy deployment.
Why Config Server and Discovery Server Start First
One important concept I observed during this deployment was service startup order.
The Config Server and Discovery Server are foundational services that the remaining microservices depend on.
Config Server
The Config Server provides centralized configuration for all application services. Without it, the services would not receive the settings required for startup.
Discovery Server (Eureka)
The Discovery Server allows services to register themselves and discover other services dynamically across the environment.
If application services attempt to start before these two components become available, they may fail to initialize or register correctly.
This is why Docker Compose uses startup dependencies to ensure these services become healthy before the rest of the application stack starts.
Exploring the Observability Stack
One of the most valuable parts of this deployment was exploring the observability tools.
Prometheus
Prometheus collected metrics from the application and infrastructure.
I verified metric collection by running queries such as:
http_server_requests_seconds_count
Prometheus provided insight into request volume and application behavior.
Grafana
Grafana visualized the metrics collected by Prometheus.
The dashboards displayed:
Request metrics
JVM metrics
Service health information
Performance trends
This made it much easier to understand the overall state of the application.
Zipkin
Zipkin provided distributed tracing capabilities.
After interacting with the Petclinic application by searching owners, creating records, and viewing pet information, traces appeared in Zipkin.
These traces showed how requests moved across multiple services, helping identify service interactions and potential bottlenecks.
Challenges Encountered
The most time-consuming part of the deployment was waiting for Docker to download and build the required images during the first execution.
Because several services needed to start in sequence, I had to carefully monitor container health and wait for the Config Server and Discovery Server to become available before the remaining services fully initialized.
Although no critical errors occurred, observing the startup sequence helped me better understand dependency management within microservice architectures.
Key Lessons Learned
This project reinforced several important DevOps concepts:
Deploying applications with Docker Compose
Managing microservice dependencies
Understanding service discovery
Working with centralized configuration
Monitoring applications using Prometheus
Visualizing metrics with Grafana
Using Zipkin for distributed tracing
Most importantly, I gained practical experience with observability, which is essential for operating applications in production environments.
Conclusion
Deploying Spring Petclinic provided a realistic introduction to cloud-native application architecture and observability. Seeing multiple services communicate successfully while monitoring them through Prometheus, Grafana, and Zipkin helped me understand how modern applications are managed in real-world environments.
This deployment was completed as part of the DevOps Micro Internship (DMI) Cohort 2 Final Assessment and served as a valuable hands-on learning experience in my DevOps and Cloud Engineering journey.
Interested in joining the next cohort?
DMI Cohort 3 Registration:
https://discord.pravinmishra.com/
Thank you for reading.

