Skip to main content

Command Palette

Search for a command to run...

🐳 Dockerizing a Three-Tier Java Spring Boot Application with Docker Compose & MySQL

If you are learning Docker, DevOps, Java, Spring Boot, or CI/CD, building a real multi-container application is one of the best ways to understand how containerization works in a practical environment.

Updated
β€’34 min readβ€’View as Markdown
🐳 Dockerizing a Three-Tier Java Spring Boot Application with Docker Compose & MySQL
H
πŸ‘‹ Hi, I’m Hritik Ranjan β€” a B.Tech CSE student and a passionate tech enthusiast focused on Quality Engineering, AI/ML, Cybersecurity, and DevOps. πŸ’‘ I enjoy building and testing scalable, secure, and intelligent systems that solve real-world problems. My expertise and interests include: πŸ”Ή Quality Assurance & Testing Hands-on experience in manual and automation testing using Selenium & Java, ensuring high-quality and reliable applications. πŸ”Ή Artificial Intelligence & Machine Learning Exploring advanced algorithms and developing intelligent systems for practical use cases. πŸ”Ή Cybersecurity Focused on vulnerability assessment, security testing, and system hardening. πŸ”Ή Web Development Building responsive and user-friendly applications using modern technologies. πŸ”Ή Data Science Analyzing complex data to extract actionable insights. πŸ’Ό Key Projects: πŸš€ Blindness Detection System Applied computer vision techniques to detect blindness-related conditions. πŸš€ AI-Powered Rail Madad Enhancement Developed an intelligent complaint management system to improve railway customer service. πŸš€ Interactive Applications Built multiple projects like quiz apps, calculators, and productivity tools. 🌱 I’m continuously learning and improving my skills in DevOps, Cloud, and Automation to become a well-rounded engineer. 🀝 Open to collaborations, internships, and opportunities in QA, DevOps, AI/ML, and Cybersecurity. πŸ“« Let’s connect: hritikranjan1408@gmail.com

In this project, I deployed a three-tier Java Spring Boot application using Docker and Docker Compose.

The application contains:

  • β˜• Java Spring Boot backend

  • πŸ—„οΈ MySQL database

  • 🐳 Docker containers

  • βš™οΈ Docker Compose

  • πŸ“¦ Maven

  • πŸ”— Docker networking

  • πŸ’Ύ Docker volumes

  • ❀️ Healthchecks

  • πŸ” Environment variables

  • πŸ—οΈ Multi-stage Docker build

  • πŸ”„ Automatic restart policies

The goal was not simply to run a Java application inside Docker.

The goal was to understand how a Java application, database, networking, configuration, persistence, and container orchestration work together.


πŸ“Œ Table of Contents

  1. What Are We Building?

  2. Project Overview

  3. Why Dockerize a Spring Boot Application?

  4. Application Architecture

  5. Technology Stack

  6. How the Application Works

  7. Project Structure

  8. Spring Boot Application

  9. Maven and pom.xml

  10. Application Properties

  11. Environment Variables

  12. Dockerfile

  13. Why Use a Multi-Stage Dockerfile?

  14. Docker Build Stage

  15. Docker Runtime Stage

  16. MySQL Database

  17. Docker Networking

  18. Docker Volumes

  19. Docker Compose

  20. Healthchecks

  21. Restart Policies

  22. Complete Setup

  23. Clone the Project

  24. Build and Start Containers

  25. Check Running Containers

  26. Access the Application

  27. Check Application Logs

  28. Check MySQL Logs

  29. Connect to MySQL

  30. Useful Docker Commands

  31. Troubleshooting

  32. Common Problems

  33. Security Best Practices

  34. Why Multi-Stage Builds Matter

  35. DevOps Concepts Demonstrated

  36. Interview Explanation

  37. Interview Questions

  38. Future Improvements

  39. What I Learned

  40. Conclusion


πŸš€ What Are We Building?

We are taking a Java Spring Boot application and converting it into a containerized application.

The final architecture contains two main Docker services:

                    USER
                     |
                     ↓
              Spring Boot App
                     |
                     ↓
                  MySQL
                     |
                     ↓
              Docker Volume

Docker Compose manages these services.

Instead of installing Java, Maven and MySQL directly on the host machine, we package the application and database into containers.

The result is a reproducible environment that can be started with a single command.


πŸ“‹ Project Overview

This project demonstrates how to deploy a Spring Boot application using Docker Compose.

The architecture contains:

β˜• Application

A Java Spring Boot application built using Maven.

πŸ—„οΈ Database

A MySQL database responsible for storing application data.

🐳 Docker

Docker packages the application and its environment into containers.

βš™οΈ Docker Compose

Docker Compose manages the complete multi-container environment.

πŸ’Ύ Volume

A Docker volume keeps MySQL data persistent.

❀️ Healthcheck

A healthcheck verifies whether MySQL is actually ready.


πŸ€” Why Dockerize a Spring Boot Application?

Normally, deploying a Spring Boot application requires:

Java
Maven
Application dependencies
MySQL
Database configuration
Environment configuration

Different machines can have different versions of these components.

For example:

Developer Machine
Java 17
Maven version A
MySQL version X

        ↓

Production Machine
Java 21
Maven version B
MySQL version Y

This can create compatibility problems.

Docker allows us to package the application environment into reproducible containers.

The deployment becomes:

Source Code
     ↓
Docker Image
     ↓
Container
     ↓
Application

The same image can then be used in:

