Skip to main content

Command Palette

Search for a command to run...

Deploying Spring PetClinic Microservices Locally with Docker Compose

Updated
10 min read
Deploying Spring PetClinic Microservices Locally with Docker Compose

Before moving the Spring PetClinic microservices application to the cloud, I first deployed it locally on my machine using Docker Compose.

This was an important step in my DevOps learning journey because it helped me understand how the application behaves before introducing cloud infrastructure, Kubernetes, GitOps, and AWS services.

Sometimes, it is easy to rush straight into cloud deployment, but local deployment gives you a clearer view of what is really happening inside the application. You get to see how the services start, how they communicate, how failures appear, and how monitoring tools help you understand the system better.

For this project, the goal was to bring up the full Spring PetClinic microservices stack locally with one command:

docker compose up -d

That one command started the application services and the observability stack.


Project Overview

Spring PetClinic is not a single application. It is a distributed microservices application made up of different services that work together.

The local deployment included:

  • Config Server

  • Discovery Server / Eureka

  • API Gateway

  • Customers Service

  • Visits Service

  • Vets Service

  • Admin Server

  • GenAI Service

  • Prometheus

  • Grafana

  • Zipkin

  • Spring Boot Admin

The application services were responsible for handling the business logic, while the monitoring and observability tools helped me understand what was happening inside the system.

The full stack included Prometheus for metrics, Grafana for dashboards, Zipkin for distributed tracing, and Spring Boot Admin for service health, logs, JVM details, and runtime insight.


Why I Started with Local Deployment

Before deploying to AWS, I wanted to answer a few questions:

  • Can all the services run successfully on my machine?

  • Do the services start in the right order?

  • Can the microservices discover and communicate with each other?

  • Can I access the application through the API Gateway?

  • Can I observe metrics, traces, and service health locally?

Running the application locally helped me build confidence before moving to a cloud environment.

It also helped me understand the foundation of the system. If the application does not work locally, troubleshooting it in the cloud becomes much harder.


Tools and Requirements

To run the project locally, I needed:

  • Git

  • Java 17

  • Docker or Docker Desktop

  • Docker Compose

  • Enough Docker memory allocation

One important thing I learned is that Docker needs enough memory for this kind of microservices setup. The guide recommends allocating at least 6 to 8 GB of RAM in Docker Desktop because the default memory limit can make startup very slow.

Since the project builds against Java 17, it was also important to confirm the correct Java version before building the application.

java -version
docker --version
docker info

These checks helped confirm that Java was installed correctly and that Docker was running.


Cloning the Repository

The first step was to clone the Spring PetClinic microservices repository:

git clone https://github.com/official-mary/spring-petclinic-microservices.git
cd spring-petclinic-microservices

This gave me access to the full application code, Docker configuration, and deployment files needed to run the stack locally.


Building the Docker Images

Before starting the services, I had to build the Docker images.

From the project root, the build command was:

./mvnw clean install -P buildDocker

On Windows, the command is:

mvnw.cmd clean install -P buildDocker

The first build took some time because Maven had to compile multiple modules and download dependencies.

This part helped me understand that each microservice had its own build process, but everything still came together as one distributed application.


Starting Everything with One Command

After building the images, I started the full stack with:

docker compose up -d

This was the most interesting part for me.

With just one command, Docker Compose started the full microservices environment, including the application services and monitoring tools.

The -d flag allowed the containers to run in detached mode, meaning they continued running in the background while I used the terminal for other checks.

What made this even more interesting was the startup order. The Docker Compose setup used health checks and service dependencies so that the Config Server and Discovery Server could come up first before the other services started.

That made sense because the other services depended on them.


Understanding the Startup Order

In a microservices application, startup order matters.

The Config Server provides centralized configuration for the services. If it is not available, other services may not be able to load the configuration they need.

The Discovery Server, also known as Eureka, acts as the service registry. The services register themselves there so they can discover and communicate with one another.

So the flow looked like this:

Config Server starts
        ↓
Discovery Server starts
        ↓
Business services start
        ↓
API Gateway starts
        ↓
Monitoring tools observe the system

This helped me understand that microservices are not just independent containers running side by side. They are connected services with dependencies, communication patterns, and startup requirements.


Verifying the Deployment

After starting the stack, I had to verify that everything was running correctly.

The first check was:

docker compose ps

This showed the status of the containers.

Then I checked the Eureka dashboard:

http://localhost:8761

From Eureka, I could confirm that the main services were registered and showing as UP.

I also opened the application through the API Gateway:

http://localhost:8080

This was the main entry point for the Spring PetClinic application.

From there, I could browse the application and confirm that pages like Owners and Veterinarians were loading properly.


Service URLs

These were the main local URLs used during the deployment:

PetClinic App / API Gateway: http://localhost:8080
Eureka Discovery Server: http://localhost:8761
Config Server: http://localhost:8888
Prometheus: http://localhost:9091
Grafana: http://localhost:3030
Zipkin: http://localhost:9411/zipkin/
Spring Boot Admin: http://localhost:9090

Having all these tools available locally made the deployment feel closer to a real production-like environment.


Observability Stack

One of the best parts of this local deployment was the observability stack.

The setup included:

  • Prometheus

  • Grafana

  • Zipkin

  • Spring Boot Admin

These tools helped me move beyond just asking, “Is the application running?”

Instead, I could ask better questions like:

  • Are the services healthy?

  • Are the endpoints responding?

  • What metrics are being collected?

  • How are requests moving between services?

  • Where is latency happening?

  • Which service is registered or failing?

That made the project much more practical.


Prometheus: Metrics Collection

Prometheus was available at:

http://localhost:9091

Each Spring Boot service exposes metrics through Spring Boot Actuator and Micrometer, and Prometheus scrapes those metrics.

In Prometheus, I could check the targets and confirm whether the service endpoints were UP.

I also explored example metrics like:

jvm_memory_used_bytes
http_server_requests_seconds_count
petclinic_owner_seconds_count

This helped me understand how metrics give visibility into application behavior and resource usage.


Grafana: Visual Dashboards

Grafana was available at:

http://localhost:3030

The Prometheus datasource was already configured, and the setup included a pre-built dashboard for Spring PetClinic metrics.

Grafana made the metrics easier to understand because it displayed them visually.

Instead of looking at raw metric queries only, I could view dashboards showing application and system performance.

This helped me see why dashboards are important in DevOps and operations work. They make it easier to monitor systems, detect issues, and understand what is happening over time.


Zipkin: Distributed Tracing

Zipkin was available at:

http://localhost:9411/zipkin/

This was one of the most interesting tools for me.

Because Spring PetClinic is a microservices application, a single user action may pass through more than one service.

For example, opening an owner’s page could involve communication between the API Gateway, Customers Service, and Visits Service.

With Zipkin, I could generate traffic by clicking around the application, then run a query to see recent traces.

This helped me understand the path a request followed and how much time was spent in each part of the system.

Distributed tracing made the invisible movement between services easier to see.


Spring Boot Admin: Service Health and Runtime Insight

Spring Boot Admin was available at:

http://localhost:9090

This tool showed live information about the registered services.

It helped me view:

  • Service health

  • Logs

  • Metrics

  • JVM details

  • Environment information

  • Runtime log levels

This was useful because it gave a central place to inspect the state of the services.

For a microservices application, having this kind of visibility is very helpful because checking each service manually can become stressful.


What I Found Most Interesting

The most interesting part of this deployment was seeing how much happened from one command.

At first, docker compose up -d looks simple.

But behind that command, several things happen:

  • Containers are created

  • Services start in order

  • Health checks run

  • Services register with Eureka

  • The API Gateway routes traffic

  • Metrics are exposed

  • Prometheus scrapes metrics

  • Grafana visualizes metrics

  • Zipkin traces requests

  • Spring Boot Admin monitors service health

That helped me appreciate Docker Compose more.

It is not only useful for starting containers. It can also help simulate a full microservices environment locally.


Challenges and Lessons Learned

One lesson I learned is that microservices need patience during startup.

Sometimes the API Gateway may return timeouts immediately after startup because Eureka registration and service discovery can take one or two minutes.

Instead of assuming something is broken immediately, I learned to check Eureka, wait for services to register, and then retry the application.

Another lesson was the importance of Docker memory allocation. A full microservices stack can be heavy, so Docker Desktop needs enough memory to run smoothly.

I also learned that observability is not optional. Without tools like Prometheus, Grafana, Zipkin, and Spring Boot Admin, it would be much harder to understand what was happening inside the system.


Stopping the Stack

To stop and remove the running containers, I used:

docker compose down

To remove the containers and volumes, the command is:

docker compose down -v

This is useful when you want to clean up the environment completely and start fresh.


Final Thoughts

Deploying Spring PetClinic locally helped me understand microservices beyond theory.

I saw how services depend on configuration, discovery, routing, monitoring, and tracing to work properly as one system.

The biggest lesson for me was that local deployment is not a small step. It is the foundation for understanding the application before moving to cloud deployment.

Before deploying to AWS, Kubernetes, or GitOps, it is important to first understand how the application behaves locally.

This project gave me practical experience with Docker Compose, microservices, service discovery, observability, and troubleshooting.

It also made the cloud deployment phase easier to understand because I already had a clearer picture of how the services worked together.

DMI Cohort 3 starts on 27 June.

If you want to build real DevOps skills through hands-on projects, you can apply here:

👉 https://docs.google.com/forms/d/e/1FAIpQLSel7ai7nyb0P1qLW4vEyfB\_nEsD4lUF1XG88vmAaFGBOb6hPA/viewform

#DMI #DevOps #Docker #Microservices #AWS #TheCloudAdvisory

9 views