728x90

한 줄 요약

nohuppgrep을 활용한 셸 스크립트 두 개로, Linux 서버에서 Spring Boot JAR를 안전하게 실행하고 종료할 수 있다.


핵심 개념 설명

nohup이란?

nohup은 "no hang up"의 약자로, 터미널 세션이 종료되어도 프로세스가 계속 실행되도록 유지하는 POSIX 표준 명령어다.
(참고: The Open Group Base Specifications Issue 7, IEEE Std 1003.1)

터미널 창을 닫거나 SSH 접속이 끊기면, 터미널에서 실행한 프로세스에 SIGHUP 신호가 전달되어 프로세스가 종료된다.
nohup은 이 신호를 무시(ignore)하도록 설정해 프로세스를 유지시킨다.

&(백그라운드 실행)이란?

명령어 끝에 &를 붙이면 해당 프로세스를 백그라운드에서 실행한다.
터미널을 블로킹하지 않고 다음 명령어를 바로 입력할 수 있다.

pgrep이란?

실행 중인 프로세스 목록에서 이름 또는 패턴으로 PID(프로세스 ID)를 검색하는 명령어다.
(참고: procps-ng 공식 문서)


실제 스크립트 분석

start.sh — 애플리케이션 시작

nohup java -jar /home/app/{프로젝트명}/{프로젝트명}.jar \
  --spring.config.location=/home/app/{프로젝트명}/application.properties \
  > /home/app/{프로젝트명}/app.log 2>&1 &
echo "실행했습니다. (PID: $!)"
구성 요소 역할
nohup 세션 종료 시 프로세스가 죽지 않도록 방지
java -jar 실행 가능한 JAR 파일을 JVM으로 실행
--spring.config.location 외부 설정 파일 경로를 Spring Boot에 전달 (Spring Boot 공식 문서 기준)
> app.log 2>&1 표준 출력(stdout)과 표준 에러(stderr)를 동일 파일로 리다이렉션
& 백그라운드 실행
$! 직전에 백그라운드로 실행한 프로세스의 PID

왜 설정 파일을 외부에 두는가?
JAR 내부의 application.properties를 수정하려면 재빌드가 필요하다.
--spring.config.location 옵션으로 외부 경로를 지정하면, JAR를 다시 빌드하지 않고도 설정을 변경할 수 있다.
(참고: Spring Boot Reference Documentation — Externalized Configuration)


stop.sh — 애플리케이션 종료

#!/bin/bash
PID=$(pgrep -f "{프로젝트명}.jar")
if [ -z "$PID" ]; then
  echo "실행 중인 프로세스가 없습니다."
else
  kill -9 $PID
  echo "종료했습니다. (PID: $PID)"
fi
구성 요소 역할
pgrep -f 프로세스 전체 명령어(full command line)에서 패턴 검색
[ -z "$PID" ] 변수가 비어 있는지 확인 (빈 문자열 = 프로세스 없음)
kill -9 SIGKILL 신호 전송 — 프로세스를 즉시 강제 종료

kill -9 주의사항
SIGKILL(9)은 프로세스가 신호를 처리할 기회 없이 즉시 종료된다.
데이터베이스 커넥션 반환, 파일 플러시 등 종료 처리(graceful shutdown)가 필요한 경우라면
위 스크립트는 개발/테스트 환경에서 간편하게 사용하기에 적합하다. 운영 환경에서 graceful shutdown이 필요하다면 kill -15(SIGTERM)를 먼저 보내고, 일정 시간 후 미종료 시 kill -9로 처리하는 방식을 고려할 수 있다.
(참고: Linux man page — signal(7))


쉽게 이해하는 비유

start.sh는 가게 문을 열고 자리를 비워도 가게가 계속 운영되도록 자동화된 직원을 세워두는 것과 같다.
stop.sh는 직원의 이름표(tystory.jar)를 보고 해당 직원만 찾아서 퇴근시키는 것과 같다.


실전 사용 방법

# 실행 권한 부여 (최초 1회)
chmod +x start.sh stop.sh

# 애플리케이션 시작
./start.sh

# 로그 확인
tail -f /home/app/tystory/app.log

# 애플리케이션 종료
./stop.sh

핵심 정리

  • nohup ... & 조합으로 SSH 접속이 끊겨도 JAR가 계속 실행된다
  • --spring.config.location으로 설정 파일을 외부에 분리하면 재배포 없이 설정 변경이 가능하다
  • > app.log 2>&1로 표준 출력과 에러 로그를 한 파일에서 관리할 수 있다
  • pgrep -f는 JAR 이름을 기준으로 정확한 PID를 찾아준다
  • kill -9는 즉시 강제 종료이므로, graceful shutdown이 필요한 서비스라면 kill -15 선행을 고려한다

추가 정보 — 더 안정적인 운영을 원한다면

방법 설명
systemd 서비스 등록 서버 재시작 시 자동 실행, 표준적인 Linux 서비스 관리 방식
journalctl 로그 연동 systemd 사용 시 로그를 시스템 저널로 통합 관리 가능
Spring Boot Actuator /actuator/shutdown 엔드포인트로 graceful shutdown 지원 (Spring Boot 공식 문서)

간단한 단일 서버 배포라면 위 스크립트로 충분하다.
운영 환경에서 자동 재시작, 서비스 등록이 필요하다면 systemd 유닛 파일 방식을 추가로 검토할 수 있다.

반응형