Table of contents
- Step 1: Create an EC2 Instance
- Step 2: Install Dependencies
- Step 3: Clone Your Project
- Step 4: Write a Dockerfile
- Step 5: Build the Application
- Step 6: Create a Docker Compose File
- Step 7: Run Docker Compose
- Step 8: Configure Security Group
- Step 9: Access the Application
- Troubleshooting: Database Connection Issues
Setting up a three-tier application (frontend, backend, and database) using Docker Compose is a great way to streamline deployment and management. In this blog, we’ll walk through building a sample expense-tracker application step by step. Let’s dive in!
Step 1: Create an EC2 Instance
Start by creating an EC2 instance in your preferred cloud environment. Make sure you have the necessary inbound security group rules to allow HTTP (port 80) and your application port (port 8080).
Step 2: Install Dependencies
On your EC2 instance:
Install Docker and Docker Compose:
sudo apt update sudo apt install docker.io docker-compose -y
Grant Docker permissions to your user:
sudo usermod -aG docker $USER
Install NGINX (optional, for reverse proxy) and MySQL:
sudo apt install nginx mysql-client -y
Step 3: Clone Your Project
Clone the project repository into your local directory:
git clone <your-repo-url> cd <your-project-folder>
Step 4: Write a Dockerfile
Here’s a sample Dockerfile for a Java-based backend:
# Stage 1 - jar(JAVA APPLICATION RUNTIME) builder USING MAVEN # Maven Image FROM maven:3.8.3-openjdk-17 AS builder # Set working directory WORKDIR /ap # Copy souce code from local to container COPY . /app # Build the application, Create jar file and skip the tests RUN mvn clean install -DskipTests=true #------------------------------------------------------------------- # Stage 2 - Execute jar file from the above stage FROM openjdk:17-alpine WORKDIR /app # Copy build (jar file) from stage 1 (builder) # expenseapp.jar where (expenseapp) is the name of the application we can find in application.properties COPY --from=builder /app/target/*.jar /app/target/expenseapp.jar # Expose application port EXPOSE 8000 # Start the application ENTRYPOINT ["java", "-jar", "/app/target/expenseapp.jar"]
Use this to containerize your Java application.
Step 5: Build the Application
Run the following command to build your Docker image:
docker build -t expense-app .
Step 6: Create a Docker Compose File
Now, set up a
docker-compose.yml
file to define and orchestrate your services:version: "3.8" services: mysql: image: mysql:latest container_name: mysql environment: MYSQL_ROOT_PASSWORD: Test@123 MYSQL_DATABASE: expenses_tracker volumes: - ./mysql-data:/var/lib/mysql networks: - appbridge healthcheck: test: ["CMD","mysqladmin","ping","-h","localhost","-uroot","-pTest@123"] interval: 10s timeout: 5s retries: 5 start_period: 30s restart: always mainapp: image: snehcreate/expensetracker_v3 container_name: Expensetracker environment: SPRING_DATASOURCE_USERNAME: root SPRING_DATASOURCE_URL: "jdbc:mysql://mysql:3306/expenses_tracker?allowPublicKeyRetrieval=true&useSSL=false" SPRING_DATASOURCE_PASSWORD: Test@123 ports: - "8080:8080" networks: - appbridge depends_on: - mysql restart: always networks: appbridge: volumes: mysql-data:
Step 7: Run Docker Compose
Spin up your application with:
docker compose up -d
This command starts your MySQL database and Java backend in separate containers, all connected via the
appbridge
network.
Step 8: Configure Security Group
Update your EC2 instance’s security group to allow traffic on port 8080 (the application port).
Step 9: Access the Application
Open your browser and visit:
http://<your-ec2-public-ip>:8080
Troubleshooting: Database Connection Issues
If your application fails to connect to MySQL, double-check the environment variable
SPRING_DATASOURCE_URL
. Here’s the correct format:SPRING_DATASOURCE_URL: "jdbc:mysql://mysql:3306/expenses_tracker?allowPublicKeyRetrieval=true&useSSL=false"
The key addition here is
allowPublicKeyRetrieval=true&useSSL=false
, which resolves common MySQL connection issues.
Final Thoughts
Congratulations! You’ve successfully built and deployed a three-tier application using Docker Compose. This setup makes it easier to manage services and scale as needed. Feel free to customize this example for your use case.
If you found this guide helpful, don’t forget to share it with your peers and leave your thoughts in the comments! 🚀