How to deploy React+Springboot+Mysql full stack project in aws using docker-continers, ec2 and rds instances (mac m1 — arm64)
There any various ways to deploy web applications in aws. This time i’m going to demonstrate using docker-containers and ec2 instances with rds database service.
Let’s jump into it. I assume you already have an aws account up and going . Go to aws Relational database service (RDS) . And create a database in configurations make sure sure database is publicly accessible. And check your database is in available state.
let’s create ec2 instances for our frontend and backend . Go to aws Ec2 services and launch a instance it’s better you create amazon linux machine . If you are a Mac m1 user select architecture type as 64bit (Arm) , create a new key pair which will be downloaded to your computer and we’ll be needed later. In network configuration allow http and https traffics create two ec2 instances.
Let’s create our spring-boot and react docker containers. Install docker desktop and keep it in running state and we are going to use docker-hub to store our docker images. Create docker hub account if you don’t have one . And create two repositories for frontend and backend
Goto your application properties file of your spring-boot application . replace localhost with your database endpoint you can find your db endpoint inside your rds instance.
spring.datasource.url=jdbc:mysql://bookmart.c2p9s8fgimrg.us-east-1.rds.amazonaws.com:3306/bookmart?createDatabaseIfNotExist=true
use the username and password to your rds instance start your application to check whether database connected or not.
next we will create a jar file of our spring boot application . open a terminl in working directory and run
mavan package
it will create a jar file inside target folder . let’s add Dockerfile to your application create a file named Dockerfile inside your root folder.
add below code-lines to that file.
FROM openjdk:17
ADD target/{your jar file} sprig_boot_backend.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "sprig_boot_backend.jar"]
replace your jar file name in the Dockerfile.
build -t {dockerhub username}/{repository name} .
It will take some time. When it’s done run the command docker images command check your image is created. your image tag will be ‘latest’. run below command to run your image in a container.
docker run -p 8080:8080 -d {docker image name}:latest
check if the service going on nicely. let’s push the image to docker hub. You can also use amazon ECR for to host docker images as well
docker push {docker username}/{repository name} :latest
Let’s log in to our backend ec2 instance open a terminal and open your downloads folder which has your downloaded key. run below command to access ec2
ssh -i "{keyname}.pem" ec2-user@{ec2 public Dns}
you can find public dns inside your ec2 instance. If you cannot access keyfile the run
chmod 400 <key.pem>
now will be able to log in to ec2 server lets install docker in the machine
[ec2-user ~]$ sudo yum update -y
[ec2-user ~]$ sudo yum install docker -y
[ec2-user ~]$ sudo service docker start
[ec2-user ~]$ sudo usermod -a -G docker ec2-user
let’s pull our docker image to the server
docker pull {dockerhub username}/{reponame}:latest
let’s run our image on ec2
docker run --name backend -p 8080:80 -d {dockerhub username}/{repository name}:latest
Here we will map our machine 8080 port with outside open port
next we will create our react docker image . currently we interacting with rest api using localhost:8080 but we need to replace with backend public dns name at each request in frontend. next we will add Dockerfile.dev to root folder.
# get the base node image
FROM node:alpine as builder
# set the working dir for container
WORKDIR /frontend
# copy the json file first
COPY ./package.json /frontend
# install npm dependencies
RUN npm install
# copy other project files
COPY . .
# build the folder
CMD [ "npm", "run", "start" ]
Next add docker-compose-local.yml file
version: '3'
services:
frontend:
build:
context: .
dockerfile: Dockerfile.dev
command: npm run start
container_name: frontend
ports:
- "3000:3000"
volumes:
- ./:/frontend
- /frontend/node_modules
lets create and run our react container
docker-compose -f docker-compose-local.yml up -d
we have our local environment all set we need to get our production environement ready. Lets add Dockerfile and docker-compose.yml file
Dockerfile contents:
# get the base node image
FROM node:alpine as builder
# set the working dir for container
WORKDIR /frontend
# copy the json file first
COPY ./package.json /frontend
# install npm dependencies
RUN npm install
# copy other project files
COPY . .
# build the folder
RUN npm run build
# Handle Nginx
FROM nginx
COPY --from=builder /frontend/build /usr/share/nginx/html
COPY ./docker/nginx/default.conf /etc/nginx/conf.d/default.conf
docker-compose.yml ->
server {
listen 80;
server_name _;
index index.html;
root /usr/share/nginx/html;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
location / {
try_files $uri /index.html =404;
}
}
create docker-compose.yml file
version: '3'
services:
frontend:
build: .
container_name: frontend
ports:
- "80:80"
volumes:
- ./:/frontend
- /frontend/node_modules
let’s create our docker container
docker-compose up -d
Now you will have your frontend up and going as well push it to docker hub frontend repo just like we did in backend docker container. and login to other ec2 instance and install docker, pull the image and run it using 3000:80 port then you can access your frontend without specifying a port.
Imagine you created a x86 architecture ec2 instances you can still build a container that supports to multi-architectures from using arm computer by using docker extension called ‘buildx’ to use that we need to create a builder first.
docker buildx create --name mybuilder
docker buildx use mybuilder
then you can build images like below. by pecifing the platform you want.
docker buildx build --tag [expected tag name] -o type=image --platform=linux/arm64,linux/amd64 .
leave a comment if you have any problem . i will try my best to help you .