Step 4: Deploy Spring Boot Application to Lightsail Server

Lecture Slides

Either click on the slide area below or click here to view it in fullscreen. Use your keypad to navigate the slides.

A PDF printable handout version of the slides is available here

Introduction

In this step, you’ll deploy your Spring Boot application to the AWS Lightsail server you’ve configured. We’ll install Java, transfer your application files, configure environment variables, and set up the application to run as a system service.

Understanding the Deployment Process

Deploying a Spring Boot application to a Linux server involves several key components:

  • Installing the Java Runtime Environment (JRE)
  • Transferring your compiled JAR file to the server
  • Configuring production environment variables
  • Setting up the application as a system service for automatic startup
TipBest Practice

Always test your application locally with production profiles before deploying to ensure your configurations work correctly in the target environment.

Installing Java on Your Lightsail Instance

First, let’s install OpenJDK 17, which is the recommended Java version for modern Spring Boot applications.

Connect to Your Instance

SSH into your Lightsail instance using the browser-based SSH client or your preferred SSH client:

# If using external SSH client
ssh -i your-key.pem ubuntu@your-lightsail-ip

Install OpenJDK 17

Update the package manager and install Java:

# Update package lists
sudo apt update

# Install OpenJDK 17
sudo apt install openjdk-17-jdk -y

# Verify installation
java -version
javac -version
NoteJava Version Compatibility

OpenJDK 17 is the current LTS (Long Term Support) version and is fully compatible with Spring Boot 3.x. If you’re using Spring Boot 2.x, OpenJDK 11 is also supported.

Preparing Your Application for Deployment

Building Your Application JAR

On your local development machine, build your Spring Boot application:

# Using Maven
./mvnw clean package -DskipTests

# Using Gradle
./gradlew build -x test

This creates a JAR file in your target/ (Maven) or build/libs/ (Gradle) directory.

Create Application Directory Structure

Back on your Lightsail server, create the directory structure for your application:

# Create application directory
sudo mkdir -p /opt/myapp

# Create logs directory
sudo mkdir -p /var/log/myapp

# Create application user
sudo useradd -r -s /bin/false myapp

# Set ownership
sudo chown -R myapp:myapp /opt/myapp
sudo chown -R myapp:myapp /var/log/myapp

Transferring Your Application to the Server

Using SCP to Transfer Files

From your local machine, transfer your JAR file to the server:

# Transfer JAR file
scp -i your-key.pem target/myapp-0.0.1-SNAPSHOT.jar ubuntu@your-lightsail-ip:/home/ubuntu/

# SSH back to server and move file
ssh -i your-key.pem ubuntu@your-lightsail-ip
sudo mv /home/ubuntu/myapp-0.0.1-SNAPSHOT.jar /opt/myapp/myapp.jar
sudo chown myapp:myapp /opt/myapp/myapp.jar
TipAlternative Transfer Methods

You can also use rsync, SFTP, or even Git to deploy your code and build directly on the server. Choose the method that best fits your deployment workflow.

Configuring Environment Variables

Create Environment Configuration

Create a configuration file for your production environment variables:

sudo nano /opt/myapp/application.env

Add your production configuration:

# /opt/myapp/application.env

# Spring Profile
SPRING_PROFILES_ACTIVE=prod

# Database Configuration
DB_HOST=your-lightsail-db-endpoint
DB_PORT=3306
DB_NAME=myapp_prod
DB_USERNAME=myappuser
DB_PASSWORD=your-secure-password

# Server Configuration
SERVER_PORT=8080

# Logging
LOGGING_LEVEL_ROOT=WARN
LOGGING_LEVEL_COM_YOURPACKAGE=INFO

# JVM Options
JAVA_OPTS=-Xms512m -Xmx1024m -Dspring.profiles.active=prod

Set appropriate permissions:

sudo chown myapp:myapp /opt/myapp/application.env
sudo chmod 600 /opt/myapp/application.env

Creating a System Service

Create Systemd Service File

Create a systemd service file to manage your Spring Boot application:

sudo nano /etc/systemd/system/myapp.service

Add the following configuration:

[Unit]
Description=My Spring Boot Application
After=network.target

[Service]
Type=exec
User=myapp
Group=myapp
ExecStart=/usr/bin/java -jar /opt/myapp/myapp.jar
EnvironmentFile=/opt/myapp/application.env
WorkingDirectory=/opt/myapp
StandardOutput=append:/var/log/myapp/application.log
StandardError=append:/var/log/myapp/error.log
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

