Hello, Guys! Hope you are doing alright. So, in this article I'll be sharing how to dockerize a Spring Boot application, push it to Dockerhub and finally deploy it to an AWS EC2 instance. If you're looking to get a Spring Boot To-Do application up and running in the cloud, you're in the right place. We'll walk through cloning the app from GitHub, creating a Docker image, and deploying it to AWS EC2. Don’t worry, it's actually a lot simpler than it sounds.
Step 1: Clone the GitHub Repository
First things first, you need to get the app's code. I have created a demo springboot todo app so that you can easily get started on creating the Dockerfile. Now go ahead, open up your terminal and run:
git clone https://github.com/ansuman-satapathy/demo-todoapp-for-dockerizing.git
mv demo-todoapp-for-dockerizing todoapp #renaming it to todoapp for easy navigation
cd todoapp #change into that directory
Once you are inside the project root folder, you'll already find a Dockerfile there. Well, that's the one I created. If you want to start from scratch, just delete that file or the content inside the file, as we will be using a file named 'Dockerfile'.
Step 2: Create a Dockerfile
Well, you already have one don't you? So, go ahead and open it with any text editor. A Dockerfile is like a recipe for Docker to build your application’s image. After that add the following content inside it.
Don't worry, I'll explain each line.
# Stage 1: Build Application
FROM maven:3.8.4-openjdk-17-slim AS builder
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN mvn clean package
#Stage 2: Extract the built JAR
FROM openjdk:17-jdk-slim AS runner
WORKDIR /app
COPY --from=builder /app/target/todoapp-0.0.1-SNAPSHOT.jar app.jar
#Stage 3: Running the Application
FROM openjdk:17-jdk-alpine AS final
WORKDIR /app
COPY --from=runner /app/app.jar .
EXPOSE 8080
ENTRYPOINT [ "java", "-jar", "app.jar" ]
This Dockerfile has three stages: one for building the app, one for preparing it to run and another for running it. Dividing the Dockerfile into multiple stages helps keep your docker image nice and small.
Exploring the Content of the Dockerfile
- Building the Application:
FROM maven:3.8.4-openjdk-17-slim AS builder
FROM maven:3.8.4-openjdk-17-slim: This line specifies the base image for this stage. We are using a Maven image with OpenJDK 17 on a slim base to keep the size small. A base image is the starting point of a Dockerfile that provides a operating system and the environment your application will run in.
AS builder: This gives a name to this stage, so we can reference it later.
WORKDIR /app
- WORKDIR /app: Sets the working directory inside the container to
/app
. All subsequent commands will be run from this directory.
COPY pom.xml .
COPY src ./src
COPY pom.xml .: This copies the
pom.xml
file from your local machine to the working directory in the container.COPY src ./src: This copies the
src
directory from your local machine to thesrc
directory in the container.
RUN mvn clean package
- RUN mvn clean package: Runs the Maven command to clean and package the application. This will compile the code and package it into a JAR file.
- Extracting the Built JAR and Preparing It To Run:
FROM openjdk:17-jdk-slim AS runner
FROM openjdk:17-jdk-slim: This line specifies the base image for this stage. We are using an OpenJDK 17 slim image to keep the size small.
AS runner: This names the stage
runner
for later reference.
WORKDIR /app
- WORKDIR /app: Again sets the working directory inside the container to
/app
.
COPY --from=builder /app/target/todoapp-0.0.1-SNAPSHOT.jar app.jar
- COPY --from=builder /app/target/todoapp-0.0.1-SNAPSHOT.jar app.jar: Copies the JAR file from the
builder
stage to the current stage. It takes the JAR from/app/target/todoapp-0.0.1-SNAPSHOT.jar
in thebuilder
stage and places it in the current/app
directory asapp.jar
.
- Running the Application:
FROM openjdk:17-jdk-alpine AS final
FROM openjdk:17-jdk-alpine: This specifies the base image for this final stage. We are using an OpenJDK 17 Alpine image, which is even slimmer and suitable for running the application.
AS final: This names the final stage
final
.
WORKDIR /app
- WORKDIR /app: Sets the working directory inside the container to
/app
.
COPY --from=runner /app/app.jar .
- COPY --from=runner /app/app.jar .: Copies the
app.jar
from therunner
stage to the current directory (/app
) in the final stage.
EXPOSE 8080
- EXPOSE 8080: Tells Docker that the container will listen on port 8080 at runtime. This doesn't actually publish the port; it's more of a documentation for users of the image.
ENTRYPOINT [ "java", "-jar", "app.jar" ]
ENTRYPOINT [ "java", "-jar", "app.jar" ]: Specifies the command to run when the container starts. Here, it runs the JAR file using the
java -jar
command.Now that we understand how a Dockerfile works, lets move forward.
Step 3: Build the Docker Image
So, now we have our Dockerfile ready. The next step is to build it and create a Docker image out of it. To do this, run this command in your terminal:
NOTE: Before proceeding, go ahead and create an account on Dockerhub. After that replace "your-dockerhub-username" with your actual username.
docker build -t your-dockerhub-username/todoapp:latest .
This command tells Docker to build an image using the Dockerfile we just created. After this command is successfully run, check that if any image was created. Run the below command to find images on your machine.
docker images
If you find an image named todoapp, then we have successfully created our docker image. Next is to upload it to Dockerhub.
Step 4: Push the Image to Docker Hub
To make your image available online, you need to push it to Docker Hub. Assuming you have created an account already, run this command:
Push your image:
docker push your-dockerhub-username/todoapp:latest
Step 5: Set Up an AWS EC2 Instance
Log in to AWS and go to the EC2 Dashboard.
Launch a new instance using an Ubuntu Server AMI.
Set up security groups to allow traffic on port 8080 by editing the inbound rules and adding a custom tcp rule for port 8080 to be open to everyone.
Step 6: Install Docker on Your EC2 Instance
Connect to your EC2 instance using SSH:
ssh -i your-key.pem ubuntu@<your-ec2-public-ip>
Install Docker by running these commands by following this tutorial. After that start Docker and ensure it runs automatically on boot:
sudo systemctl start docker
sudo systemctl enable docker
Step 7: Pull and Run Your Docker Image
Pull the Docker image you pushed earlier. This command basically pulls the image from your docker hub account inside the EC2 instance.
sudo docker pull your-dockerhub-username/todoapp:latest
Run the Docker container: Finally run the below command to run the image on port 8080 of the EC2 instance.
sudo docker run -d -p 8080:8080 your-dockerhub-username/todoapp:latest
Step 8: Check Your Application
Locate your public IP address for the EC2 instance. Then, open your web browser and go to:
http://<your-ec2-public-ip>:8080
Voila! You should see your To-Do application up and running!
Troubleshooting
Not reachable? Check that your EC2 security group allows traffic on port 8080.
Container not running? Use
docker ps
to see if the container is active anddocker logs <container-id>
for any errors.
Conclusion
We’ve now got a Spring Boot To-Do application running in the cloud with Docker and AWS EC2. It might seem like a lot at first, but with these steps, it’s pretty manageable. Enjoy your newly deployed app(terminate the instance if you are not rich), and happy coding!
Credits: (Image by pikisuperstar on Freepik)