How to Deploy Spring Boot to AWS: A Practical Guide
Purpose
I’ve deployed dozens of Spring Boot applications to AWS over the past few years. What I’ve learned is that choosing the right AWS service makes all the difference. EC2 gives you full control but requires manual setup. Elastic Beanstalk handles the infrastructure for you. ECS with Fargate is perfect for containerized workloads.
This guide shows you how to deploy Spring Boot to AWS using these three approaches. I’ll walk you through preparing your JAR, setting up the infrastructure, configuring databases, and securing your application.
Preparing the JAR File
Before deploying to AWS, you need a production-ready JAR. I use Maven for my builds, but Gradle works just as well.
First, build your application:
mvn clean package -DskipTestsThis creates an executable JAR in the target directory. The key insight here is that Spring Boot packages an embedded Tomcat server inside the JAR, so you don’t need to install a separate application server on AWS.
Before deploying, I always create a production profile:
server.port=80spring.profiles.active=prodlogging.level.root=WARNlogging.level.com.myapp=INFO
# Database (I'll cover this later)spring.datasource.url=jdbc:mysql://${RDS_ENDPOINT}:3306/mydbspring.datasource.username=${DB_USERNAME}spring.datasource.password=${DB_PASSWORD}Test the JAR locally first:
java -jar target/myapp-1.0.0.jar --spring.profiles.active=prodEC2 Deployment Option
EC2 gives you complete control over your infrastructure. I use EC2 when I need custom OS configurations or when I want full control over the server setup.
Launch the Instance
I start by launching an EC2 instance in the AWS Console:
- Choose an AMI - Amazon Linux 2 or Ubuntu 20.04 work well
- Select instance type - t2.micro for testing, t3.medium for production
- Configure security group - allow ports 80 (HTTP), 443 (HTTPS), and 22 (SSH)
- Create or use an existing key pair for SSH access
Install Java and Deploy
Once the instance is running, SSH into it:
Install Java 17:
sudo yum update -ysudo yum install java-17-amazon-corretto -yjava -versionCreate a deployment directory:
sudo mkdir /opt/myappsudo chown ec2-user:ec2-user /opt/myappUpload your JAR using SCP:
Set Up Systemd Service
I create a systemd service to keep the application running:
sudo nano /etc/systemd/system/myapp.serviceAdd this configuration:
[Unit]Description=Spring Boot ApplicationAfter=network.target
[Service]User=ec2-userExecStart=/usr/bin/java -jar /opt/myapp/app.jar --spring.profiles.active=prodSuccessExitStatus=143Restart=on-failureRestartSec=10
[Install]WantedBy=multi-user.targetEnable and start the service:
sudo systemctl daemon-reloadsudo systemctl enable myappsudo systemctl start myappsudo systemctl status myappConfigure Nginx Reverse Proxy
I recommend putting Nginx in front of your Spring Boot app:
sudo amazon-linux-extras install nginx1 -ysudo systemctl start nginxsudo systemctl enable nginxConfigure Nginx as a reverse proxy:
server { listen 80; server_name myapp.example.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; }}For HTTPS, I use Let’s Encrypt with certbot:
sudo yum install certbot -ysudo certbot --nginx -d myapp.example.comElastic Beanstalk Option
Elastic Beanstalk is simpler than EC2 because it handles the infrastructure for you. It provisions load balancers, auto-scaling groups, and monitoring automatically.
Install EB CLI
First, install the Elastic Beanstalk CLI:
brew install awsebcli # macOS# orsudo apt-get install awsebcli # UbuntuInitialize Your Application
Navigate to your project root and run:
eb initThis prompts you to:
- Select a region (I use us-east-1)
- Choose an application name
- Select a platform (Java)
- Set up SSH access
Create Your Environment
Create a new environment:
eb create productionElastic Beanstalk provisions:
- EC2 instances
- Load balancer
- Auto-scaling group
- Security groups
- CloudWatch monitoring
Deploy Your Application
Build your JAR:
mvn clean packageDeploy to Elastic Beanstalk:
eb deployCheck the status:
eb statuseb healthView logs:
eb logsConfigure Environment Variables
Set environment variables for your database credentials:
eb setenv RDS_ENDPOINT=mydb.xxxx.us-east-1.rds.amazonaws.comeb setenv DB_USERNAME=admineb setenv DB_PASSWORD=securepasswordeb setenv SPRING_PROFILES_ACTIVE=prodCustom Configuration with .ebextensions
I create a .ebextensions directory in my project root for custom configuration:
option_settings: aws:elasticbeanstalk:container:java:tomcat: JvmPort: 5000 XmxSize: 512m XmsSize: 256m
aws:elasticbeanstalk:environment:proxy:nginx: ProxyServerOptions: ssl_policy: ELBSecurityPolicy-TLS-1-2-2017-01Setting Up RDS Database
I use Amazon RDS for managed databases. It handles backups, patching, and scaling automatically.
Create RDS Instance
- Go to the RDS console
- Click “Create database”
- Choose MySQL or PostgreSQL
- Select instance size (db.t3.micro for testing, db.t3.medium for production)
- Set master username and password
- Create a new VPC security group
Configure Security Groups
Allow your EC2 instance or Elastic Beanstalk environment to access the database:
- Go to the RDS security group
- Add an inbound rule for MySQL (port 3306) or PostgreSQL (port 5432)
- Allow traffic from your EC2 security group or Elastic Beanstalk security group
Update Spring Boot Configuration
Your application properties should reference the RDS endpoint:
spring.datasource.url=jdbc:mysql://${RDS_ENDPOINT}:3306/mydbspring.datasource.username=${DB_USERNAME}spring.datasource.password=${DB_PASSWORD}
# Connection poolingspring.datasource.hikari.maximum-pool-size=10spring.datasource.hikari.minimum-idle=5
# JPAspring.jpa.hibernate.ddl-auto=updatespring.jpa.show-sql=falseSecurity and Monitoring
Security Best Practices
I’ve learned these security practices the hard way:
- Use AWS Secrets Manager for sensitive credentials:
aws secretsmanager create-secret \ --name prod/db/password \ --secret-string "SecurePassword123"Access secrets in your application:
@Value("${spring.datasource.password}")private String dbPassword;Set the environment variable to reference the secret:
eb setenv SPRING_DATASOURCE_PASSWORD='{{resolve:secretsmanager:prod/db/password:SecretString}}'- Restrict security group rules - Only allow necessary ports and from specific sources
- Enable HTTPS only - Redirect HTTP to HTTPS
- Use IAM roles instead of access keys
- Rotate credentials regularly
Monitoring Setup
Enable CloudWatch metrics:
eb setenv AWS_ACCESS_KEY_ID=ignoredeb setenv AWS_SECRET_ACCESS_KEY=ignoredCreate CloudWatch alarms:
- CPU utilization > 70%
- Memory utilization > 80%
- Application health checks failing
Enable X-Ray for request tracing:
eb setenv AWS_XRAY_DAEMON_ADDRESS=127.0.0.1:2000Cost Estimation
Based on my experience, here’s what you can expect to pay:
EC2 Deployment:
- t3.medium instance: ~$15/month
- Elastic IP: ~$3/month
- Total: ~$18/month
Elastic Beanstalk Deployment:
- t3.medium instances (2 instances): ~$30/month
- Application Load Balancer: ~$18/month
- Total: ~$48/month
RDS Database:
- db.t3.micro: ~$15/month
- db.t3.medium: ~$35/month
- Multi-AZ deployment: 2x cost
Total for small production app: ~$50-100/month
I recommend starting with the AWS Free Tier (12 months) to test your deployment. You get 750 hours of t2.micro EC2 instances and 25 GB of RDS storage free.
Scaling Strategies
When your application grows, you’ll need to scale.
Elastic Beanstalk Auto-scaling
Configure auto-scaling:
eb scale 2 # Minimum 2 instancesCreate a trigger in the console or use .ebextensions:
Resources: AWSEBAutoScalingGroup: Type: AWS::AutoScaling::AutoScalingGroup Properties: MinSize: 2 MaxSize: 10 TargetTrackingConfigurations: - PredefinedMetricSpecification: PredefinedMetricType: ASGAverageCPUUtilization TargetValue: 70.0Load Balancer Health Checks
Elastic Beanstalk automatically configures health checks on /. Customize this path:
management.endpoints.web.exposure.include=healthmanagement.endpoint.health.show-details=alwaysSummary
I’ve shown you three ways to deploy Spring Boot to AWS:
- EC2 - Full control, manual setup, best for custom configurations
- Elastic Beanstalk - Managed platform, auto-scaling included, best for most applications
- ECS with Fargate - Containerized deployment, best for Docker workloads
For your first deployment, I recommend Elastic Beanstalk. It’s the simplest option and handles most operational tasks for you. As your application grows, you can migrate to ECS for more advanced container orchestration.
The key is to start simple. Deploy your application, secure it, set up monitoring, then optimize for cost and performance based on actual usage.
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments