Haru Utils

애플리케이션 · 설치·설정 레시피

Spring Boot를 systemd 서비스로 운영하기

실행 가능한 JAR을 전용 리눅스 계정으로 격리하고, 외부 설정·안전한 systemd 유닛·로그·재시작·부팅 자동 시작·롤백까지 운영 가능한 형태로 구성합니다.
Spring Boot 배포systemd 서비스Java JARUbuntu JavaSpring Boot 운영
지원 환경Ubuntu Server 24.04 LTS + OpenJDK 21
예상 시간45
난이도중급
검토일2026-08-28

BEFORE YOU START

시작 전에 준비하세요

01

CI에서 빌드·테스트하고 체크섬을 확인한 실행 가능 JAR

02

애플리케이션이 요구하는 정확한 Java 주 버전과 메모리 계획

03

사용할 포트·프로필·외부 설정·비밀값 보관 위치

04

헬스 체크 경로와 이전 정상 JAR로 되돌리는 롤백 절차

권장 대상 Spring Boot JAR을 VM 또는 물리 서버에서 직접 운영하는 개발자·운영자

FOLLOW THE RECIPE

8단계 구성·점검 레시피

1
확인시스템을 변경하지 않는 점검 단계

JAR·Java·서버 환경 확인

애플리케이션의 빌드 Java와 운영 JRE 호환성을 먼저 확인합니다. 예시는 Ubuntu 24.04의 OpenJDK 21을 사용하지만 프로젝트 요구 버전이 우선입니다.

운영체제 확인
cat /etc/os-release
현재 Java 확인
java -version
CPU·메모리 확인
lscpu
가용 메모리 확인
free -h
JAR 형식 확인
file /path/to/myapp.jar
  • 애플리케이션이 지원하는 Java 주 버전을 빌드 설정에서 확인했다.
  • JAR은 CI 산출물이고 체크섬·버전을 식별할 수 있다.
  • JVM과 OS가 사용할 충분한 메모리 여유가 있다.
결과 읽기

UnsupportedClassVersionError는 보통 빌드 Java가 운영 Java보다 새 버전일 때 발생합니다. 무작정 JRE를 바꾸기보다 지원 매트릭스를 확인합니다.

다음 판단

기존 계정·서비스·포트·파일을 점검합니다.

2
확인시스템을 변경하지 않는 점검 단계

기존 서비스·포트·배포 경로 점검

동일 이름의 유닛과 실행 계정, 기본 포트, 기존 JAR을 확인해 운영 중 서비스를 덮어쓰지 않습니다.

실행 계정 확인
getent passwd myapp
기존 유닛 확인
systemctl status myapp.service --no-pager
기본 포트 확인
sudo ss -ltnp | grep ':8080 '
기존 배포 파일 확인
sudo ls -la /opt/myapp
디스크 여유 확인
df -h /opt /var/log
  • myapp 이름과 8080 포트가 기존 서비스와 충돌하지 않는다.
  • 기존 JAR·설정·유닛이 있으면 소유 팀과 롤백 버전을 확인했다.
  • 배포 및 로그 경로에 충분한 여유 공간이 있다.
결과 읽기

기존 서비스가 active라면 신규 설치가 아니라 무중단 또는 점검 배포입니다. 트래픽 제거와 롤백 계획을 먼저 세웁니다.

다음 판단

호환 JRE와 전용 실행 계정을 준비합니다.

3
변경패키지·설정·서비스 상태가 달라지는 단계

JRE와 전용 실행 계정 준비

GUI가 필요 없는 서버용 JRE를 설치하고 로그인할 수 없는 전용 시스템 계정을 만듭니다. 계정이 이미 있으면 useradd를 다시 실행하지 않습니다.

변경 단계입니다. 대상 서버, 백업 파일, 서비스 중단 영향과 바로 이전 상태로 돌아가는 방법을 다시 확인하세요.
패키지 인덱스 갱신
sudo apt update
OpenJDK 21 JRE 설치
sudo apt-get install -y openjdk-21-jre-headless
설치 Java 확인
/usr/bin/java -version
전용 시스템 계정 생성
sudo useradd --system --home-dir /opt/myapp --shell /usr/sbin/nologin myapp
getent passwd myapp 결과가 없을 때만 실행합니다.
읽기 전용 배포 경로 생성
sudo install -d -o root -g myapp -m 0750 /opt/myapp
쓰기 전용 상태·로그 경로 생성
sudo install -d -o myapp -g myapp -m 0750 /var/lib/myapp /var/lib/myapp/tmp /var/log/myapp
설정 경로 생성
sudo install -d -o root -g myapp -m 0750 /etc/myapp
  • 애플리케이션 요구 Java 버전과 /usr/bin/java가 일치한다.
  • myapp 계정은 nologin 셸을 사용하고 sudo 권한이 없다.
  • /opt/myapp은 root:myapp 소유 0750으로 서비스 계정이 수정할 수 없다.
  • myapp은 /var/lib/myapp·/var/log/myapp과 systemd가 만드는 /run/myapp만 쓸 수 있다.
결과 읽기

한 서버에 여러 Java 버전이 있으면 systemd ExecStart에 명시한 절대 경로가 실제 지원 JRE인지 확인합니다.

다음 판단

JAR·외부 설정·systemd 유닛을 배치합니다.

4
주의권한·연결·중단 영향을 확인할 단계

JAR·외부 설정·systemd 유닛 구성

작업마다 고유한 <BACKUP_SUFFIX>를 정해 기존 산출물·유닛·환경 파일을 먼저 보존합니다. 비밀값은 유닛 파일이나 ExecStart 인자에 넣지 않고 권한이 제한된 외부 파일 또는 운영 비밀 저장소에서 제공합니다.

고유 백업 접미사 생성
date -u +%Y%m%dT%H%M%SZ
출력값을 이번 배포의 <BACKUP_SUFFIX>로 사용하고 배포 기록에 남깁니다. JAR·유닛·환경 파일 백업에는 모두 같은 값을 사용합니다.
기존 JAR 백업
sudo cp --preserve=all --no-clobber /opt/myapp/myapp.jar /opt/myapp/myapp.jar.<BACKUP_SUFFIX>.bak
기존 파일이 있을 때만 실행합니다. 대상이 이미 있으면 덮어쓰지 말고 새 고유 접미사를 만듭니다.
기존 유닛 백업
sudo cp --preserve=all --no-clobber /etc/systemd/system/myapp.service /etc/systemd/system/myapp.service.<BACKUP_SUFFIX>.bak
기존 파일이 있을 때만 실행하고 JAR과 같은 <BACKUP_SUFFIX>를 사용합니다.
검증한 JAR 설치
sudo install -o root -g myapp -m 0640 /path/to/myapp.jar /opt/myapp/myapp.jar
기존 JAR을 백업했고 새 산출물의 체크섬을 확인한 뒤 실행합니다.
기존 환경 파일 백업
sudo cp --preserve=all --no-clobber /etc/myapp/myapp.env /etc/myapp/myapp.env.<BACKUP_SUFFIX>.bak
환경 파일이 이미 있을 때만 실행하고 JAR·유닛과 같은 <BACKUP_SUFFIX>를 사용합니다.
환경 파일 생성 또는 보존
sudo touch /etc/myapp/myapp.env
환경 파일 소유권 설정
sudo chown root:myapp /etc/myapp/myapp.env
환경 파일 권한 제한
sudo chmod 640 /etc/myapp/myapp.env
환경 파일 편집
sudoedit /etc/myapp/myapp.env
아래 예시를 환경에 맞게 입력하고 실제 비밀값은 가능한 한 별도 비밀 저장소에서 주입합니다.
systemd 유닛 파일 생성 또는 보존
sudo touch /etc/systemd/system/myapp.service
touch는 기존 유닛 내용을 지우지 않습니다.
systemd 유닛 소유권 지정
sudo chown root:root /etc/systemd/system/myapp.service
systemd 유닛 권한 제한
sudo chmod 644 /etc/systemd/system/myapp.service
systemd 유닛 편집
sudoedit /etc/systemd/system/myapp.service
아래 예시를 반영하고 ExecStart의 Java·JAR 절대 경로를 실제 환경과 대조합니다.
설정 예시 · /etc/myapp/myapp.env
비밀값을 제외한 운영 환경 예시
SPRING_PROFILES_ACTIVE=prod
SERVER_ADDRESS=127.0.0.1
SERVER_PORT=8080
JAVA_TOOL_OPTIONS=-XX:MaxRAMPercentage=70.0 -Djava.io.tmpdir=/var/lib/myapp/tmp
DB 비밀번호 같은 비밀값은 가능하면 별도 비밀 저장소에서 주입합니다. 파일에 둘 수밖에 없다면 0640 권한과 접근 감사를 유지합니다.
설정 예시 · /etc/systemd/system/myapp.service
전용 계정과 쓰기 경로를 제한한 서비스 유닛
[Unit]
Description=My Spring Boot application
Wants=network-online.target
After=network-online.target

[Service]
Type=exec
User=myapp
Group=myapp
WorkingDirectory=/opt/myapp
EnvironmentFile=-/etc/myapp/myapp.env
ExecStart=/usr/bin/java -jar /opt/myapp/myapp.jar
SuccessExitStatus=143
Restart=on-failure
RestartSec=5s
UMask=0027
RuntimeDirectory=myapp
RuntimeDirectoryMode=0750
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/lib/myapp /var/log/myapp /run/myapp

[Install]
WantedBy=multi-user.target
애플리케이션이 다른 경로에 써야 한다면 오류 로그를 확인하고 그 경로만 ReadWritePaths에 추가합니다. 보호 옵션은 스테이징에서 기능 검증 후 운영 적용합니다.
  • /opt/myapp과 JAR은 root:myapp 소유이며 각각 0750·0640으로 서비스 계정이 수정할 수 없다.
  • 유닛 파일의 ExecStart는 java와 JAR의 절대 경로를 사용한다.
  • 유닛 파일에 비밀번호·토큰이 없다.
  • 쓰기 가능 경로를 /var/lib/myapp·/var/log/myapp·/run/myapp으로 제한했다.
  • 환경 파일 접근 권한이 root와 myapp 그룹으로 제한된다.
결과 읽기

ProtectSystem=strict 적용 후 쓰기 오류가 나면 보호 기능을 통째로 끄지 말고 필요한 단일 경로를 ReadWritePaths에 추가합니다.

다음 판단

유닛 문법을 검증하고 서비스를 시작합니다.

5
변경패키지·설정·서비스 상태가 달라지는 단계

유닛 검증 후 시작과 자동 시작

systemd가 유닛을 읽기 전에 문법을 검사합니다. 시작 실패 시 자동 재시작에 맡기지 말고 첫 로그를 확인합니다.

변경 단계입니다. 대상 서버, 백업 파일, 서비스 중단 영향과 바로 이전 상태로 돌아가는 방법을 다시 확인하세요.
임시 디렉터리 생성
sudo install -d -o myapp -g myapp -m 0750 /var/lib/myapp/tmp
유닛 문법 검사
sudo systemd-analyze verify /etc/systemd/system/myapp.service
유닛 다시 읽기
sudo systemctl daemon-reload
서비스 활성화 및 시작
sudo systemctl enable --now myapp.service
서비스 상태 확인
systemctl status myapp.service --no-pager
최근 로그 확인
sudo journalctl -u myapp.service -n 120 --no-pager
  • systemd-analyze verify가 오류를 출력하지 않는다.
  • myapp.service가 active (running) 상태다.
  • 로그에 프로필·포트·DB 연결·권한 오류가 없다.
  • 부팅 자동 시작이 enabled 상태다.
결과 읽기

Start request repeated too quickly는 원인이 아니라 반복 실패 결과입니다. journalctl에서 가장 처음 발생한 Java 예외나 권한 오류를 찾습니다.

다음 판단

프로세스·포트·HTTP·재부팅 동작을 검증합니다.

6
확인시스템을 변경하지 않는 점검 단계

프로세스·포트·헬스·재부팅 검증

systemd 상태만 보지 않고 실제 포트와 HTTP 응답을 확인합니다. 애플리케이션이 Actuator를 사용한다면 인증·노출 정책에 맞는 헬스 경로를 사용합니다.

활성 상태 확인
systemctl is-active myapp.service
부팅 자동 시작 확인
systemctl is-enabled myapp.service
실행 계정과 PID 확인
systemctl show myapp.service -p MainPID -p User -p Group
리스닝 주소 확인
sudo ss -ltnp | grep ':8080 '
로컬 HTTP 응답 확인
curl --fail --silent --show-error --output /dev/null http://127.0.0.1:8080/actuator/health
Actuator 헬스가 활성화된 경우 사용합니다. 아니면 서비스가 제공하는 비민감 헬스 경로로 교체합니다.
현재 부팅의 로그 확인
sudo journalctl -u myapp.service -b --no-pager
  • 프로세스가 root가 아닌 myapp 계정으로 실행된다.
  • 8080은 127.0.0.1에만 바인딩되어 있다.
  • 헬스 체크가 정상 상태를 반환하고 핵심 의존성도 확인한다.
  • 유지보수 재부팅 후 서비스·헬스·로그를 다시 검증했다.
결과 읽기

active 상태여도 HTTP가 실패하면 포트·컨텍스트 경로·프로필·의존성 준비 상태를 확인합니다. 헬스 엔드포인트에 상세 비밀 정보를 공개하지 않습니다.

다음 판단

서비스 격리·비밀값·외부 노출을 최종 확인합니다.

7
주의권한·연결·중단 영향을 확인할 단계

실행 권한·비밀값·외부 노출 점검

서비스 계정과 쓰기 경로를 제한하고, 애플리케이션 포트는 NGINX 같은 역방향 프록시 뒤의 루프백으로 유지합니다.

유닛 보안 분석
systemd-analyze security myapp.service
배포 경로와 JAR 소유권 확인
stat -c '%U %G %a %n' /opt/myapp /opt/myapp/myapp.jar
각각 root myapp 750, root myapp 640이 기대 결과입니다.
서비스 계정의 JAR 쓰기 차단 확인
sudo -u myapp test ! -w /opt/myapp/myapp.jar
서비스 계정의 배포 경로 쓰기 차단 확인
sudo -u myapp test ! -w /opt/myapp
허용된 쓰기 경로 소유권 확인
stat -c '%U %G %a %n' /var/lib/myapp /var/log/myapp /run/myapp
환경 파일 권한 확인
stat -c '%U %G %a %n' /etc/myapp/myapp.env
외부 리스닝 확인
sudo ss -ltnp | grep ':8080 '
프로세스 환경 노출 범위 점검
systemctl show myapp.service -p EnvironmentFiles
  • myapp 계정은 로그인·sudo 권한이 없고 애플리케이션 전용이다.
  • /opt/myapp과 JAR은 root:myapp 소유이고 서비스 계정이 수정할 수 없다.
  • 서비스 계정의 쓰기는 /var/lib/myapp·/var/log/myapp·/run/myapp으로 제한된다.
  • 비밀번호·토큰을 유닛·ExecStart·Git·로그에 넣지 않는다.
  • 8080은 루프백에 바인딩하고 외부 요청은 TLS 프록시를 통해 받는다.
  • Actuator는 필요한 엔드포인트만 인증된 내부망에 노출한다.
  • JRE와 Spring Boot 보안 업데이트를 정기 적용하고 재부팅·재배포 검증한다.
결과 읽기

systemd-analyze security 점수는 절대적인 취약점 판정이 아니라 격리 옵션 확인 도구입니다. 기능을 깨지 않는 범위에서 항목별로 보강합니다.

다음 판단

이전 JAR·유닛으로 되돌리는 절차를 확인합니다.

8
주의권한·연결·중단 영향을 확인할 단계

이전 JAR·유닛으로 안전하게 롤백

백업 목록과 배포 기록에서 이번 변경의 <BACKUP_SUFFIX>를 명시적으로 선택합니다. 기존 배포는 이전 JAR·유닛과 기존 환경 파일을 복원하고, 이번에 새로 만든 환경 파일은 먼저 고유한 .disabled 파일로 이동한 뒤에만 이전 서비스를 시작합니다. 최초 설치는 서비스와 유닛을 비활성화하고 신규 환경 파일도 .disabled로 이동하며 JAR·상태·로그는 삭제하지 않습니다.

서비스 중지
sudo systemctl stop myapp.service
JAR 백업 후보 목록 확인
sudo find /opt/myapp -maxdepth 1 -type f -name 'myapp.jar.*.bak' -printf '%TY-%Tm-%Td %TH:%TM:%TS %p\n' | sort
배포 기록·파일 시각·체크섬을 대조해 복원할 한 개의 <BACKUP_SUFFIX>를 고릅니다. 최신 파일을 자동 선택하지 않습니다.
유닛 백업 후보 목록 확인
sudo find /etc/systemd/system -maxdepth 1 -type f -name 'myapp.service.*.bak' -printf '%TY-%Tm-%Td %TH:%TM:%TS %p\n' | sort
JAR과 같은 <BACKUP_SUFFIX>의 유닛 백업을 선택합니다.
환경 파일 백업 후보 목록 확인
sudo find /etc/myapp -maxdepth 1 -type f -name 'myapp.env.*.bak' -printf '%TY-%Tm-%Td %TH:%TM:%TS %p\n' | sort
이번 배포 전 환경 파일이 있었는지 배포 기록과 함께 확인합니다.
기존 JAR 백업 존재 확인
sudo test -f /opt/myapp/myapp.jar.<BACKUP_SUFFIX>.bak
명시적으로 고른 <BACKUP_SUFFIX>를 사용합니다. 기존 배포 롤백 분기에서 성공해야 하며 신규 설치라면 복원 명령을 건너뜁니다.
기존 유닛 백업 존재 확인
sudo test -f /etc/systemd/system/myapp.service.<BACKUP_SUFFIX>.bak
기존 배포 분기에서는 JAR과 같은 접미사의 두 백업이 모두 성공해야 합니다. 신규 설치라면 복원 명령을 건너뜁니다.
기존 환경 파일 백업 분기 확인
sudo test -f /etc/myapp/myapp.env.<BACKUP_SUFFIX>.bak
성공하면 기존 환경 파일 복원 분기를 실행합니다. 실패했다는 이유만으로 신규 분기를 실행하지 말고 배포 기록에서 이번 배포 전 환경 파일이 없었음을 확인합니다.
기존 환경 파일 복원
sudo cp --preserve=all /etc/myapp/myapp.env.<BACKUP_SUFFIX>.bak /etc/myapp/myapp.env
기존 환경 파일 백업 확인이 성공한 경우에만 실행하며 이전 JAR·유닛을 시작하기 전에 완료합니다.
복원 환경 파일 소유권 재확립
sudo chown root:myapp /etc/myapp/myapp.env
기존 환경 파일 복원 분기에서만 실행합니다.
복원 환경 파일 권한 재확립
sudo chmod 640 /etc/myapp/myapp.env
기존 환경 파일 복원 분기에서만 실행합니다.
신규 환경 파일 분기 확인
sudo test ! -f /etc/myapp/myapp.env.<BACKUP_SUFFIX>.bak
성공하고 배포 기록상 myapp.env가 이번 배포에서 새로 생성됐을 때만 다음 명령을 실행합니다.
신규 환경 파일을 복구 가능하게 비활성화
sudo mv --no-clobber /etc/myapp/myapp.env /etc/myapp/myapp.env.disabled.<BACKUP_SUFFIX>
신규 환경 파일 분기에서 이전 JAR·유닛을 시작하기 전에 실행합니다. 대상이 이미 있으면 새 고유 접미사를 사용하며 파일을 삭제하거나 덮어쓰지 않습니다.
신규 환경 파일 활성 경로 제거 확인
sudo test ! -e /etc/myapp/myapp.env
신규 환경 파일 분기에서 성공해야 합니다. 실패하면 이전 JAR·유닛을 시작하지 않습니다.
복원 환경 파일 상태 확인
sudo stat -c '%U %G %a %n' /etc/myapp/myapp.env
기존 환경 파일 복원 분기에서 root myapp 640이 출력되는지 확인합니다.
이전 JAR 복원
sudo cp --preserve=all /opt/myapp/myapp.jar.<BACKUP_SUFFIX>.bak /opt/myapp/myapp.jar
기존 JAR 백업 확인이 성공한 경우에만 실행합니다.
이전 유닛 복원
sudo cp --preserve=all /etc/systemd/system/myapp.service.<BACKUP_SUFFIX>.bak /etc/systemd/system/myapp.service
기존 유닛 백업 확인이 성공한 경우에만 실행합니다.
복원 JAR 소유권 재확립
sudo chown root:myapp /opt/myapp/myapp.jar
기존 배포 롤백 분기에서만 실행합니다.
복원 JAR 권한 재확립
sudo chmod 640 /opt/myapp/myapp.jar
기존 배포 롤백 분기에서만 실행합니다.
복원 유닛 소유권 재확립
sudo chown root:root /etc/systemd/system/myapp.service
기존 배포 롤백 분기에서만 실행합니다.
복원 유닛 권한 재확립
sudo chmod 644 /etc/systemd/system/myapp.service
기존 배포 롤백 분기에서만 실행합니다.
신규 설치 서비스 자동 시작 해제
sudo systemctl disable myapp.service
백업이 없는 최초 설치 롤백 분기에서 실행합니다.
신규 설치 유닛을 복구 가능하게 비활성화
sudo mv --no-clobber /etc/systemd/system/myapp.service /etc/systemd/system/myapp.service.disabled.<BACKUP_SUFFIX>
JAR·유닛 백업이 모두 없는 최초 설치 롤백 분기에서만 실행합니다. 대상이 이미 있으면 새 고유 접미사를 사용하며 JAR·상태·로그 파일은 삭제하지 않습니다.
유닛 다시 읽기
sudo systemctl daemon-reload
복원 유닛 문법 확인
sudo systemd-analyze verify /etc/systemd/system/myapp.service
기존 배포 롤백 분기에서만 실행합니다. 환경 파일은 이미 복원됐거나 신규 파일이 .disabled로 이동한 상태여야 합니다.
이전 버전 시작
sudo systemctl start myapp.service
JAR·유닛 백업을 복원하고, 환경 파일도 기존 백업으로 복원했거나 신규 파일을 .disabled로 이동했음을 확인한 기존 배포 분기에서만 실행합니다.
롤백 로그 확인
sudo journalctl -u myapp.service -n 120 --no-pager
  • 이전 JAR의 체크섬·버전·DB 호환성을 확인했다.
  • 백업 후보 목록과 배포 기록을 대조해 한 개의 <BACKUP_SUFFIX>를 명시적으로 선택했다.
  • 기존 배포는 같은 접미사의 JAR·유닛 백업을 모두 확인한 뒤 복원했다.
  • 복원된 JAR은 root:myapp 0640, 유닛은 root:root 0644이다.
  • 기존 환경 파일은 같은 접미사의 백업으로 복원해 root:myapp 0640을 적용했다.
  • 이번 배포에서 새로 만든 환경 파일은 이전 서비스 시작 전에 고유한 .disabled 파일로 이동했다.
  • 최초 설치 롤백은 서비스 자동 시작을 해제하고 유닛과 신규 환경 파일을 각각 .disabled로 이동했으며 JAR·데이터·로그는 보존했다.
  • 이전 JAR·유닛이 이번 배포의 새 환경 파일을 읽지 않는 것을 확인한 뒤에만 서비스를 시작했다.
  • 롤백 후 헬스 체크와 핵심 업무 기능을 다시 검증했다.
  • 실패 산출물과 로그를 원인 분석용으로 별도 보존했다.
결과 읽기

이전 JAR이 새 DB 스키마와 호환되지 않으면 단순 파일 롤백이 안전하지 않습니다. 배포 전 backward-compatible 마이그레이션과 별도 DB 복구 계획이 필요합니다.

다음 판단

계속 실패하면 systemd·포트·NGINX 장애 대응 가이드로 이어갑니다.

SECURITY CHECK

운영 전 마지막 보안 점검

  • 서비스는 로그인할 수 없는 전용 myapp 계정으로 실행한다.
  • JAR·유닛·환경 파일의 소유권과 쓰기 권한을 최소화한다.
  • 비밀번호·토큰을 유닛과 명령 인자에 넣지 않는다.
  • 애플리케이션 포트는 루프백에 두고 외부에는 TLS 프록시만 노출한다.
  • Actuator와 관리 엔드포인트를 최소 범위로 제한한다.
  • JRE·Spring Boot 보안 업데이트와 롤백 가능한 배포 이력을 유지한다.

COMMON ERRORS

자주 막히는 지점

서비스가 즉시 종료됨

증상
myapp.service가 failed 또는 activating과 failed를 반복합니다.
가능한 원인
Java 버전 불일치, 잘못된 프로필·환경값, DB 연결 실패 또는 파일 권한 오류가 흔합니다.
확인 순서
journalctl에서 첫 Java 예외를 확인하고 /usr/bin/java, JAR, 환경 파일, 쓰기 경로를 순서대로 검증합니다.
트러블슈팅으로 이어보기

포트가 이미 사용 중

증상
Web server failed to start 또는 Address already in use 오류가 발생합니다.
가능한 원인
기존 프로세스나 다른 서비스가 같은 포트를 리스닝합니다.
확인 순서
ss로 PID와 소유 서비스를 확인하고 임의 종료하지 말고 포트 소유 관계를 정리합니다.
트러블슈팅으로 이어보기

NGINX에서 502·504 발생

증상
로컬 서비스는 시작됐지만 프록시 요청이 502 또는 504로 실패합니다.
가능한 원인
upstream 주소·포트 불일치, 애플리케이션 지연 또는 방화벽·바인딩 문제가 원인일 수 있습니다.
확인 순서
로컬 헬스, 리스닝 주소, NGINX upstream, 타임아웃과 애플리케이션 로그 순서로 확인합니다.
트러블슈팅으로 이어보기

PRIMARY REFERENCES

공식 문서

설치 저장소와 지원 버전은 바뀔 수 있습니다. 검토일 이후에는 링크된 공식 문서와 현재 서버의 패키지 후보 버전을 함께 확인하세요.

도구 빠른 검색

최근 사용한 도구를 다시 열거나, 이름과 기능으로 검색하세요.

검색어와 도구의 입력·결과는 저장하지 않습니다.

↑↓ 이동 · Enter 열기 · Esc 닫기