Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Deploying a Java Spring Boot Application on CentOS 7

Tech 3

This guide details the steps to deploy a Java Spring Boot application on a CentOS 7 server, covering enviroment setup, service installation, and automated deployment scripts.

Initial Server Configuration

Begin by installing essential tools and creating necessary directories.

yum install wget vim net-tools -y
mkdir -p /data/{html,backend}

Installing Java Development Kit 17

Install JDK 17, which is required to run the Java application.

# Download the JDK 17 RPM package
wget https://download.oracle.com/java/17/latest/jdk-17_linux-x64_bin.rpm
# Install the package
sudo yum -y localinstall ./jdk-17_linux-x64_bin.rpm
# Verify the installation
java -version

Successful installation will output version details similar to:

java version "17.0.11" 2024-04-16 LTS
Java(TM) SE Runtime Environment (build 17.0.11+7-LTS-207)
Java HotSpot(TM) 64-Bit Server VM (build 17.0.11+7-LTS-207, mixed mode, sharing)

Installing and Configuring Nginx

Nginx will act as a reverce proxy for the application.

# Install Nginx from the EPEL repository
yum install epel-release -y
yum install nginx -y

Configuration files are typically located in /etc/nginx/conf.d/. Create or edit a configuration file (e.g., app.conf) to define proxy rules for your application's endpoints.

Installing and Securing Redis

Install Redis, which will be used as a caching layer or session store.

# Install Redis
yum install redis -y
# Start the Redis service
systemctl start redis
# Enable Redis to start on boot
systemctl enable redis
# Check the service status
systemctl status redis

To set a password, edit the Redis configuration file:

vi /etc/redis.conf

Find the line # requirepass foobared, uncomment it, and replace foobared with a strong password.

Preparing for Automated Deployment

Set up SSH key-based authentication from your local machine to the server to enable secure file transfers.

# On your local machine, copy the public key to the server
ssh-copy-id root@your_server_ip

Build and Deployment Script

The following script, run from a local development or CI/CD machine, builds the project and deploys it to the server. It assumes a Gradle project structure.

#!/bin/bash
# deploy.sh - Builds the project and transfers the JAR to the server

SERVER_IP="192.168.7.166"
PROJECT_HOME="/local/path/to/your/project"
REMOTE_DIR="/data/backend"

cd "${PROJECT_HOME}"

git pull

# Build the project, skipping tests and other non-essential tasks
./gradlew :application-module:build -x test \
  -Dorg.gradle.java.home='/usr/local/jdk-17.0.8' \
  -Dorg.gradle.daemon=true

if [ $? -ne 0 ]; then
  echo "Build failed. Exiting."
  exit 1
fi

# Copy the built JAR file to the server
JAR_FILE="${PROJECT_HOME}/application-module/build/libs/application-0.0.1-SNAPSHOT.jar"
scp "${JAR_FILE}" root@${SERVER_IP}:${REMOTE_DIR}/

# Execute the remote restart script
ssh root@${SERVER_IP} << 'ENDSSH'
  cd /data/backend
  ./service_restart.sh
ENDSSH

Server-Side Management Scripts

Create the folowing helper scripts in the server's /data/backend directory.

1. Port Check Script (port_check.sh) This script checks if a given port is in use.

#!/bin/bash
# port_check.sh - Checks if a port is in use. Returns 1 if used, 0 if free.
TARGET_PORT=$1
PROCESS_ID=$(lsof -ti:${TARGET_PORT})

if [ -n "${PROCESS_ID}" ]; then
  echo "1"
else
  echo "0"
fi

2. Application Restart Script (service_restart.sh) This is the main script that stops the old instance and starts the new one, updating the Nginx configuration.

#!/bin/bash
# service_restart.sh - Manages application lifecycle and Nginx proxy.

ACTIVE_PORT=8080
PREVIOUS_PORT=8081
TIMESTAMP=$(date +"%Y%m%d%H%M%S")

# Determine which port is free
PORT_STATUS=$(./port_check.sh ${ACTIVE_PORT})
if [ "${PORT_STATUS}" -eq "1" ]; then
  echo "Port ${ACTIVE_PORT} is occupied. Switching to port ${PREVIOUS_PORT}."
  ACTIVE_PORT=8081
  PREVIOUS_PORT=8080
else
  echo "Port ${ACTIVE_PORT} is available for use."
fi

# Start the new application instance on the chosen port
nohup java -Dspring.profiles.active=prod \
           -Dserver.port=${ACTIVE_PORT} \
           -jar application-0.0.1-SNAPSHOT.jar > app_${ACTIVE_PORT}.log 2>&1 &

# Wait for the application to fully start (looks for startup message in logs)
tail -f app_${ACTIVE_PORT}.log | grep -m 1 "Started Application in"

# Update Nginx configuration to point to the new port
echo "proxy_pass http://127.0.0.1:${ACTIVE_PORT};" > /etc/nginx/conf.d/app_proxy.conf
nginx -s reload

# Gracefully shut down the previous instance after a short delay
sleep 15
SHUTDOWN_RESPONSE=$(curl -s http://127.0.0.1:${PREVIOUS_PORT}/actuator/shutdown || echo "0")

if [ "${SHUTDOWN_RESPONSE}" != "{\"message\":\"Shutting down\"}" ]; then
  echo "Warning: Graceful shutdown of previous instance may have failed."
  # Optionally force kill the process on the old port
  # pkill -f "server.port=${PREVIOUS_PORT}"
else
  echo "Previous instance shut down successfully."
fi

Make both scripts executable:

chmod +x /data/backend/port_check.sh /data/backend/service_restart.sh

Installing Additional Dependencies (Tesseract OCR)

If your application requires Optical Character Recognition (OCR), install Tesseract.

yum install tesseract tesseract-langpack-deu -y

Database Configuration

This deployment assumes a pre-configured remote database (e.g., Alibaba Cloud RDS). Ensure your application's application-prod.properties or application.yml file contains the corrrect JDBC URL, username, and password for the production database.

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.