Enable and Start the Service

# Reload systemd configuration
sudo systemctl daemon-reload

# Enable service to start on boot
sudo systemctl enable myapp.service

# Start the service
sudo systemctl start myapp.service

# Check service status
sudo systemctl status myapp.service
WarningService Startup Issues

If your service fails to start, check the logs using sudo journalctl -u myapp.service -f to identify configuration or dependency issues.

Configuring Application Properties for Production

Ensure your application-prod.properties file contains the correct database configuration:

# src/main/resources/application-prod.properties

# Database configuration using environment variables
spring.datasource.url=jdbc:mysql://${DB_HOST:localhost}:${DB_PORT:3306}/${DB_NAME:myapp}
spring.datasource.username=${DB_USERNAME:root}
spring.datasource.password=${DB_PASSWORD:password}

# Production optimizations
spring.jpa.hibernate.ddl-auto=validate
spring.jpa.show-sql=false

# Server configuration
server.port=${SERVER_PORT:8080}

# Logging configuration
logging.level.root=${LOGGING_LEVEL_ROOT:INFO}
logging.file.name=/var/log/myapp/application.log
logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n

# Security headers
server.servlet.session.cookie.secure=true
server.servlet.session.cookie.http-only=true

Testing Your Deployment

Verify Application Status

Check that your application is running correctly:

# Check service status
sudo systemctl status myapp.service

# View recent logs
sudo tail -f /var/log/myapp/application.log

# Test application endpoint
curl http://localhost:8080/actuator/health

Check Network Connectivity

Verify your application is accessible:

# Test local connection
curl -I http://localhost:8080

# Check if port is listening
sudo netstat -tlnp | grep :8080

Configure Lightsail Firewall

Open the necessary ports in your Lightsail instance firewall:

  1. Go to the Lightsail console
  2. Select your instance
  3. Click the Networking tab
  4. Add a custom rule:
    • Application: Custom
    • Protocol: TCP
    • Port: 8080
NotePort 8080 is Temporary

We’re opening port 8080 for testing purposes. In the next step, we’ll configure Nginx as a reverse proxy, which will handle HTTP (80) and HTTPS (443) traffic.

Monitoring and Log Management

Set Up Log Rotation

Create a logrotate configuration to manage log file sizes:

sudo nano /etc/logrotate.d/myapp

Add the following configuration:

/var/log/myapp/*.log {
    daily
    rotate 30
    compress
    delaycompress
    missingok
    notifempty
    create 0644 myapp myapp
    postrotate
        systemctl reload myapp.service > /dev/null 2>&1 || true
    endscript
}

Basic Monitoring Commands

Keep these commands handy for monitoring your application:

# Check application status
sudo systemctl status myapp.service

# View real-time logs
sudo journalctl -u myapp.service -f

# Check memory usage
free -h

# Check disk usage
df -h

# Monitor CPU and memory usage
top

Troubleshooting Common Issues

Application Won’t Start

  1. Check Java installation: java -version
  2. Verify JAR file exists and has correct permissions
  3. Check environment file syntax and permissions
  4. Review systemd logs: sudo journalctl -u myapp.service -n 50

Database Connection Issues

  1. Verify database is running and accessible
  2. Test connection from server: mysql -h DB_HOST -u DB_USERNAME -p
  3. Check environment variables are correctly set
  4. Verify firewall allows database connections

Memory Issues

  1. Monitor memory usage: free -h
  2. Adjust JVM heap settings in JAVA_OPTS
  3. Consider upgrading your Lightsail instance plan

Summary and Key Takeaways

In this step, you’ve successfully:

  • Installed Java 17 on your Lightsail server for running Spring Boot applications
  • Created a proper directory structure with appropriate user permissions for security
  • Transferred your application JAR file to the production server
  • Configured environment variables for production database and application settings
  • Set up a systemd service for automatic application startup and management
  • Implemented logging with proper rotation to prevent disk space issues
  • Configured basic monitoring tools to track application health

Your Spring Boot application is now running on AWS Lightsail, but it’s only accessible via port 8080. In the next step, we’ll configure Nginx as a reverse proxy to handle web traffic on standard HTTP/HTTPS ports and improve performance and security.

TipNext Steps Preview

The next step will involve setting up Nginx to proxy requests to your Spring Boot application, enabling you to serve traffic on port 80 (HTTP) and eventually port 443 (HTTPS) with SSL certificates.