Spring Boot μ± Nginxλ‘ λ°°ν¬νκΈ°
κ°μ
Spring Boot μ±μ λ΄μ₯ ν°μΊ£μμ μ€νλλ©°, Nginxλ 리λ²μ€ νλ‘μλ‘μ μλ¨μμ μμ²μ λ°μ Spring Bootμ μ λ¬νλ€.
Reactλ μ μ νμΌμ μ§μ μλΉνλ©΄ λμ§λ§, Spring Bootλ λ€λ¦
λλ€! Spring Bootλ μκΈ° μμ μ΄ μΉ μλ²(λ΄μ₯ ν°μΊ£)λ₯Ό κ°μ§κ³ μμ΄μ μ€μ€λ‘ HTTP μμ²μ μ²λ¦¬ν μ μμ΄μ.
κ·Έλ°λ° μ Nginxλ₯Ό μμ λλκ³ μ? Nginxκ° μμμ SSL μ²λ¦¬, λ‘λ λ°Έλ°μ±, μ μ νμΌ μΊμ±, 보μμ λ΄λΉν΄μ£Όλ©΄, Spring Bootλ λΉμ¦λμ€ λ‘μ§μλ§ μ§μ€ν μ μκ±°λ μ. λ§μΉ μλΉμμ ν μ§μ(Nginx)μ΄ μλ μλλ₯Ό νκ³ , μ£Όλ°©μ₯(Spring Boot)μ μ리μλ§ μ§μ€νλ κ²κ³Ό κ°μμ!
λ°°ν¬ μν€ν
μ²
graph LR
A[π€ μ¬μ©μ<br/>λΈλΌμ°μ ] -->|"<https://api.example.com><br/>ν¬νΈ 443"| B[π₯οΈ Nginx<br/>리λ²μ€ νλ‘μ]
B -->|"<http://localhost:8080><br/>λ΄λΆ ν΅μ "| C[π Spring Boot<br/>λ΄μ₯ ν°μΊ£]
C --> D[ποΈ Database<br/>MySQL/PostgreSQL]
style B fill:#90EE90
style C fill:#87CEEBMermaid
볡μ¬
flowchart TD
A["π» λ‘컬 κ°λ°"] -->|"./gradlew build<br/>λλ mvn package"| B["π¦ JAR νμΌ μμ±<br/>app.jar"]
B -->|"scp λλ CI/CD"| C["π₯οΈ μλ²μ μ
λ‘λ"]
C --> D["π java -jar app.jar<br/>Spring Boot μ€ν"]
D --> E["βοΈ Nginx 리λ²μ€ νλ‘μ<br/>μ€μ + SSL"]
E --> F["π μλΉμ€ μ€ν!"]
style B fill:#FFD700
style E fill:#90EE90Mermaid
볡μ¬
Step 1: Spring Boot μ± λΉλ
# Gradle νλ‘μ νΈ
./gradlew clean build -x test
# κ²°κ³Ό: build/libs/myapp-0.0.1-SNAPSHOT.jar
# Maven νλ‘μ νΈ
mvn clean package -DskipTests
# κ²°κ³Ό: target/myapp-0.0.1-SNAPSHOT.jar
Bash
볡μ¬
Step 2: μλ²μ μ
λ‘λ λ° μ€ν
# JAR νμΌ μ
λ‘λ
scp build/libs/myapp-0.0.1-SNAPSHOT.jar ubuntu@μλ²IP:/home/ubuntu/app/
# μλ²μμ μ€ν
cd /home/ubuntu/app
java -jar myapp-0.0.1-SNAPSHOT.jar
Bash
볡μ¬
Systemd μλΉμ€λ‘ λ±λ‘ (κΆμ₯!)
ν°λ―Έλμμ μ§μ java -jarλ‘ μ€ννλ©΄, SSH μ°κ²°μ΄ λμ΄μ§λ©΄ μ±λ κ°μ΄ μ£½μ΄μ. κ·Έλμ systemd μλΉμ€λ‘ λ±λ‘ν΄μΌ ν΄μ!
sudo nano /etc/systemd/system/myapp.service
Bash
볡μ¬
[Unit]
Description=My Spring Boot Application
After=network.target
[Service]
User=ubuntu
ExecStart=/usr/bin/java -jar /home/ubuntu/app/myapp-0.0.1-SNAPSHOT.jar
SuccessExitStatus=143
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
Environment=SPRING_PROFILES_ACTIVE=prod
Environment=SERVER_PORT=8080
[Install]
WantedBy=multi-user.target
Plain Text
볡μ¬
# μλΉμ€ λ±λ‘ λ° μμ
sudo systemctl daemon-reload
sudo systemctl start myapp
sudo systemctl enable myapp
# μν νμΈ
sudo systemctl status myapp
# λ‘κ·Έ νμΈ
sudo journalctl -u myapp -f
Bash
볡μ¬
νλͺ© | μ€λͺ
|
After=network.target | λ€νΈμν¬κ° μ€λΉλ ν μμ |
Restart=always | μ±μ΄ μ£½μΌλ©΄ μλ μ¬μμ |
RestartSec=5 | μ¬μμ μ 5μ΄ λκΈ° |
Environment | νκ²½ λ³μ μ€μ (νλ‘νμΌ, ν¬νΈ λ±) |
Step 3: Nginx 리λ²μ€ νλ‘μ μ€μ
sudo nano /etc/nginx/sites-available/spring-app
Bash
볡μ¬
server {
listen 80;
server_name api.example.com;
# β 리λ²μ€ νλ‘μ β Spring Bootλ‘ μ λ¬
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;
# νμμμ μ€μ
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# WebSocket μ§μ (νμμ)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# ν° νμΌ μ
λ‘λ νμ©
client_max_body_size 10M;
}
Plain Text
볡μ¬
νλ‘μ ν€λκ° μ νμν΄?
sequenceDiagram
participant μ¬μ©μ as π€ μ¬μ©μ<br/>IP: 203.0.113.50
participant Nginx as π₯οΈ Nginx<br/>IP: 10.0.0.1
participant Spring as π Spring Boot<br/>IP: 127.0.0.1
μ¬μ©μ->>Nginx: μμ² (IP: 203.0.113.50)
Note over Nginx: ν€λ μμ΄ μ λ¬νλ©΄<br/>Springμ Nginx IPλ§ λ³΄μ
Nginx->>Spring: μμ² μ λ¬
Note over Nginx,Spring: X-Real-IP: 203.0.113.50<br/>X-Forwarded-For: 203.0.113.50<br/>X-Forwarded-Proto: https
Note over Spring: μ΄μ μ§μ§ μ¬μ©μ IPλ₯Ό<br/>μ μ μμ΄μ!Mermaid
볡μ¬
ν€λ | μν |
Host | μλ μμ²λ λλ©μΈ μ΄λ¦ |
X-Real-IP | μ€μ ν΄λΌμ΄μΈνΈ IP |
X-Forwarded-For | νλ‘μ 체μΈμ κ±°μΉ IP λͺ©λ‘ |
X-Forwarded-Proto | μλ νλ‘ν μ½ (http/https) |
μ΄ ν€λκ° μμΌλ©΄ Spring Bootλ λͺ¨λ μμ²μ΄ 127.0.0.1(Nginx)μμ μ¨ κ²μΌλ‘ μΈμν΄μ. μ¬μ©μμ μ§μ§ IPλ₯Ό μ μ μκ² λλ κ±°μ£ !
Step 4: νμ±ν λ° SSL μ μ©
# μ¬μ΄νΈ νμ±ν
sudo ln -s /etc/nginx/sites-available/spring-app /etc/nginx/sites-enabled/
# ν
μ€νΈ λ° μ μ©
sudo nginx -t && sudo systemctl reload nginx
# SSL μ μ©
sudo certbot --nginx -d api.example.com
Bash
볡μ¬
μ΅μ’
μ€μ (HTTPS ν¬ν¨)
# μ
μ€νΈλ¦Ό μ μ (λ‘λ λ°Έλ°μ± λλΉ)
upstream spring_backend {
server localhost:8080;
}
server {
listen 443 ssl http2;
server_name api.example.com;
ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
# 리λ²μ€ νλ‘μ
location / {
proxy_pass http://spring_backend;
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;
}
# Health Check μλν¬μΈνΈ (λ‘κΉ
μ μΈ)
location = /actuator/health {
proxy_pass http://spring_backend;
access_log off;
}
client_max_body_size 10M;
}
server {
listen 80;
server_name api.example.com;
return 301 https://$host$request_uri;
}
Plain Text
볡μ¬
Spring Boot application.yml μ€μ
server:
port: 8080
forward-headers-strategy: framework # β νλ‘μ ν€λ μΈμ (νμ!)
# Actuator (Health Check)
management:
endpoints:
web:
exposure:
include: health
YAML
볡μ¬
forward-headers-strategy: framework μ€μ μ κΌ ν΄μ£ΌμΈμ! μ΄κ±Έ μ νλ©΄ Spring Bootκ° Nginxκ° λ³΄λ΄μ£Όλ X-Forwarded-* ν€λλ₯Ό 무μν΄μ.
μμ£Ό λ°μνλ λ¬Έμ
λ¬Έμ | μμΈ | ν΄κ²° |
502 Bad Gateway | Spring Bootκ° μ λμκ°κ³ μμ | systemctl status myappμΌλ‘ νμΈ |
504 Gateway Timeout | μλ΅ μκ° μ΄κ³Ό | proxy_read_timeout λ리기 |
CORS μλ¬ | νλ‘ νΈ-λ°± λλ©μΈ λ€λ¦ | Spring Bootμ CORS μ€μ or Nginxμμ μ²λ¦¬ |
리λ€μ΄λ νΈ λ¬΄ν 루ν | X-Forwarded-Proto λ―Έμ€μ | νλ‘μ ν€λ μ€μ νμΈ |
νμΌ μ
λ‘λ μ€ν¨ | ν¬κΈ° μ ν | client_max_body_size λ리기 |
μ€μ΅
μ€μ΅ νκ²½
νλͺ© | κ° |
λ‘컬 νλ‘μ νΈ | Spring Boot + Gradle |
λΉλ κ²°κ³Όλ¬Ό | build/libs/APP.war |
μλ² | alohaserver4.cafe24.com |
WAR λ°°ν¬ κ²½λ‘ | /var/www/krules/backend/ |
μ μ΄ μ€ν¬λ¦½νΈ | start.sh / stop.sh / restart.sh |
SSH μ μ | Host alias alohaserver4 μ¬μ© |
Spring Bootλ νμΌ λ³΅μ¬λ§μΌλ‘ λλμ§ μμμ. APP.war μ
λ‘λ β restart.sh μ격 μ€ν μμλ‘ λ°°ν¬ν΄μΌ ν΄μ!
λ°°ν¬ νμΌ κ΅¬μ‘°
πΒ νλ‘μ νΈ λ£¨νΈ/
βββ πΒ deploy.bat β λΉλ + μ
λ‘λ + μ¬μμ μλν
βββ πΒ start.bat β μλ² μ± μ격 μμ
βββ πΒ stop.bat β μλ² μ± μ격 μ’
λ£
βββ πΒ restart.bat β μλ² μ± μ격 μ¬μμ
πΒ μλ² /var/www/krules/backend/
βββ π»Β APP.war β λ°°ν¬λ μ ν리μΌμ΄μ
βββ πΒ start.sh β APP.war λ°±κ·ΈλΌμ΄λ μ€ν (λ‘κ·Έ μ μ₯)
βββ πΒ stop.sh β APP.war νλ‘μΈμ€ μ’
λ£
βββ πΒ restart.sh β stop.sh β start.sh μμλ‘ μ¬μμ
πΒ μλ² /var/www/krules/log/
βββ π°Β appwar_20260422_120000.log β μ€ν λ‘κ·Έ (start.sh μλ μμ±)
Plain Text
볡μ¬
μ¬μ μ€λΉ: μλ² λλ ν 리 μμ± (μ΅μ΄ 1ν)
# μλ² μ μ
ssh alohaserver4
# λ°°ν¬ κ²½λ‘ μμ±
mkdir -p /var/www/krules/backend
mkdir -p /var/www/krules/log
Bash
볡μ¬
start.sh
#!/bin/bash
# νμ¬ μ€ν¬λ¦½νΈκ° μμΉν κ²½λ‘λ‘ μ΄λ
cd "$(dirname "$0")"
# λ‘κ·Έ λλ ν 리 μμ±
LOG_DIR="../log"
mkdir -p "$LOG_DIR"
LOG_FILE="$LOG_DIR/appwar_$(date +%Y%m%d_%H%M%S).log"
# JAVA_HOMEμ΄ μ€μ λμ΄ μμ§ μμΌλ©΄ java λͺ
λ Ήμ΄ μ¬μ©
JAVA_CMD=${JAVA_HOME:-}/bin/java
if [ ! -x "$JAVA_CMD" ]; then
JAVA_CMD=java
fi
# JVM λ©λͺ¨λ¦¬ μ ν (μ΅μ 128MB, μ΅λ 256MB)
JAVA_OPTS="-Xms128m -Xmx256m"
# Spring νλ‘νμΌ λͺ
μ (server = μ€μλ² μ€μ , local = λ‘컬 κ°λ°)
SPRING_OPTS="--spring.profiles.active=server"
# APP.war νμΌμ λ°±κ·ΈλΌμ΄λμμ μ€ννκ³ λ‘κ·Έ μ μ₯
$JAVA_CMD $JAVA_OPTS -jar APP.war $SPRING_OPTS > "$LOG_FILE" 2>&1 &
JavaScript
볡μ¬
stop.sh
#!/bin/bash
# APP.war νλ‘μΈμ€ μ’
λ£ μ€ν¬λ¦½νΈ
# νμ¬ κ²½λ‘μ APP.war νλ‘μΈμ€λ§ μ’
λ£
cd "$(dirname "$0")"
APP_PATH="$(pwd)/APP.war"
PIDS=$(ps -ef | grep '[j]ava.*-jar' | grep "$APP_PATH" | awk '{print $2}')
if [ -z "$PIDS" ]; then
echo "μ€ν μ€μΈ APP.war νλ‘μΈμ€κ° μμ΅λλ€."
exit 0
fi
for PID in $PIDS; do
echo "APP.war νλ‘μΈμ€ μ’
λ£: $PID"
kill $PID
sleep 1
if ps -p $PID > /dev/null; then
echo "κ°μ μ’
λ£: $PID"
kill -9 $PID
fi
echo "μ’
λ£ μλ£: $PID"
sleep 1
done
echo "λͺ¨λ APP.war νλ‘μΈμ€κ° μ’
λ£λμμ΅λλ€."
JavaScript
볡μ¬
restart.sh (νλ‘μ νΈ λ£¨νΈμ μ μ₯)
start.shμ stop.shλ₯Ό μμλλ‘ νΈμΆνλ μ¬μμ μ€ν¬λ¦½νΈμμ.
#!/bin/bash
# APP.war μ¬μμ μ€ν¬λ¦½νΈ (stop.sh β start.sh μμλ‘ μ€ν)
cd "$(dirname "$0")"
echo "=== APP.war μ¬μμ μμ ==="
# κΈ°μ‘΄ νλ‘μΈμ€ μ’
λ£
bash stop.sh
# νλ‘μΈμ€ μμ μ’
λ£ λκΈ°
sleep 2
# μ νλ‘μΈμ€ μμ
bash start.sh
echo "=== APP.war μ¬μμ μλ£ ==="
Bash
볡μ¬
1λ¨κ³: μλ λ°°ν¬
flowchart TB
A["π» λ‘컬<br>gradlew clean bootWar"] -->|"APP.war μμ±"| B["π¦ APP.war"]
B -->|"scp μ
λ‘λ<br>WAR + sh νμΌ"| C["π₯οΈ μλ²<br>/var/www/krules/backend/"]
C -->|"plink restart.sh"| D["π Spring Boot μ¬μμ"]
D --> E["π λΈλΌμ°μ νμΈ"]Mermaid
볡μ¬
# 1. λ‘컬μμ WAR λΉλ
./gradlew clean bootWar
# λΉλ κ²°κ³Ό νμΈ
ls build/libs/
# APP.war νμΌ μμ±λ¨
# 2. μλ²μ APP.war + sh νμΌ μ
λ‘λ
scp build/libs/APP.war alohaserver4:/var/www/krules/backend/APP.war
scp start.sh stop.sh restart.sh alohaserver4:/var/www/krules/backend/
# 3. sh νμΌ μ€ν κΆν λΆμ¬ (μ΅μ΄ 1ν)
ssh alohaserver4 "chmod +x /var/www/krules/backend/*.sh"
# 4. restart.sh μ격 μ€ν
ssh alohaserver4 "cd /var/www/krules/backend && bash restart.sh"
# 5. λ‘κ·Έ νμΈ
ssh alohaserver4 "tail -f /var/www/krules/log/appwar_*.log"
Bash
볡μ¬
2λ¨κ³: νλ‘ νΈμλ .env νκ²½λ³μ μ€μ
λ°±μλ API μ£Όμλ₯Ό νκ²½μ λ°λΌ λΆλ¦¬ν΄μ κ΄λ¦¬ν΄μ. Vite νλ‘μ νΈλ VITE_ μ λμ¬, CRAλ REACT_APP_ μ λμ¬λ₯Ό λΆμ¬μΌ μΈμν΄μ.
# .env.local (λ‘컬 κ°λ°μ© β .gitignoreμ μΆκ° κΆμ₯)
VITE_API_URL=http://localhost:8080/api
# VITE_API_URL=http://192.168.30.19:8080/api # κ°μ λ€νΈμν¬ λ€λ₯Έ PC ν
μ€νΈ
# .env.production (λ°°ν¬μ©)
# λ°©μ A (μλΈλλ©μΈ): api.κ΅λ£°.com β Spring Boot
# VITE_API_URL=http://xn--3e0b91t.com/api # HTTP μ μ© μ
# VITE_API_URL=https://api.xn--3e0b91t.com/api # HTTPS μ μ© ν
# λ°©μ B (리λ²μ€ νλ‘μ): κ΅λ£°.com/api β Spring Boot
# VITE_API_URL=http://xn--3e0b91t.com/api # HTTP μ μ© μ
# VITE_API_URL=https://xn--3e0b91t.com/api # HTTPS μ μ© ν
Bash
볡μ¬
React μ½λμμ μ΄λ κ² μ¬μ©ν΄μ:
// νκ²½λ³μλ‘ API μ£Όμλ₯Ό μ½μ΄μ΄
const res = await fetch(`${import.meta.env.VITE_API_URL}/products`);
JavaScript
볡μ¬
3λ¨κ³: Nginx 리λ²μ€ νλ‘μ μ€μ β λ°©μ μ ν
λ κ°μ§ λ°©μμ΄ μμ΄μ. μν©μ λ§κ² νλλ₯Ό μ ννμΈμ!
graph TD
A["π μ¬μ©μ μμ²"] --> B{λ°©μ μ ν}
B -->|"λ°©μ A<br>μλΈλλ©μΈ"| C["api.κ΅λ£°.com<br>β Spring Boot :8080"]
B -->|"λ°©μ B<br>리λ²μ€ νλ‘μ"| D["κ΅λ£°.com/api/**<br>β Spring Boot :8080"]
C --> E["π Spring Boot"]
D --> EMermaid
볡μ¬
λΉκ΅ | λ°©μ A β μλΈλλ©μΈ | λ°©μ B β κ²½λ‘ κΈ°λ° λ¦¬λ²μ€ νλ‘μ |
API URL | api.κ΅λ£°.com/api/... | κ΅λ£°.com/api/... |
DNS μ€μ | api μλΈλλ©μΈ Aλ μ½λ μΆκ° νμ | μΆκ° DNS λΆνμ |
SSL μΈμ¦μ | api μλΈλλ©μΈ μΈμ¦μ λ³λ λ°κΈ | κΈ°μ‘΄ λλ©μΈ μΈμ¦μ 곡μ |
Nginx νμΌ μ | 2κ° (νλ‘ νΈ + λ°±μλ κ°κ°) | 1κ° (νλμ server λΈλ‘μ ν΅ν©) |
μΆμ² μν© | API μλ²λ₯Ό λ
립μ μΌλ‘ κ΄λ¦¬ν λ | λλ©μΈ νλλ‘ νμ€νμ λ¨μνκ² κ΅¬μ±ν λ |
λ°©μ A β μλΈλλ©μΈ (api.κ΅λ£°.com)
ssh alohaserver4
nano /etc/nginx/conf.d/krules-backend.conf
Bash
볡μ¬
# λ°±μλ μ μ© μλ² λΈλ‘ (api μλΈλλ©μΈ)
server {
listen 80;
server_name api.xn--3e0b91t.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;
proxy_connect_timeout 60s;
proxy_read_timeout 60s;
}
client_max_body_size 10M;
}
Plain Text
볡μ¬
νλ‘ νΈμλ .env.production:
VITE_API_URL=https://api.xn--3e0b91t.com/api
Bash
볡μ¬
λ°©μ B β κ²½λ‘ κΈ°λ° λ¦¬λ²μ€ νλ‘μ (κ΅λ£°.com/api)
νλ‘ νΈμλμ λ°±μλλ₯Ό νλμ Nginx μλ² λΈλ‘μμ μ²λ¦¬ν΄μ. λλ©μΈ νλλ‘ νμ€ν ꡬμ±ν λ νΈν΄μ!
ssh alohaserver4
nano /etc/nginx/conf.d/krules.conf
Bash
볡μ¬
server {
listen 80;
server_name xn--3e0b91t.com www.xn--3e0b91t.com;
# ββ νλ‘ νΈμλ (React Vite μ μ νμΌ) ββββββββββββββββββ
root /var/www/krules/frontend;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
location /assets/ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# ββ λ°±μλ (Spring Boot 리λ²μ€ νλ‘μ) βββββββββββββββββ
# /api/ λ‘ μμνλ μμ²μ Spring Bootλ‘ μ λ¬
location /api/ {
proxy_pass <http://localhost:8080>; # β /api/ κ²½λ‘ κ·Έλλ‘ μ λ¬
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;
proxy_connect_timeout 60s;
proxy_read_timeout 60s;
client_max_body_size 10M;
}
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml;
}
Plain Text
볡μ¬
proxy_pass <http://localhost:8080>; β λμ / λ₯Ό λΆμ΄μ§ μμΌλ©΄ /api/ κ²½λ‘κ° κ·Έλλ‘ Spring Bootμ μ λ¬λΌμ. Spring Bootμ RequestMappingλ /api/... λ‘ λ§μΆ°μΌ ν΄μ!
νλ‘ νΈμλ .env.production:
VITE_API_URL=https://xn--3e0b91t.com/api
Bash
볡μ¬
nginx -t && systemctl reload nginx
Bash
볡μ¬
3λ¨κ³: κ°λ³ μ μ΄ bat νμΌ (μλ² κ΄λ¦¬μ©)
PuTTYμ plink.exe(μ격 λͺ
λ Ή), pscp.exe(νμΌ λ³΅μ¬)λ₯Ό μ¬μ©ν΄μ.
μ€μΉ: https://www.putty.org/ β λ€μ΄λ‘λ ν PATHμ μΆκ°νκ±°λ bat νμΌκ³Ό κ°μ ν΄λμ λμΈμ.
start.bat
@echo off
chcp 65001 > nul
set REMOTE_USER=root
set REMOTE_HOST=alohaserver4.cafe24.com
set REMOTE_PATH=/var/www/krules/backend
:: π λΉλ°λ²νΈ μ
λ ₯ (μ 보μ΄κ²)
for /f "delims=" %%p in ('powershell -Command "$p = Read-Host ''SSH Password'' -AsSecureString; $BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($p); [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)"') do set REMOTE_PASS=%%p
echo [START] Spring Boot μ± μμ μ€...
plink -pw %REMOTE_PASS% %REMOTE_USER%@%REMOTE_HOST% "cd %REMOTE_PATH% && bash start.sh"
echo μλ£!
pause
Shell
볡μ¬
stop.bat
@echo off
chcp 65001 > nul
set REMOTE_USER=root
set REMOTE_HOST=alohaserver4.cafe24.com
set REMOTE_PATH=/var/www/krules/backend
:: π λΉλ°λ²νΈ μ
λ ₯ (μ 보μ΄κ²)
for /f "delims=" %%p in ('powershell -Command "$p = Read-Host ''SSH Password'' -AsSecureString; $BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($p); [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)"') do set REMOTE_PASS=%%p
echo [STOP] Spring Boot μ± μ’
λ£ μ€...
plink -pw %REMOTE_PASS% %REMOTE_USER%@%REMOTE_HOST% "cd %REMOTE_PATH% && bash stop.sh"
echo μλ£!
pause
Shell
볡μ¬
restart.bat
@echo off
chcp 65001 > nul
set REMOTE_USER=root
set REMOTE_HOST=alohaserver4.cafe24.com
set REMOTE_PATH=/var/www/krules/backend
:: π λΉλ°λ²νΈ μ
λ ₯ (μ 보μ΄κ²)
for /f "delims=" %%p in ('powershell -Command "$p = Read-Host ''SSH Password'' -AsSecureString; $BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($p); [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)"') do set REMOTE_PASS=%%p
echo [RESTART] Spring Boot μ± μ¬μμ μ€...
plink -pw %REMOTE_PASS% %REMOTE_USER%@%REMOTE_HOST% "cd %REMOTE_PATH% && bash restart.sh"
echo μλ£!
pause
Shell
볡μ¬
4λ¨κ³: ν΅ν© λ°°ν¬ μλν (deploy.bat)
clean bootWar β APP.war + sh νμΌ μ
λ‘λ β restart.sh μ격 μ€νκΉμ§ ν λ²μ!
deploy.bat
@echo off
chcp 65001 > nul
echo.
echo =============================================
echo Spring Boot bootWar Build ^& Deploy
echo =============================================
echo.
:: ββββββββββββββββββββββββββββββββββββββββββββ
:: μ€μ κ°
:: ββββββββββββββββββββββββββββββββββββββββββββ
set PROJECT_DIR=%~dp0
set REMOTE_USER=root
set REMOTE_HOST=alohaserver4.cafe24.com
set REMOTE_PATH=/var/www/krules/backend
:: π λΉλ°λ²νΈ μ
λ ₯ (μ 보μ΄κ²)
for /f "delims=" %%p in ('powershell -Command "$p = Read-Host ''SSH Password'' -AsSecureString; $BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($p); [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)"') do set REMOTE_PASS=%%p
echo.
:: ββββββββββββββββββββββββββββββββββββββββββββ
:: [1] bootWar λΉλ
:: ββββββββββββββββββββββββββββββββββββββββββββ
echo [1/3] bootWar λΉλ μ€...
cd /d %PROJECT_DIR%
call gradlew.bat clean bootWar
if errorlevel 1 (
echo.
echo [μ€λ₯] λΉλ μ€ν¨! μλ¬λ₯Ό νμΈνμΈμ.
pause
exit /b 1
)
echo λΉλ μλ£ - APP.war μμ±λ¨
echo.
:: ββββββββββββββββββββββββββββββββββββββββββββ
:: [2] νμΌ μ
λ‘λ
:: ββββββββββββββββββββββββββββββββββββββββββββ
echo [2/3] νμΌ μ
λ‘λ μ€...
pscp -pw %REMOTE_PASS% build\libs\APP.war %REMOTE_USER%@%REMOTE_HOST%:%REMOTE_PATH%/APP.war
if errorlevel 1 (
echo.
echo [μ€λ₯] WAR μ
λ‘λ μ€ν¨!
pause
exit /b 1
)
pscp -pw %REMOTE_PASS% start.sh stop.sh restart.sh %REMOTE_USER%@%REMOTE_HOST%:%REMOTE_PATH%/
echo μ
λ‘λ μλ£
echo.
:: ββββββββββββββββββββββββββββββββββββββββββββ
:: [3] μλ² μ¬μμ
:: ββββββββββββββββββββββββββββββββββββββββββββ
echo [3/3] μλ² μ¬μμ μ€...
plink -pw %REMOTE_PASS% %REMOTE_USER%@%REMOTE_HOST% "chmod +x %REMOTE_PATH%/*.sh && cd %REMOTE_PATH% && bash restart.sh"
if errorlevel 1 (
echo.
echo [μ€λ₯] μ¬μμ μ€ν¨!
pause
exit /b 1
)
:: ββββββββββββββββββββββββββββββββββββββββββββ
:: [4] μλ£
:: ββββββββββββββββββββββββββββββββββββββββββββ
echo.
echo =============================================
echo λ°°ν¬ μλ£!
echo λ‘κ·Έ νμΈ:
echo ssh %REMOTE_USER%@%REMOTE_HOST%
echo tail -f /var/www/krules/log/appwar_*.log
echo =============================================
echo.
pause
Shell
볡μ¬
μ€ν λ°©λ²: deploy.bat λλΈν΄λ¦ β bootWar λΉλ β WAR + sh μ
λ‘λ β restart.sh μ€νκΉμ§ μλ!
(μ ν) SSH ν€ μΈμ¦μΌλ‘ λΉλ°λ²νΈ μμ΄ λ°°ν¬
# 1. SSH ν€ μμ± (μ΄λ―Έ μμΌλ©΄ μλ΅)
ssh-keygen -t ed25519 -C "deploy-key"
# 2. 곡κ°ν€λ₯Ό μλ²μ λ±λ‘
ssh-copy-id alohaserver4
Bash
볡μ¬
ν€ λ±λ‘ ν κ° bat νμΌμμ pscp -pw / plink -pw λμ νμ€ λͺ
λ ΉμΌλ‘ κ΅μ²΄:
:: WAR μ
λ‘λ (pscp β scp)
scp build\\libs\\APP.war alohaserver4:%REMOTE_PATH%/APP.war
scp start.sh stop.sh restart.sh alohaserver4:%REMOTE_PATH%/
:: μ격 μ€ν (plink β ssh)
ssh alohaserver4 "chmod +x %REMOTE_PATH%/*.sh && cd %REMOTE_PATH% && bash restart.sh"
Shell
볡μ¬
체ν¬λ¦¬μ€νΈ
~/.ssh/config μ alohaserver4 Host μ€μ μλ£?
μλ²μ /var/www/krules/backend/ λ° /var/www/krules/log/ λλ ν 리 μμ±?
νλ‘μ νΈ λ£¨νΈμ start.sh / stop.sh / restart.sh νμΌ μ‘΄μ¬?
./gradlew clean bootWar β build/libs/APP.war μμ± νμΈ?
scp APP.war + *.sh μ
λ‘λ μ±κ³΅?
μλ²μμ chmod +x /var/www/krules/backend/*.sh μλ£?
ssh alohaserver4 "cd /var/www/krules/backend && bash restart.sh" μ€ν νμΈ?
tail -f /var/www/krules/log/appwar_*.log λ‘ μ μ κΈ°λ λ‘κ·Έ νμΈ?
Nginx conf.d/krules-backend.conf 리λ²μ€ νλ‘μ μ€μ ?
nginx -t ν΅κ³Ό λ° systemctl reload nginx μλ£?
start.bat / stop.bat / restart.bat κ°λ³ λμ νμΈ?
deploy.bat ν΅ν© λ°°ν¬ ν
μ€νΈ μλ£?
ν΅μ¬ μ 리
Spring Boot = λ΄μ₯ ν°μΊ£μΌλ‘ μ체 μ€ν β Nginxλ 리λ²μ€ νλ‘μ μν
systemd μλΉμ€ λ±λ‘μΌλ‘ μ± μλ μμ/μ¬μμ 보μ₯
νλ‘μ ν€λ(X-Real-IP, X-Forwarded-For λ±) μ€μ νμ
Spring Boot forward-headers-strategy: framework μ€μ νμ
CertbotμΌλ‘ HTTPS μ μ© + HTTPβHTTPS 리λ€μ΄λ νΈ