Development
     ↓
Testing
     ↓
Staging
     ↓
Production

πŸ—οΈ Application Architecture

The project follows a simple three-tier architecture:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚          USER           β”‚
β”‚       Web Browser       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
             β”‚
             β”‚ HTTP
             ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚     SPRING BOOT APP     β”‚
β”‚                         β”‚
β”‚        Java             β”‚
β”‚        Spring Boot      β”‚
β”‚        Thymeleaf        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
             β”‚
             β”‚ MySQL :3306
             ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚          MYSQL          β”‚
β”‚                         β”‚
β”‚       Database          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
             β”‚
             ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚     DOCKER VOLUME       β”‚
β”‚   Persistent Database   β”‚
β”‚          Data           β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Docker Compose manages the application and database services.


🧰 Technology Stack

Technology Purpose
Java Programming language
Spring Boot Application framework
Maven Build and dependency management
Thymeleaf Server-side UI templating
MySQL Relational database
Docker Containerization
Docker Compose Container orchestration
Docker Network Service communication
Docker Volume Persistent storage
Healthcheck Service readiness
Environment Variables Configuration management

πŸ”„ How the Application Works

When the user opens the application:

Browser
   |
   ↓
Spring Boot Container
   |
   ↓
Spring Boot processes request
   |
   ↓
Application communicates with MySQL
   |
   ↓
MySQL returns data
   |
   ↓
Spring Boot processes data
   |
   ↓
Thymeleaf generates response
   |
   ↓
Browser

The important part is that the Java application and MySQL database are running in separate containers.


πŸ“ Project Structure

A typical structure can look like:

java-docker-project/
β”‚
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ main/
β”‚   β”‚   β”œβ”€β”€ java/
β”‚   β”‚   └── resources/
β”‚   β”‚       β”œβ”€β”€ templates/
β”‚   β”‚       └── application.properties
β”‚   β”‚
β”‚   └── test/
β”‚
β”œβ”€β”€ pom.xml
β”œβ”€β”€ Dockerfile
β”œβ”€β”€ docker-compose.yml
└── README.md

The most important files are:

pom.xml
Dockerfile
docker-compose.yml
application.properties

Each file has a different responsibility.


β˜• Spring Boot Application

Spring Boot provides the main application framework.

It handles:

  • HTTP requests

  • Business logic

  • Database communication

  • Application configuration

  • Dependency management

  • Web interface

The application can use Thymeleaf for server-side HTML rendering.

The architecture is therefore:

Browser
   ↓
Spring Boot
   ↓
Thymeleaf
   ↓
MySQL

πŸ“¦ Maven and pom.xml

Maven is the build and dependency management tool used by the Java application.

The main configuration file is:

pom.xml

The POM defines project information and dependencies.

For example:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.2.2</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.Spring-Boot-MVC</groupId>
	<artifactId>ExpensesTracker</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>ExpensesTracker</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>17</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-security</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-validation</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.thymeleaf.extras</groupId>
			<artifactId>thymeleaf-extras-springsecurity6</artifactId>
		</dependency>

		<dependency>
			<groupId>com.mysql</groupId>
			<artifactId>mysql-connector-j</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

The exact dependencies depend on the application.


πŸ”¨ Maven Build

Maven can compile and package the application.

A common command is:

mvn clean install

Let's understand it.

clean

Removes previously generated build files.

install

Compiles, tests and packages the application and installs the generated artifact into the local Maven repository.

The final output is generally a JAR file:

target/
    application.jar

This JAR file is what we ultimately need in the runtime Docker container.


βš™οΈ Application Properties

Spring Boot commonly stores configuration in:

application.properties

For example:

spring.datasource.url=jdbc:mysql://db:3306/testdb
spring.datasource.username=root
spring.datasource.password=root

spring.jpa.hibernate.ddl-auto=update

Here:

db

is the MySQL service name.

This is important.

Inside Docker Compose:

Spring Boot Container
        |
        ↓
      db:3306
        |
        ↓
MySQL Container

We don't normally use:

localhost

for the database hostname when the database is in another container.


πŸ” Environment Variables

Hardcoding database credentials inside source code is not recommended.

Instead, Spring Boot properties can be overridden using environment variables.

For example:

spring.datasource.url

can be mapped to:

SPRING_DATASOURCE_URL

Similarly:

spring.datasource.username

becomes:

SPRING_DATASOURCE_USERNAME

and:

spring.datasource.password

becomes:

SPRING_DATASOURCE_PASSWORD

The naming convention is:

spring.datasource.url
        ↓
SPRING_DATASOURCE_URL
spring.datasource.username
        ↓
SPRING_DATASOURCE_USERNAME
spring.datasource.password
        ↓
SPRING_DATASOURCE_PASSWORD

This is a very useful Spring Boot + Docker concept.


🐳 Dockerfile

The Dockerfile describes how the Java application image is built.

Instead of creating a single huge image, this project uses a multi-stage Docker build.

The architecture is:

Stage 1
Maven Builder
      ↓
Compile Application
      ↓
Create JAR
      ↓
Stage 2
Runtime Image
      ↓
Run JAR

This is an important Docker optimization technique.


πŸ—οΈ Why Use a Multi-Stage Dockerfile?

Suppose we use one image for everything:

Java
+
Maven
+
Source Code
+
Build Tools
+
Dependencies
+
JAR

The final image may become unnecessarily large.

But the production container only needs:

Java Runtime
+
Application JAR

