Deploying Spring Boot Backend to AWS EC2
Amazon EC2 (Elastic Compute Cloud) provides resizable compute capacity in the cloud. Deploying your Spring Boot application to EC2 gives you full control over the server environment. This guide walks you through the complete process.
Prerequisites
Before starting, ensure you have:
- AWS account with appropriate permissions
- Spring Boot application (JAR file)
- Basic knowledge of Linux commands
- SSH client installed on your local machine
- AWS CLI configured (optional but recommended)
Step 1: Launch an EC2 Instance
Choose Amazon Machine Image (AMI)
- Log in to AWS Console
- Navigate to EC2 service
- Click "Launch Instance"
Recommended AMI: Amazon Linux 2023 or Ubuntu 22.04 LTS
- Amazon Linux: Optimized for AWS, includes AWS CLI
- Ubuntu: Familiar to many developers, extensive package support
Select Instance Type
For Spring Boot applications, consider:
- t3.micro (Free tier): Testing and development
- t3.small: Small production workloads
- t3.medium: Medium production workloads
- t3.large: Large production workloads
Start with t3.micro for testing, then scale up as needed.
Configure Key Pair
- Create a new key pair or select existing
- Name it (e.g., "spring-boot-server")
- Key pair type: RSA
- Private key file format: .pem (for Mac/Linux) or .ppk (for Windows/PuTTY)
- Click "Create key pair" and download the file
- Important: Store this file securely - you can't download it again!
Configure Network Settings
- Security Group: Create new security group
- Name: "spring-boot-security-group"
- Description: "Security group for Spring Boot application"
Inbound Rules:
- SSH (22): From "My IP" (for initial access)
- HTTP (80): From "Anywhere-IPv4" (for web traffic)
- HTTPS (443): From "Anywhere-IPv4" (for secure web traffic)
- Custom TCP (8080): From "My IP" (if using default Spring Boot port)
Note: For production, restrict SSH to specific IPs and use a load balancer.
Configure Storage
- Size: 20 GB is sufficient for most applications
- Volume Type: gp3 (general purpose SSD)
- Keep default encryption enabled
Review and Launch
- Review all settings
- Click "Launch Instance"
- Wait for instance to be in "Running" state (green status)
Step 2: Connect to Your EC2 Instance
Get Instance Information
- Select your instance in EC2 console
- Click "Connect"
- Note the Public IPv4 address (e.g., 54.123.45.67)
- Note the username (e.g., "ec2-user" for Amazon Linux, "ubuntu" for Ubuntu)
Connect via SSH
For Mac/Linux:
# Change permissions on key file
chmod 400 spring-boot-server.pem
# Connect to instance
ssh -i spring-boot-server.pem ec2-user@54.123.45.67
For Windows (PowerShell):
# Connect using SSH
ssh -i spring-boot-server.pem ec2-user@54.123.45.67
First Connection: You'll see a message asking to add the host to known_hosts. Type "yes".
Step 3: Install Java on EC2 Instance
For Amazon Linux 2023
# Update package manager
sudo dnf update -y
# Install Java 17 (or Java 11)
sudo dnf install java-17-amazon-corretto -y
# Verify installation
java -version
Expected output: openjdk version "17.x.x"
For Ubuntu
# Update package list
sudo apt update
# Install Java 17
sudo apt install openjdk-17-jdk -y
# Verify installation
java -version
Step 4: Install Additional Tools
Install Git (Optional)
# Amazon Linux
sudo dnf install git -y
# Ubuntu
sudo apt install git -y
Install Unzip (for extracting files)
# Amazon Linux
sudo dnf install unzip -y
# Ubuntu
sudo apt install unzip -y
Step 5: Prepare Your Spring Boot Application
Build Your Application
On your local machine, build the JAR file:
# Using Maven
mvn clean package
# Using Gradle
./gradlew build
# The JAR file will be in target/ or build/libs/
# Example: myapp-0.0.1-SNAPSHOT.jar
Transfer JAR to EC2
Option 1: Using SCP
# From your local machine
scp -i spring-boot-server.pem target/myapp-0.0.1-SNAPSHOT.jar ec2-user@54.123.45.67:/home/ec2-user/
Option 2: Using AWS Systems Manager Session Manager
If you have SSM configured, you can transfer files through the console.
Option 3: Using S3
- Upload JAR to S3 bucket
- On EC2 instance, install AWS CLI and download:
# Install AWS CLI (if not installed)
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
# Download from S3
aws s3 cp s3://my-bucket/myapp.jar /home/ec2-user/
Step 6: Create Application Directory
On your EC2 instance:
# Create application directory
mkdir -p ~/app
cd ~/app
# Move JAR file to app directory (if using SCP)
mv ~/myapp-0.0.1-SNAPSHOT.jar ~/app/
# Create logs directory
mkdir logs
Step 7: Create systemd Service (Recommended)
Create a systemd service for automatic startup and management:
# Create service file
sudo nano /etc/systemd/system/spring-boot-app.service
Add the following content:
[Unit]
Description=Spring Boot Application
After=network.target
[Service]
Type=simple
User=ec2-user
WorkingDirectory=/home/ec2-user/app
ExecStart=/usr/bin/java -jar /home/ec2-user/app/myapp-0.0.1-SNAPSHOT.jar
Restart=always
RestartSec=10
StandardOutput=append:/home/ec2-user/app/logs/output.log
StandardError=append:/home/ec2-user/app/logs/error.log
[Install]
WantedBy=multi-user.target
Key Configuration:
- User: The user that runs the application
- WorkingDirectory: Where the JAR file is located
- ExecStart: Command to start the application
- Restart: Automatically restart if it crashes
Enable and Start Service
# Reload systemd
sudo systemctl daemon-reload
# Enable service (start on boot)
sudo systemctl enable spring-boot-app
# Start service
sudo systemctl start spring-boot-app
# Check status
sudo systemctl status spring-boot-app
# View logs
sudo journalctl -u spring-boot-app -f
Step 8: Configure Application Properties
If your Spring Boot app needs configuration, create application.properties:
# Create config directory
mkdir -p ~/app/config
# Create application.properties
nano ~/app/config/application.properties
Example configuration:
server.port=8080
spring.datasource.url=jdbc:mysql://your-rds-endpoint:3306/mydb
spring.datasource.username=admin
spring.datasource.password=your-password
logging.file.path=/home/ec2-user/app/logs
Update your service file to use config:
ExecStart=/usr/bin/java -jar -Dspring.config.location=file:/home/ec2-user/app/config/application.properties /home/ec2-user/app/myapp-0.0.1-SNAPSHOT.jar
Step 9: Configure Firewall (Security Group)
Your security group should allow:
- Port 8080 (Spring Boot default) from your IP or load balancer
- Port 80/443 if using a reverse proxy
To update security group:
- Go to EC2 Console → Security Groups
- Select your security group
- Edit inbound rules
- Add rule: Type: Custom TCP, Port: 8080, Source: Your IP or 0.0.0.0/0
Security Note: For production, use a load balancer and restrict direct access to EC2.
Step 10: Test Your Application
Check if Application is Running
# Check if port is listening
sudo netstat -tulpn | grep 8080
# Or using ss
sudo ss -tulpn | grep 8080
# Check logs
tail -f ~/app/logs/output.log
Access Application
Open your browser and navigate to:
http://your-ec2-public-ip:8080
Or test from command line:
curl http://localhost:8080/actuator/health
Step 11: Set Up Reverse Proxy (Optional but Recommended)
For production, use Nginx as a reverse proxy:
Install Nginx
# Amazon Linux
sudo dnf install nginx -y
# Ubuntu
sudo apt install nginx -y
Configure Nginx
# Edit Nginx configuration
sudo nano /etc/nginx/conf.d/spring-boot.conf
Add configuration:
server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Start Nginx
# Start Nginx
sudo systemctl start nginx
sudo systemctl enable nginx
# Test configuration
sudo nginx -t
# Restart Nginx
sudo systemctl restart nginx
Now access your app via HTTP port 80!
Application Management Commands
Service Management
# Start application
sudo systemctl start spring-boot-app
# Stop application
sudo systemctl stop spring-boot-app
# Restart application
sudo systemctl restart spring-boot-app
# View status
sudo systemctl status spring-boot-app
# View logs
sudo journalctl -u spring-boot-app -f
Manual Deployment Process
# 1. Stop application
sudo systemctl stop spring-boot-app
# 2. Backup current version
cp myapp-0.0.1-SNAPSHOT.jar myapp-0.0.1-SNAPSHOT.jar.backup
# 3. Upload new JAR (via SCP or S3)
# ... transfer new JAR file ...
# 4. Start application
sudo systemctl start spring-boot-app
# 5. Check logs
sudo journalctl -u spring-boot-app -f
Security Best Practices
1. Use IAM Roles Instead of Access Keys
Attach an IAM role to your EC2 instance instead of storing AWS credentials in your application.
2. Keep Security Groups Restrictive
- Only open necessary ports
- Restrict SSH access to specific IPs
- Use load balancers for public-facing applications
3. Regular Updates
# Amazon Linux
sudo dnf update -y
# Ubuntu
sudo apt update && sudo apt upgrade -y
4. Use HTTPS
Set up SSL/TLS certificates (Let's Encrypt or AWS Certificate Manager) with Nginx.
5. Monitor Your Instance
- Set up CloudWatch alarms
- Monitor CPU, memory, and disk usage
- Review application logs regularly
Troubleshooting Common Issues
Issue: Application Won't Start
Check:
# View application logs
sudo journalctl -u spring-boot-app -n 50
# Check Java version
java -version
# Verify JAR file exists and is readable
ls -lh ~/app/*.jar
Issue: Port Already in Use
Solution:
# Find process using port 8080
sudo lsof -i :8080
# Kill the process
sudo kill -9 <PID>
Issue: Can't Connect from Browser
Check:
- Security group allows inbound traffic on port 8080
- Application is running:
sudo systemctl status spring-boot-app - Firewall on instance (usually managed by security groups)
- Check application logs for errors
Issue: Out of Memory
Solution: Increase heap size in service file:
ExecStart=/usr/bin/java -Xms512m -Xmx1024m -jar /home/ec2-user/app/myapp-0.0.1-SNAPSHOT.jar
Cost Optimization Tips
- Use Reserved Instances: For long-running workloads, save up to 75%
- Right-Size Instances: Monitor usage and downsize if not needed
- Stop When Not in Use: Stop instances during non-business hours
- Use Spot Instances: For development/testing, save up to 90%
- Monitor Costs: Set up billing alerts in AWS Console
Next Steps
- Set up automated deployments with GitHub Actions or AWS CodeDeploy
- Configure CloudWatch for monitoring and logging
- Set up load balancing for high availability
- Configure auto-scaling based on traffic
- Set up database connection (RDS)
- Implement CI/CD pipeline
Deploying Spring Boot to EC2 gives you full control and flexibility. Start simple, then optimize for production with load balancers, auto-scaling, and monitoring.
