홈 › 리눅스 운영 › 04 / 13

자바 애플리케이션 배포

섹션 7진행 0 / 13

3. 코드 예제

예제 1: 변수와 pid 확인 — app.sh 발췌

bash
APP_HOME=${APP_HOME:-/opt/myapp}
JAVA=${JAVA_HOME:+$JAVA_HOME/bin/}java
JAVA_OPTS=${JAVA_OPTS:--Xms256m -Xmx512m -Djava.security.egd=file:/dev/./urandom}
PID_FILE=$APP_HOME/run/$APP_NAME.pid
[ -f "$APP_HOME/conf/env" ] && . "$APP_HOME/conf/env"

pid_alive() { [ -f "$PID_FILE" ] && kill -0 "$(cat "$PID_FILE")" 2>/dev/null; }

${JAVA_HOME:+$JAVA_HOME/bin/} 은 JAVA_HOME 이 있을 때만 그 경로를 앞에 붙입니다. 없으면 PATH 의 java 를 씁니다. pid_alive 함수 하나를 start, stop, status 가 모두 씁니다.

예제 2: start·stop — app.sh 발췌

bash
do_start() {
  pid_alive && { echo "이미 실행 중 PID=$(cat "$PID_FILE")"; return 0; }
  cd "$APP_HOME" || exit 1
  nohup "$JAVA" $JAVA_OPTS -jar current/app.jar >> "$LOG" 2>&1 &
  echo $! > "$PID_FILE"
  sleep 1
  pid_alive && echo "started PID=$(cat "$PID_FILE")" || { tail -n 5 "$LOG"; exit 1; }
}
do_stop() {
  pid_alive || { echo "실행 중 아님"; rm -f "$PID_FILE"; return 0; }
  local pid; pid=$(cat "$PID_FILE")
  kill "$pid"
  for _ in $(seq 1 "$STOP_WAIT"); do
    kill -0 "$pid" 2>/dev/null || { echo "stopped PID=$pid"; rm -f "$PID_FILE"; return 0; }
    sleep 1
  done
  kill -9 "$pid"; rm -f "$PID_FILE"
}

시작 실패 시 로그 마지막 5줄을 바로 보여 주는 것이 작은 배려이지만 배포 중 가장 자주 쓰입니다. 포트 충돌, 설정 파일 오류가 그 5줄에 나옵니다.

예제 3: 데모 실행 결과 — demo.sh

demo.sh 는 Hello.java 를 jar 두 버전으로 묶고 임시 폴더를 APP_HOME 으로 삼아 전체 흐름을 돌립니다.

bash
echo 'JAVA_OPTS="-Xmx128m -Dapp.version=v1"' > "$APP_HOME/conf/env"
bash app.sh deploy build/app-v1.jar
bash app.sh start
bash app.sh status
tail -n 1 "$APP_HOME/logs/stdout.log"
text
deployed: /tmp/tmp.IQORIXGGai/releases/20260910_163658
started PID=581
running PID=581 current=20260910_163658
Hello v1 started, maxHeap=128MB

maxHeap=128MB 가 conf/env 의 -Xmx128m 이 적용됐다는 증거입니다. 앱 코드는 System.getProperty("app.version") 으로 -D 값을 읽습니다.

예제 4: 배포·롤백 결과 — demo.sh

bash
bash app.sh stop                      # Git Bash 는 실행 중 jar 교체 불가
bash app.sh deploy build/app-v2.jar   # 리눅스는 stop 없이 deploy 후 restart
bash app.sh start
bash app.sh rollback
bash app.sh status
ls "$APP_HOME/releases"
text
deployed: /tmp/tmp.IQORIXGGai/releases/20260910_163707
started PID=615
Hello v2 started, maxHeap=128MB
stopped PID=615
rolled back: /tmp/tmp.IQORIXGGai/releases/20260910_163658
started PID=636
running PID=636 current=20260910_163658
20260910_163658
20260910_163707

롤백 뒤 current 가 첫 릴리스로 돌아갔고 두 릴리스 폴더가 모두 남아 있습니다. Git Bash 에서는 TERM 이 강제 종료로 전달돼 shutdown hook 로그가 0건이고, 리눅스에서는 1건이 찍힙니다.