Deploy Java SpringBoot & React.js with four steps on AWS

Deploy Java SpringBoot & React.js with four steps on AWS
Docker is the Key

Deployments can become a huge pain if any config is missed while setting up the deployment infra. Almost every time we face the below situation if deployment steps are not done correctly.

I did everything right, followed all the steps of a(random blog), and also checked YouTube videos with 100K views, yet my backend deployment is not working. Why, is that?

If you are reading this blog while having the same question in your head, then you are at the right place.

Now, just follow along and experience a lifetime worth of fun……

In this blog, we will be writing Dockerfiles and Docker compose files to deploy Vite React.js frontend and Java SpringBoot backend. Using the steps below we can host our backend and frontend on the same EC2 instance. For ease of the deployment process, I am using api.domain-name for backend access and domain-name for frontend access.

The important point to note here is for frontend React.js we are using Vite and for backend, we are using Jhipster as tools to bootstrap the projects.

Just four steps and your frontend and backend are up and running in 30 seconds with SSL certificate(auto-renew as well), Reverse proxy, Nginx config and end-to-end Dockerize on your AWS EC2 instance.

Minor setup:

It’s required in case you don’t have an AWS EC2 instance or docker installed in the instance.

  1. Set up an EC2 instance with Ubuntu and log in to your instance using ssh.
  2. Set up Docker on the AWS instance, use Docker setup from the Docker documentation to install Docker.

Frontend: Vite React.js Dockerfile and Docker Compose config:

React.js with Vite setup already provides the below Dockerfile and you can further create a docker-compose file to build a frontend image and attach to a docker network.

# Dockerfile

# Use the official Node.js image as the base image
FROM node:16 AS build

# Set the working directory in the container
WORKDIR /app

# Copy the package.json and package-lock.json files to the container
COPY package*.json ./

# Install dependencies in the container
RUN npm install

# Copy the rest of the application files to the container
COPY . .

# Build the Vite React.js application
RUN npm run build

# Use a lightweight Node.js image to serve the built application
FROM node:16-alpine

# Set the working directory in the container
WORKDIR /app

# Install the 'serve' package globally to serve the application
RUN npm install -g serve

# Copy the built application files from the build container
COPY --from=build /app/dist /app/dist

# Expose port 5000 for the application
EXPOSE 5000

# Command to run the application using 'serve'
CMD ["serve", "-s", "dist", "-l", "5000"] # docker-compose.yml
# docker-compose.yml

name: react-frontend
services:
  app:
    image: react-frontend
    expose:
      - '5000'
    environment:
      - VIRTUAL_HOST=domain-name
      - VIRTUAL_PORT=5000
      - LETSENCRYPT_HOST=domain-name
      - LETSENCRYPiT_EMAIL=verified-mail-id
    networks:
      production: {}
networks:
  production:
    external: true
    name: production

Backend: Jhipster Java SpringBoot Dockerfile and Docker Compose config:

Java SpringBoot with Jhipster setup already provides the Dockerfile and below docker-compose file to build the backend image and attach it to a docker network.

# src/main/docker/app.yml

name: backend-service
services:
  app:
    image: jhpister-backend
    expose:
      - "8080"
    environment:
      - _JAVA_OPTIONS=-Xmx512m -Xms256m
      - SPRING_PROFILES_ACTIVE=prod,api-docs
      - MANAGEMENT_PROMETHEUS_METRICS_EXPORT_ENABLED=true
      - SPRING_DATASOURCE_URL=jdbc:postgresql://postgresql:5432/jhipster-backend-db
      - SPRING_LIQUIBASE_URL=jdbc:postgresql://postgresql:5432/jhipster-backend-db
      - SPRING_DATASOURCE_USERNAME=postgres
      - SPRING_DATASOURCE_PASSWORD=postgres123
      - SPRING_PROFILES_ACTIVE=prod
      - VIRTUAL_HOST=subdomain-name
      - LETSENCRYPT_HOST=subdomain-name
      - LETSENCRYPT_EMAIL=email-id
      - VIRTUAL_PORT=8080
    networks:
      production: {}
  postgresql: # using local postgres instance 
    extends:
      file: ./postgresql.yml
      service: postgresql
networks: 
  production: 
    external: true
    name: production

Support me to write interesting articles by clapping on the blog. Now say close your eyes and copy-paste the four steps below.

THE STEPS START HERE:

Step 1:

Create Docker network and attach all the containers to that network. This will help Jwilder container to acknowledge any changes in your linked containers.

$ docker network create production

Step 2:

Jwilder/Nginx proxy container, for your nginx and reverse proxy setup:

$ docker run -d -p 80:80 -p 443:443 \
    --name nginx-proxy \
    --network production \
    -v ~/certs:/etc/nginx/certs:ro \
    -v /etc/nginx/vhost.d \
    -v /usr/share/nginx/html \
    -v /var/run/docker.sock:/tmp/docker.sock:ro \
    jwilder/nginx-proxy

Step 3:

Letsencrypt docker container to enable with SSL certificates creation and auto-renew:

$ docker run -d \
    --name nginx-proxy-letsencrypt \
    --network production \
    -v ~/certs:/etc/nginx/certs:rw \
    -v /var/run/docker.sock:/var/run/docker.sock:ro \
    --volumes-from nginx-proxy \
    --env "DEFAULT_EMAIL=email-id" \
    nginxproxy/acme-companion

Step 4:

Running frontend and backend docker containers, using the above created Dockerfiles and Docker compose files.

# running frontend containers: from frontend folder
$ docker build -t react-frontend .
$ docker compose -f docker-compose.yml up -d

# running backend containers: from backend folder
$ ./gradlew -Pprod bootJar jibDockerBuild
$ docker compose -f src/main/docker/app.yml up -d 

VIOLA !!! . That’s it, your Jhipster Java Springboot backend and React.js frontend is up and running on a single EC2 instance.

Now every time you want to deploy frontend and backend service and will be checking out this blog. Just copy-paste commands and clap :)

Need help building next-gen products using React-Native, Next.js, SpringBoot? Contact me on Fiverr or connect with me on LinkedIn. I will be glad to help you build the next big thing.