Containerizing applications is becoming increasingly important. In this guide, I'll walk you through deploying a Spring Boot banking application using Docker, first manually and then with Docker Compose. We'll cover everything from setting up the environment to running the application in containers.
Prerequisites
Before we begin, make sure you have:
- An AWS Account
- An Ubuntu EC2 instance (t2.medium)
- Docker installed
- Docker Compose installed
- Basic understanding of Spring Boot and MySQL
- (I already used vagrant box my local environment)
Project Overview
Our banking application is built with:
- Spring Boot (Java)
- MySQL Database
- Maven for build management
- Docker for containerization
Setup My Local Using Vangrant
- cloning the repo from github and navigating to project code using git clone commad
Aungs-MacBook-Pro:cloud-native-box aungkohtet$ git clone https://github.com/aungkohtat/banking-app-project.git
Cloning into 'banking-app-project'...
warning: You appear to have cloned an empty repository.
Aungs-MacBook-Pro:cloud-native-box aungkohtet$ cd banking-app-project/
Aungs-MacBook-Pro:banking-app-project aungkohtet$ ls -la
total 56
drwxr-xr-x 10 aungkohtet staff 320 Oct 28 09:06 .
drwxr-xr-x 28 aungkohtet staff 896 Oct 28 09:05 ..
drwxr-xr-x 9 aungkohtet staff 288 Oct 28 09:04 .git
-rw-r--r--@ 1 aungkohtet staff 905 Oct 28 07:51 Dockerfile
-rw-r--r--@ 1 aungkohtet staff 2781 Oct 28 07:51 README.md
-rw-r--r--@ 1 aungkohtet staff 1940 Oct 28 07:51 docker-compose.yml
drwxr-xr-x 5 aungkohtet staff 160 Oct 28 07:52 images
-rw-r--r--@ 1 aungkohtet staff 10666 Oct 28 07:51 mvnw
-rw-r--r--@ 1 aungkohtet staff 2503 Oct 28 07:51 pom.xml
drwxr-xr-x 4 aungkohtet staff 128 Oct 28 07:52 src
Aungs-MacBook-Pro:banking-app-project aungkohtet$
Part 1: Manual Deployment with Docker
Step 1: Create the Dockerfile
First, let's create a multi-stage Dockerfile to optimize our build:
# Stage 1: Build Environment
FROM maven:3.8.3-openjdk-17 AS builder
WORKDIR /app
COPY . /app
RUN mvn clean install -DskipTests=true
# Stage 2: Production Environment
FROM openjdk:17-jdk-alpine
COPY --from=builder /app/target/*.jar /app/target/bankapp.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app/target/bankapp.jar"]
Step 2: Set Up Docker Infrastructure
- Create a volume for MySQL data:
docker volume create mysql-bankapp
- Create a network for container communication:
docker network create bankapp
- Run MySQL container:
docker run -d --name mysql \
-e MYSQL_ROOT_PASSWORD=Test@123 \
-e MYSQL_DATABASE=BankDB \
--network=bankapp \
mysql:latest
Step 3: Build and Run the Application
- Build the application image:
docker build -t bankapp-mini .
- Run the application container:
docker run -d --name bankapp-mini \
-e SPRING_DATASOURCE_USERNAME="root" \
-e SPRING_DATASOURCE_URL="jdbc:mysql://mysql:3306/BankDB?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC" \
-e SPRING_DATASOURCE_PASSWORD="Test@123" \
--network=bankapp \
-p 8080:8080 \
bankapp-mini:latest
- Now we are ready to see our banking application
- Which works properly, all functions works properly which you can see in images
- take a look of images to see output :
Login
-Register Account
My Dashboard
Deposit
withdraw
transfer money
Transaction History
- Now stoping and deleting the exisiting container of bankapp-mini using command
docker stop 4f35135bde6c && docker rm 4f35135bde6c
Part 2: Deployment with Docker Compose
Now building same application by creating docker-compose.yml
Step 1: Create docker-compose.yml
Create a docker-compose.yml
file to simplify deployment:
version: "3.8"
services:
mysql:
image: mysql:latest
container_name: mysql
environment:
MYSQL_ROOT_PASSWORD: Test@123
MYSQL_DATABASE: BankDB
volumes:
- mysql-bankapp:/var/lib/mysql
networks:
- bankapp
restart: always
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-uroot", "-pTest@123"]
interval: 10s
timeout: 5s
retries: 3
start_period: 30s
bankapp:
image: bankapp-mini
container_name: bankapp-mini
environment:
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/BankDB?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
SPRING_DATASOURCE_PASSWORD: Test@123
ports:
- "8080:8080"
depends_on:
- mysql
networks:
- bankapp
restart: always
volumes:
mysql-bankapp:
networks:
bankapp:
Step 2: Deploy with Docker Compose
docker compose up
Dashboard
Key Features of Our Docker Setup
- Multi-Stage Builds: We use multi-stage builds to keep our final image size small by separating the build environment from the runtime environment.
- Volume Management: Persistent storage for MySQL data ensures we don't lose data when containers restart.
- Network Isolation: Custom network ensures secure communication between containers.
- Health Checks: MySQL container includes health checks to ensure the database is ready before the application starts.
- Environment Variables: Configuration is handled through environment variables, making the setup flexible and secure.
Security Considerations
- Configure AWS security groups to only allow necessary ports (8080 for the application).
- Use environment variables for sensitive data instead of hardcoding values.
- Implement proper database credentials and access controls.
Common Issues and Solutions
- Connection Issues: If the application can't connect to MySQL, ensure both containers are on the same network and the MySQL container is healthy.
- Port Conflicts: If port 8080 is already in use, map to a different port in your docker-compose.yml.
- Volume Permissions: If MySQL can't write to the volume, check volume permissions and ownership.
Conclusion
Docker and Docker Compose significantly simplify the deployment of Spring Boot applications. While manual deployment gives you more control, Docker Compose offers a more maintainable and reproducible solution. Choose the approach that best fits your needs, considering factors like environment complexity and team expertise.
Remember to always follow security best practices and properly manage your AWS resources to avoid unnecessary costs.
Additional Resources
The complete source code for this project is available on GitHub at: my github repo
Top comments (0)