π§ Overview
In this guide, Iβll walk you through a complete deployment pipeline for Spring Boot services using GitHub Actions, Ubuntu servers, and Nginx. We'll deploy two environmentsβDev and Prodβon separate servers and configure:
β
Systemd-based service management
β
Auto-start on reboot
β
Reverse proxy with Nginx
β
CI/CD using GitHub Actions
β
Branch-based deployment:
β Push to dev β Deploys to Dev server
β Push to main β Deploys to Prod server
ββββββββββββββ
β Static IP β
β your-ip β
ββββββ¬ββββββββ
β
ββββββββ΄βββββββ
β Reverse β
β Proxy β
β (Nginx) β
ββββββ¬ββββββββ
ββββββββ΄ββββββββ
β β
βββββββΌββββββ ββββββΌββββββ
β Dev Serverβ β Prod Serverβ
βyour-ip β β your-ip |
β Port 8081 β β Port 8082 β
βββββββββββββ ββββββββββββββ
π§ 1. Initial Server Setup
β
Install Java 21
sudo apt update && sudo apt upgrade -y
sudo apt install openjdk-21-jdk -y
java -version
π Create App Directory
mkdir ~/apps
cd ~/apps
π¦ 2. Deploy Spring Boot Applications
Upload your JARs to respective servers:
scp dev-app.jar ubuntu@your-ip:/home/ubuntu/apps/
scp prod-app.jar ubuntu@your-ip:/home/ubuntu/apps/
βοΈ 3. Create systemd Services
Use environment variables for better flexibility.
π Create Environment Files
On Dev Server:
echo "SERVER_PORT=8081" > /home/ubuntu/apps/dev.env
On Prod Server:
echo "SERVER_PORT=8082" > /home/ubuntu/apps/prod.env
π§ͺ Dev Service: /etc/systemd/system/dev-app.service
[Unit]
Description=Spring Boot Dev Application
After=network.target
[Service]
User=ubuntu
WorkingDirectory=/home/ubuntu/apps
EnvironmentFile=/home/ubuntu/apps/dev.env
ExecStart=/usr/bin/java -jar /home/ubuntu/apps/dev-app.jar --server.port=${SERVER_PORT}
SuccessExitStatus=143
Restart=always
RestartSec=5
StandardOutput=file:/home/ubuntu/apps/dev-output.log
StandardError=file:/home/ubuntu/apps/dev-error.log
[Install]
WantedBy=multi-user.target
Repeat similarly for prod-app.service with prod.env.
βΆοΈ 4. Enable and Start Services
sudo systemctl daemon-reload
sudo systemctl enable dev-app # On Dev Server
sudo systemctl enable prod-app # On Prod Server
sudo systemctl start dev-app
sudo systemctl start prod-app
β
5. Verify Deployment
Check status:
systemctl status dev-app
systemctl status prod-app
Test API:
curl http://:8081/endpoint
curl http://:8082/endpoint
π 6. CI/CD: Auto-Deploy with GitHub Actions
Create workflow files for each branch.
Example: .github/workflows/deploy-dev.yml
on:
push:
branches: [dev]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Copy JAR to Dev Server
uses: appleboy/scp-action@master
with:
host: ${{ secrets.DEV_HOST }}
username: ubuntu
key: ${{ secrets.SSH_KEY }}
source: target/dev-app.jar
target: /home/ubuntu/apps/dev-app.jar
- name: Restart Dev App
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.DEV_HOST }}
username: ubuntu
key: ${{ secrets.SSH_KEY }}
script: sudo systemctl restart dev-app
Repeat similarly for main branch β Prod server.
π 7. Logging with Rotation
Logs are stored at:
/home/ubuntu/apps/dev-output.log
/home/ubuntu/apps/prod-output.log
π¦ Add Log Rotation
Create /etc/logrotate.d/dev-app:
/home/ubuntu/apps/dev-output.log {
daily
rotate 7
compress
missingok
notifempty
copytruncate
}
Repeat for prod-output.log.
π‘οΈ 8. Security Best Practices
Enable UFW firewall:
sudo ufw allow 22
sudo ufw allow 80
sudo ufw allow 8081
sudo ufw allow 8082
sudo ufw enable
Disable root SSH login
Keep servers updated regularly
Use GitHub Secrets for all sensitive credentials
π 9. Optional: Reverse Proxy with Nginx
Install Nginx on your reverse proxy server:
sudo apt install nginx -y
Create config: /etc/nginx/sites-available/reverse-proxy
server {
listen 80;
server_name your-ip;
location /dev/ {
proxy_pass http://your-ip:8081/;
proxy_set_header Host $host;
}
location /prod/ {
proxy_pass http://your-ip:8082/;
proxy_set_header Host $host;
}
}
Enable and restart:
sudo ln -s /etc/nginx/sites-available/reverse-proxy /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
Test:
http://your-ip/dev/hello β Dev
http://your-ip/prod/hello β Prod
π§ Pro Tips for Production
Health Check : Use /actuator/health endpoint and restart if it fails
Monitoring : Use htop, glances, or Prometheus + Grafana
Docker (Optional) : Containerize apps to simplify deployment
Secrets : Always use .env files or GitHub Secrets
Recovery : Keep previous .jar backups or use versioned deployment folders
π Conclusion
With this setup, youβve built a complete, secure, and automated deployment pipeline for Spring Boot services:
Branch-based CI/CD deployment
Nginx reverse proxy with clean routing
Auto-restarting apps
Centralized logging with rotation
Optional Docker support for scaling later
π’ If this helped you, give a β€οΈ or comment below!
Follow me for more hands-on guides in DevOps, Linux, and Java π
Top comments (0)