Therefore, multi-stage builds separate:

BUILD ENVIRONMENT

from:

RUNTIME ENVIRONMENT

πŸ”¨ Docker Build Stage

The first stage uses a Maven image.

Conceptually:

# Stage 1: Build JAR
FROM maven:3.9-eclipse-temurin-17-alpine AS builder
WORKDIR /app

COPY . .

# Build the executable jar (skipping unit tests)
RUN mvn clean package -DskipTests

# Stage 2: Run Application
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app

COPY --from=builder /app/target/*.jar /app/expenseapp.jar

EXPOSE 8080

CMD ["java", "-jar", "expenseapp.jar"]

The builder stage:

  1. Starts with Maven

  2. Sets working directory

  3. Copies project files

  4. Downloads dependencies

  5. Compiles the application

  6. Runs the Maven build

  7. Produces the JAR file

The result may look like:

target/
   └── application.jar

πŸš€ Docker Runtime Stage

The second stage uses a smaller Java runtime image.

Conceptually:

FROM eclipse-temurin:...-jre

WORKDIR /app

COPY --from=builder /app/target/*.jar app.jar

EXPOSE 8080

ENTRYPOINT ["java", "-jar", "app.jar"]

The important line is:

COPY --from=builder

This means:

Copy the required application artifact from the builder stage into the runtime stage.

The final image doesn't need:

Maven
Source Code
Build Tools

It only needs the application runtime and JAR.


πŸ“¦ Multi-Stage Build Flow

The complete process is:

pom.xml
   |
   ↓
Maven Builder Container
   |
   ↓
mvn clean install
   |
   ↓
application.jar
   |
   ↓
Runtime Java Image
   |
   ↓
Java + application.jar

This produces a cleaner and more efficient final image.


πŸ—„οΈ MySQL Database

MySQL runs in its own container.

For example:

MySQL Container
      |
      ↓
Database

The Spring Boot application communicates with MySQL through the Docker network.

Example:

Spring Boot
     |
     ↓
db:3306
     |
     ↓
MySQL

The default MySQL port is:

3306

πŸ”— Docker Networking

Docker Compose creates a network for the services.

For example:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚          Docker Network           β”‚
β”‚                                   β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚ Spring Boot │──→│   MySQL   β”‚ β”‚
β”‚  β”‚    app      β”‚   β”‚    db     β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚                                   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

The application can connect using:

db:3306

instead of using a hardcoded container IP.

Docker's internal DNS resolves the service name.

This is one of the biggest advantages of Compose networking.


πŸ’Ύ Docker Volumes

Database persistence is extremely important.

Without a volume:

MySQL Container
       ↓
Database Data

If the container is removed, database data can be lost.

With a volume:

MySQL Container
       ↓
Docker Volume
       ↓
Persistent Data

For example:

volumes:
  mysql_data:

Then:

services:

  db:
    volumes:
      - mysql_data:/var/lib/mysql

Now the lifecycle becomes:

Container Deleted
       ↓
Volume Remains
       ↓
Database Data Remains

This is why Docker volumes are critical for stateful services such as databases.


βš™οΈ Docker Compose

Docker Compose is the central orchestration file.

Usually:

docker-compose.yml

contains:

services:

version: "3.8"

services:
  mysql_db:
    image: mysql:8.0
    container_name: mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: "Test@123"
      MYSQL_DATABASE: expenses_tracker
    ports:
      - "3306:3306"
    networks:
      - expense-app-nw
    healthcheck:
      test: ["CMD-SHELL", "mysqladmin ping -pTest@123 --silent"]
      interval: 5s
      timeout: 5s
      retries: 10
      start_period: 30s
    volumes:
      - mysql_data:/var/lib/mysql

  java_app:
    build:
      context: .
    container_name: expenseapp
    restart: always
    ports:
      - "8081:8080"
    environment:
      SPRING_DATASOURCE_URL: "jdbc:mysql://mysql_db:3306/expenses_tracker?allowPublicKeyRetrieval=true&useSSL=false"
      SPRING_DATASOURCE_USERNAME: root
      SPRING_DATASOURCE_PASSWORD: "Test@123"
    depends_on:
      mysql_db:
        condition: service_healthy
    networks:
      - expense-app-nw

networks:
  expense-app-nw:
    driver: bridge

volumes:
  mysql_data:

Compose can define:

  • Services

  • Images

  • Builds

  • Ports

  • Environment variables

  • Networks

  • Volumes

  • Healthchecks

  • Dependencies

  • Restart policies

Instead of manually running multiple Docker commands, Compose lets us define the entire application architecture as code.


🧩 Example Docker Compose Structure

A simplified example:

services:

  app:
    build: .
    container_name: java_app
    ports:
      - "8080:8080"

    environment:
      SPRING_DATASOURCE_URL: jdbc:mysql://db:3306/testdb
      SPRING_DATASOURCE_USERNAME: root
      SPRING_DATASOURCE_PASSWORD: root

    depends_on:
      db:
        condition: service_healthy

    restart: always

  db:
    image: mysql:8
    container_name: mysql_db

    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: testdb

    volumes:
      - mysql_data:/var/lib/mysql

    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5

    restart: always

volumes:
  mysql_data:

This is a simplified example. Adjust image versions, credentials, database names and application configuration according to your actual project.


❀️ Healthchecks

One of the most important parts of this project is the MySQL healthcheck.

Simply checking:

Container = Running

does not necessarily mean:

MySQL = Ready

MySQL may take some time to initialize.

Without a healthcheck:

MySQL Container Starts
        ↓
Spring Boot Starts
        ↓
Spring Boot Connects
        ↓
MySQL Not Ready
        ↓
Connection Failure

With a healthcheck:

MySQL Starts
    ↓
Healthcheck
    ↓
MySQL Ready?
    ↓
YES
    ↓
Spring Boot Starts

🩺 MySQL Healthcheck

A common healthcheck is:

healthcheck:
  test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
  interval: 10s
  timeout: 5s
  retries: 5

The command:

mysqladmin ping

checks whether MySQL is responding.


πŸ”„ depends_on with Healthcheck

Docker Compose can use the health status:

depends_on:
  db:
    condition: service_healthy

This tells Compose:

Start the application after the database service reports a healthy status.

This is better than relying only on container startup order.


πŸ” Restart Policies

A container may stop because of:

  • Application crash

  • Temporary failure

  • Server issue

  • Unexpected error

A restart policy can automatically restart it.

For example:

restart: always

This means Docker should restart the container when appropriate.

Restart policies improve application resilience.

However, restart policies are not a replacement for proper monitoring and troubleshooting.


πŸ’» Complete Setup

Let's now deploy the application.


1️⃣ Install Docker

First install Docker Desktop or Docker Engine depending on your operating system.

Verify:

docker --version

Then:

docker compose version

2️⃣ Clone the Repository

Clone the project:

git clone https://github.com/hritikranjan1/Expenses-Tracker-WebApp.git

Move into the project:

cd Expenses-Tracker-WebApp

3️⃣ Check Project Files

Verify:

pom.xml
Dockerfile
docker-compose.yml
src/

For example:

ls

On Windows:

dir

4️⃣ Configure Database Properties

Configure Spring Boot to use the MySQL service.

For example:

spring.datasource.url=jdbc:mysql://db:3306/testdb
spring.datasource.username=root
spring.datasource.password=root

Or provide these through environment variables.


5️⃣ Build and Start Containers

Run:

docker compose up -d --build

This command:

Reads docker-compose.yml
        ↓
Builds Spring Boot image
        ↓
Pulls MySQL image
        ↓
Creates network
        ↓
Creates volume
        ↓
Creates containers
        ↓
Starts MySQL
        ↓
Runs healthcheck
        ↓
Starts Spring Boot

πŸ” Check Running Containers

Run:

docker compose ps

or:

docker ps

You should see something similar to:

NAME        STATUS
java_app    Up
mysql_db    Up (healthy)

The important thing is that MySQL should eventually show:

healthy

🌍 Access the Application

If Spring Boot exposes port 8080:

http://localhost:8080

Open it in your browser.

The request flow becomes:

Browser
   ↓
localhost:8080
   ↓
Spring Boot Container
   ↓
MySQL Container

πŸ“œ Check Application Logs

To see Spring Boot logs:

docker logs java_app

Follow logs:

docker logs -f java_app

You may see Spring Boot startup information.

Look for messages indicating that the application has successfully started.


πŸ—„οΈ Check MySQL Logs

Run:

docker logs mysql_db

Follow:

docker logs -f mysql_db

Look for messages indicating MySQL is ready to accept connections.


πŸ”Œ Connect to MySQL

You can enter the MySQL container:

docker exec -it mysql_db mysql -uroot -p

Enter the configured password.

Then:

SHOW DATABASES;

Select the application database:

USE testdb;

Check tables:

SHOW TABLES;

Exit:

exit;

πŸ§ͺ Test the Application

Testing should happen at multiple levels.

Test 1 β€” Container

docker ps

Test 2 β€” MySQL

docker exec -it mysql_db mysqladmin ping -uroot -p

Test 3 β€” Spring Boot

Open:

http://localhost:8080

Test 4 β€” Logs

docker logs java_app

This gives a structured way to verify the deployment.


🧰 Useful Docker Commands

Build image

docker compose build

Start containers

docker compose up -d

Build and start

docker compose up -d --build

Stop containers

docker compose stop

Stop and remove containers

docker compose down

Remove containers and volumes

docker compose down -v

⚠️ Be careful with:

docker compose down -v

because it can remove the MySQL volume and therefore the persistent database data.


πŸ“¦ Image Commands

List Docker images:

docker images

Remove an image:

docker rmi <image-name>

Build manually:

docker build -t springboot-app .

Run manually:

docker run -p 8080:8080 springboot-app

For this project, Docker Compose is preferred because we have multiple services.


πŸ”Ž Container Inspection

Inspect the application container:

docker inspect java_app

Inspect MySQL:

docker inspect mysql_db

This can help investigate:

  • Network

  • Volumes

  • Environment

  • Container configuration

  • IP addresses

  • Mounts


🌐 Check Docker Network

List networks:

docker network ls

Inspect a network:

docker network inspect <network-name>

This can show which containers are connected.

For example:

java_app
   |
   +------ Docker Network ------+
                              |
                              ↓
                           mysql_db

πŸ’Ύ Check Docker Volumes

List volumes:

docker volume ls

Inspect a volume:

docker volume inspect <volume-name>

The volume is responsible for keeping MySQL data persistent.


🐞 Troubleshooting

Troubleshooting is an important DevOps skill.

When the application doesn't work, don't immediately rebuild everything.

Follow a structured process.


❌ Problem 1: Spring Boot Cannot Connect to MySQL

Possible error:

Communications link failure

or:

Connection refused

Check MySQL:

docker compose ps

Then:

docker logs mysql_db

Make sure MySQL is healthy.

Also verify:

Database hostname
Database port
Database name
Username
Password

❌ Problem 2: Using localhost for MySQL

A common mistake is:

spring.datasource.url=jdbc:mysql://localhost:3306/testdb

If MySQL is in another container, this may not work as expected.

Instead use the Compose service name:

spring.datasource.url=jdbc:mysql://db:3306/testdb

The concept is:

Spring Boot Container
       |
       ↓
       db:3306
       |
       ↓
MySQL Container

❌ Problem 3: MySQL Is Running But Application Still Fails

Check:

docker compose ps

A running container does not always mean the service is ready.

Check health:

docker inspect mysql_db

Check logs:

docker logs mysql_db

This is where healthchecks become useful.


❌ Problem 4: Port 8080 Already in Use

You may see:

Bind for 0.0.0.0:8080 failed

This means another application is using port 8080.

You can change:

ports:
  - "8081:8080"

Now access:

http://localhost:8081

The important distinction is:

Host Port : Container Port

So:

8081:8080

means:

Host β†’ 8081
Container β†’ 8080

❌ Problem 5: Docker Build Fails

Check:

docker compose build

Look carefully at the error.

Common causes:

  • Incorrect Maven dependency

  • Network issue while downloading dependencies

  • Incorrect Java version

  • Invalid Dockerfile

  • Incorrect source path

  • Build failure in Maven

You can test Maven locally:

mvn clean install

If the Maven build fails outside Docker, fix the application first.


❌ Problem 6: Container Keeps Restarting

Check:

docker ps -a

Then:

docker logs java_app

The logs usually provide the actual reason.

Possible causes:

Application crash
Database connection failure
Configuration error
Missing environment variable
Incorrect Java version
Incorrect JAR path

❌ Problem 7: Database Data Disappears

Check whether a volume is configured:

docker volume ls

If MySQL is running without persistent storage, removing the container may remove the database data.

Use:

volumes:
  - mysql_data:/var/lib/mysql

and define:

volumes:
  mysql_data:

πŸ” Security Best Practices

For learning, you may see configurations such as:

root
root

But this should not be used in production.

Production systems should follow stronger security practices.

1. Don't use root for the application

Create a dedicated MySQL user.

2. Use strong passwords

Never use simple credentials in production.

3. Don't commit secrets

Never push:

.env

or credentials into GitHub.

4. Use secrets management

Use a proper secret-management system in production.

5. Keep database private

Don't expose MySQL publicly unless there is a specific requirement.

6. Use HTTPS

Production web applications should use TLS.

7. Scan Docker images

Use image scanning tools to identify vulnerabilities.

8. Keep dependencies updated

Regularly update:

Java
Spring Boot
Maven dependencies
MySQL
Docker base images

9. Use non-root containers

Where practical, run applications using a non-root user.


🏭 Why Multi-Stage Builds Matter

Multi-stage builds are one of the most useful Docker optimization techniques for compiled applications such as Java applications.

Without multi-stage builds:

Final Image
|
+-- Maven
+-- JDK
+-- Source Code
+-- Build Dependencies
+-- JAR

With multi-stage builds:

Builder Image
|
+-- Maven
+-- JDK
+-- Source
+-- Dependencies
|
↓
JAR
|
↓
Runtime Image
|
+-- JRE
+-- JAR

Benefits:

  • Smaller final image

  • Faster deployment

  • Less unnecessary software

  • Reduced attack surface

  • Cleaner production containers

This is one of the major reasons to use multi-stage Docker builds for Java applications.


🎯 DevOps Concepts Demonstrated

This project demonstrates several important DevOps concepts.

🐳 Containerization

Java Application
      ↓
Docker Image
      ↓
Container

βš™οΈ Orchestration

Docker Compose
      ↓
Spring Boot + MySQL

πŸ”— Networking

Spring Boot
      ↓
Docker Network
      ↓
MySQL

πŸ’Ύ Persistent Storage

MySQL
  ↓
Docker Volume
  ↓
Persistent Data

❀️ Healthchecks

MySQL
  ↓
Healthcheck
  ↓
Healthy
  ↓
Spring Boot

πŸ” Configuration Management

Environment Variables
        ↓
Docker Compose
        ↓
Spring Boot

πŸ—οΈ Build Optimization

Maven Builder
      ↓
JAR
      ↓
Lightweight Runtime Image

🧠 Complete Deployment Flow

The entire project can be represented as:

                Developer
                    |
                    ↓
               Source Code
                    |
                    ↓
             Dockerfile
                    |
                    ↓
          Multi-Stage Build
                    |
           β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”
           ↓                 ↓
      Maven Builder      Runtime Image
           |                 |
           ↓                 ↓
      application.jar    Java Runtime
                             |
                             ↓
                     Spring Boot App
                             |
                             ↓
                       Docker Network
                             |
                             ↓
                          MySQL
                             |
                             ↓
                      Docker Volume

Docker Compose manages the runtime architecture.


πŸ’Ό How to Explain This Project in an Interview

If an interviewer asks:

"Explain your Docker project."

You can answer:

"I deployed a three-tier Java Spring Boot application using Docker and Docker Compose. The application uses Spring Boot for the backend, Maven for dependency management and building the application, and MySQL for persistent data storage. I created a multi-stage Dockerfile where the first stage uses Maven to build the application and generate the JAR file, while the second stage uses a lightweight Java runtime image to run only the required JAR. Docker Compose manages the application and database services, networking, environment variables, healthchecks, restart policies, and persistent volumes. The Spring Boot application connects to MySQL through the Docker network using the database service name rather than localhost. I also configured a MySQL healthcheck so the application doesn't attempt to connect before the database is ready."

This answer demonstrates that you understand both Docker commands and the underlying architecture.


❓ Interview Questions

1. Why did you use Docker Compose?

Because the project contains multiple services.

Docker Compose provides a simple way to define and manage those services together.


2. Why did you use a multi-stage Dockerfile?

To separate the build environment from the runtime environment and keep the final image smaller and cleaner.


3. What is the purpose of the Maven stage?

The Maven stage compiles the Java source code, downloads dependencies, runs the build and generates the JAR file.


4. Why don't you copy the complete source code into the runtime image?

The runtime container only needs the generated application artifact and Java runtime.

Keeping build tools and source code out of the runtime image reduces image size and attack surface.


5. Why does Spring Boot connect to db instead of localhost?

Because MySQL is running in a separate container.

Docker Compose provides service-name-based DNS, so the application can connect to:

db:3306

6. Why is a healthcheck needed?

Because MySQL may take time to become ready after its container starts.

The healthcheck lets Compose determine whether the database is actually ready.


7. Why use a Docker volume?

Because MySQL is stateful.

The volume keeps database data persistent even if the MySQL container is recreated.


8. What does restart: always do?

It tells Docker to restart the container when it stops according to the restart policy.


9. What is the purpose of pom.xml?

It defines the Maven project configuration, dependencies, plugins and build information.


10. How can Spring Boot properties be passed through Docker?

Using environment variables.

For example:

spring.datasource.url

can be represented as:

SPRING_DATASOURCE_URL

πŸš€ Future Improvements

This project can be extended into a complete production-style DevOps project.

1. Add Nginx

Architecture:

User
 ↓
Nginx
 ↓
Spring Boot
 ↓
MySQL

2. Add HTTPS

Configure SSL/TLS for secure communication.


3. Add CI/CD

For example:

GitHub
   ↓
GitHub Actions
   ↓
Maven Tests
   ↓
Docker Build
   ↓
Security Scan
   ↓
Docker Registry
   ↓
Deployment

4. Push Image to Docker Hub

Build:

docker build -t username/springboot-app .

Login:

docker login

Push:

docker push username/springboot-app

5. Deploy on AWS

The application can be deployed using:

AWS EC2

or container services such as:

Amazon ECS

6. Add Monitoring

Use:

Prometheus
+
Grafana

to monitor:

  • CPU

  • Memory

  • Application metrics

  • Request count

  • Response time


7. Add Centralized Logging

Production environments can use centralized logging solutions to collect logs from containers.


8. Move to Kubernetes

The Docker Compose architecture can be converted into Kubernetes resources:

Docker Compose
      ↓
Kubernetes
      ↓
Deployment
      ↓
Service
      ↓
ConfigMap
      ↓
Secret
      ↓
PersistentVolume

This would be the next step toward a more advanced cloud-native deployment.


πŸ“š What I Learned From This Project

This project helped me understand that Docker is not simply:

docker build
docker run

A real application requires:

Application
    +
Database
    +
Networking
    +
Storage
    +
Configuration
    +
Healthchecks
    +
Security
    +
Build Optimization

The most important concepts I practiced were:

  • Docker containerization

  • Docker images

  • Docker Compose

  • Spring Boot containerization

  • Maven builds

  • Multi-stage Dockerfiles

  • Docker networking

  • MySQL containers

  • Docker volumes

  • Healthchecks

  • Environment variables

  • Restart policies

  • Container logs

  • Container troubleshooting

  • Database persistence


πŸ† Why This Is a Good DevOps Portfolio Project

A basic Docker project might only demonstrate:

docker build
docker run

But this project demonstrates much more:

β˜• Spring Boot
       +
πŸ“¦ Maven
       +
🐳 Docker
       +
βš™οΈ Docker Compose
       +
πŸ—„οΈ MySQL
       +
πŸ”— Networking
       +
πŸ’Ύ Volumes
       +
❀️ Healthchecks
       +
πŸ” Environment Variables
       +
πŸ—οΈ Multi-Stage Builds

This makes it a strong beginner-to-intermediate DevOps portfolio project.

Instead of telling an interviewer:

"I know Docker."

you can explain a complete architecture and the problems you solved.


πŸ“‹ Final Architecture

                         USER
                           |
                           ↓
                  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                  β”‚  Spring Boot    β”‚
                  β”‚     App         β”‚
                  β”‚                 β”‚
                  β”‚ Java + Maven    β”‚
                  β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                           |
                           | Docker Network
                           |
                           ↓
                  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                  β”‚      MySQL      β”‚
                  β”‚    Database     β”‚
                  β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                           |
                           ↓
                  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                  β”‚ Docker Volume   β”‚
                  β”‚ Persistent Data β”‚
                  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Docker Compose manages the complete stack.


🎯 Final Checklist

Before considering the project complete:

[βœ“] Java application created
[βœ“] Maven dependencies configured
[βœ“] pom.xml configured
[βœ“] Spring Boot properties configured
[βœ“] Dockerfile created
[βœ“] Multi-stage Docker build configured
[βœ“] MySQL service configured
[βœ“] Docker network configured
[βœ“] Environment variables configured
[βœ“] Docker volume configured
[βœ“] MySQL healthcheck configured
[βœ“] Restart policy configured
[βœ“] Docker Compose configured
[βœ“] Application image built
[βœ“] Containers started
[βœ“] MySQL verified
[βœ“] Application tested
[βœ“] Logs checked

πŸŽ₯ Reference Tutorial

This project was learned and implemented as part of a Docker/DevOps learning series.

The relevant section starts around:

03:51:00

YouTube:

https://youtu.be/9bSbNNH4Nqw?t=13860


πŸ“ Conclusion

This project gave me practical experience with deploying a Java Spring Boot application using Docker and Docker Compose.

The final environment contains:

Spring Boot
     ↓
Docker Container
     ↓
Docker Network
     ↓
MySQL Container
     ↓
Docker Volume

The most valuable part was understanding how all these components work together.

I learned that containerization is not just about packaging an application.

A production-oriented containerized application also needs:

  • Reliable networking

  • Persistent storage

  • Proper configuration

  • Database readiness

  • Healthchecks

  • Restart policies

  • Optimized images

  • Security practices

  • Troubleshooting strategies

The multi-stage Docker build was particularly useful because it separates the Maven build environment from the runtime environment and helps keep the final image lightweight.

The next logical steps for this project are:

Docker
   ↓
CI/CD
   ↓
AWS
   ↓
Monitoring
   ↓
Kubernetes

For anyone learning DevOps, I highly recommend building projects like this.

Don't just learn Docker commands.

Build something. Break it. Troubleshoot it. Automate it. Deploy it.

That's where real DevOps learning begins. πŸš€


πŸ”— Connect With Me

πŸ’Ό LinkedIn: https://www.linkedin.com/in/hritikranjan1/

🌐 Website: https://hritikranjan.in

πŸ“ DevOps Blogs: https://blogs.hritikranjan.in

πŸ’» GitHub: https://github.com/hritikranjan1


⭐ If you found this project useful, consider giving the repository a Star!

πŸš€ Built with Java β€’ Spring Boot β€’ Maven β€’ Docker β€’ Docker Compose β€’ MySQL

Happy Dockering!

πŸš€ Complete Learning & Career Resources | 2027–2028

A curated collection of learning resources for AI, Data Analytics, Python, Data Engineering, Cybersecurity, Cloud, Networking, Finance, Digital Marketing, Project Management, DevOps and Generative AI.

πŸ“š Learn Β β†’Β  πŸ§ͺ Practice Β β†’Β  πŸ› οΈ Build Β β†’Β  πŸ™ Share Β β†’Β  πŸš€ Grow


🌟 About This Repository

Welcome to the Complete Learning & Career Resources Repository! πŸš€

This repository is designed as a centralized learning hub for students, developers, QA engineers, DevOps engineers, cloud learners, cybersecurity enthusiasts, data professionals, project managers, business professionals and anyone interested in continuous learning.

The goal is simple:

Learn β†’ Practice β†’ Build β†’ Document β†’ Share β†’ Grow

Instead of searching for useful resources again and again, this repository brings them together in one place.


🎯 What You Will Find Here

  • πŸ€– Artificial Intelligence

  • 🧠 Generative AI

  • πŸ“Š Data Analytics

  • 🐍 Python

  • βš™οΈ Data Engineering

  • ☁️ Cloud Computing

  • 🌐 Computer Networking

  • πŸ” Cybersecurity

  • βš™οΈ DevOps

  • πŸ“‹ Project Management

  • πŸ’° Finance

  • πŸ“ˆ Digital Marketing

  • 🧩 Business Analysis

  • πŸš€ Career Development

  • πŸŽ“ Professional Learning

  • πŸ› οΈ Project Ideas

  • πŸ“š Learning Roadmaps


πŸ“Š Repository Overview

Category Resources
πŸ€– AI Courses 15
πŸ”΅ Google Courses 15
🟣 IBM Courses 10
πŸ”₯ Best Courses 2027–2028 21
🌟 Learning & Career Resources 14
πŸ“– Personal Resources 4+

πŸ“š Table of Contents


πŸ€– AI Courses

πŸš€ Explore AI fundamentals, Python, AI infrastructure, Generative AI, AI governance and specialized AI applications.

# Course Link
1 AI For Everyone Start Course β†—
2 AI Python for Beginners Start Course β†—
3 AI Infrastructure and Operations Fundamentals Start Course β†—
4 Generative AI for Human Resources (HR) Professionals Start Course β†—
5 AI Fundamentals Start Course β†—
6 AI for Healthcare Start Course β†—
7 AI Applications in Accounting and Finance Start Course β†—
8 AI Governance and Privacy Professional Certification (AIGP) Start Course β†—
9 Ethics and Governance in the Age of Generative AI Start Course β†—
10 Hands-on quantum error correction with Google Quantum AI Start Course β†—
11 AI-Powered Higher Education Start Course β†—
12 Modern Project Leadership: Agile, AI, and Beyond Start Course β†—
13 AI-Powered Business Analysis: Excel, KPIs & GenAI Start Course β†—
14 AI in Law: Research, Risk, and Legal Drafting Start Course β†—
15 Generative AI for Project Managers Start Course β†—

πŸ”΅ Google Courses

🌐 Explore Data Analytics, AI, Cybersecurity, Networking, Cloud, Digital Marketing and Project Management.

# Course Link
1 Foundations: Data, Data, Everywhere Start Course β†—
2 Ask Questions to Make Data-Driven Decisions Start Course β†—
3 Prepare Data for Exploration Start Course β†—
4 Agile Project Management Start Course β†—
5 Project Initiation: Starting a Successful Project Start Course β†—
6 AI Fundamentals Start Course β†—
7 Foundations of Digital Marketing and E-commerce Start Course β†—
8 Play It Safe: Manage Security Risks Start Course β†—
9 The Bits and Bytes of Computer Networking Start Course β†—
10 Analyze Data to Answer Questions Start Course β†—
11 Automate Cybersecurity Tasks with Python Start Course β†—
12 Architecting with Google Compute Engine Start Course β†—
13 AI for Writing and Communicating Start Course β†—
14 From Likes to Leads: Interact with Customers Online Start Course β†—
15 AI for Data Analysis Start Course β†—

🟣 IBM Courses

πŸ’™ Explore SQL, Python, Data Analytics, Deep Learning, RAG and Generative AI resources.

# Course Link
1 Databases and SQL for Data Science with Python Start Course β†—
2 RAG and Agentic AI Capstone Project Start Course β†—
3 Excel Basics for Data Analysis Start Course β†—
4 Introduction to Data Analytics Start Course β†—
5 Data Visualization and Dashboards with Excel and Cognos Start Course β†—
6 IBM AI Foundations for Business Start Course β†—
7 AI Capstone Project with Deep Learning Start Course β†—
8 Python Project for Data Engineering Start Course β†—
9 Building Generative AI-Powered Applications with Python Start Course β†—
10 Vector Databases for RAG: An Introduction Start Course β†—

πŸ”₯ Best Courses 2027–2028

🎯 A broader collection covering AI, Data, Python, Finance, Cybersecurity, Marketing, Networking, Management and Data Engineering.

# Course Link
1 AI For Everyone Start Course β†—
2 Foundations: Data, Data, Everywhere Start Course β†—
3 Ask Questions to Make Data-Driven Decisions Start Course β†—
4 Prepare Data for Exploration Start Course β†—
5 Financial Markets Start Course β†—
6 Agile Project Management Start Course β†—
7 Play It Safe: Manage Security Risks Start Course β†—
8 Project Initiation: Starting a Successful Project Start Course β†—
9 AI Fundamentals Start Course β†—
10 Analyze Data to Answer Questions Start Course β†—
11 Foundations of Digital Marketing and E-commerce Start Course β†—
12 The Bits and Bytes of Computer Networking Start Course β†—
13 Sequence Models Start Course β†—
14 Federal Taxation I: Individuals, Employees, and Sole Proprietors Start Course β†—
15 Designing the Organization Start Course β†—
16 Game Theory Start Course β†—
17 Using Python to Access Web Data Start Course β†—
18 Viral Marketing and How to Craft Contagious Content Start Course β†—
19 Python Project for Data Engineering Start Course β†—
20 Value Chain Management Start Course β†—
21 Applying Data Analytics in Finance Start Course β†—

🌟 Learning & Career Resources

πŸ’‘ Additional resources for learning, career development, language learning, hosting, education and professional growth.

Category Program Tracking Link
πŸ“± Apps AppSumo https://appsumo.8odi.net/c/5203965/416948/7443
🌐 Website Hosting Automattic, Inc. (WordPress.com, Pressable, WooCommerce, Jetpack) https://automattic.pxf.io/c/5203965/1900456/22744
πŸ‡¬πŸ‡§ College British Council - EOL English Online https://englishonline.sjv.io/c/5203965/1152772/14579
πŸ“š Educational Carson Dellosa Education https://carsondellosaeducation.sjv.io/c/5203965/2241626/29119
πŸŽ“ College Coursera B2C Affiliate Program https://imp.i384100.net/c/5203965/1164545/14726
πŸ“Š Learning DataCamp https://datacamp.pxf.io/c/5203965/1012793/13294
🎨 Collectibles & Hobbies Domestika https://domestika.sjv.io/c/5203965/1492994/17608
πŸŽ“ College edX https://edx.sjv.io/c/5203965/1505390/17728
πŸ’Ό Career Medical Spanish https://curiositymediainc.sjv.io/c/5203965/2899794/33984
πŸ§ͺ Educational MEL Science https://imp.i328067.net/c/5203965/574569/9515
πŸ—£οΈ Apps Preply Learners https://preply.sjv.io/c/5203965/1987575/24422
🌍 Learning Rosetta Stone https://aff.rosettastone.com/c/5203965/1637427/18979
πŸ›οΈ Website Hosting Shopify https://shopify.pxf.io/c/5203965/1061744/13624
🎯 Learning Udemy https://trk.udemy.com/c/5203965/3193860/39854

πŸ—ΊοΈ Recommended Learning Roadmaps

Choose one roadmap according to your career goal. You don't need to learn everything at once.


πŸ€– AI Roadmap

AI Fundamentals
      ↓
Python Basics
      ↓
Mathematics & Statistics
      ↓
Data Fundamentals
      ↓
Machine Learning
      ↓
Deep Learning
      ↓
Generative AI
      ↓
Prompt Engineering
      ↓
RAG
      ↓
Vector Databases
      ↓
Agentic AI
      ↓
AI Applications
      ↓
Real-World Projects
      ↓
GitHub Portfolio