- 00-server-setup.sh: JDK8(Temurin)·Tomcat9·systemd·nginx·act_runner 구축 (멱등)
- arko-dev-deploy.sh: WAR 검증→백업→ROOT 재전개→환경설정 주입→기동→헬스체크→실패 시 롤백
- build-and-upload.sh: 개발자 PC에서 JDK8 빌드 후 WAR 업로드 (서버 자원 보호)
- deploy-dev.yml: master push 시 자동 배포, 수동 재배포·롤백 지원
서버가 2코어/메모리 여유 1G에 40여 개 서비스가 동거하는 환경이라
Maven 빌드는 서버에서 돌리지 않고 개발자 PC에서 수행한다.
JSP가 리소스를 컨텍스트 경로 없이 하드코딩해 ROOT 전개만 가능하며,
globals-{dev,live}.properties는 .gitignore 대상이라 서버 config/에 두고 배포 시 주입한다.
198 lines
8.8 KiB
Bash
198 lines
8.8 KiB
Bash
#!/usr/bin/env bash
|
|
# arko_renual 개발서버 최초 1회 구축 스크립트 (zio-server / 101.79.17.164)
|
|
#
|
|
# 실행: sudo bash 00-server-setup.sh
|
|
# 멱등: 이미 설치된 항목은 건너뛴다. 여러 번 실행해도 안전.
|
|
#
|
|
# 이 서버는 이미 40개 이상의 서비스가 돌고 있고 디스크가 99% 찬 상태다.
|
|
# 그래서 아래 순서로만 진행하고, 각 단계에서 실패하면 즉시 멈춘다.
|
|
#
|
|
# 1) 사전 점검(디스크/메모리) — 여유가 없으면 중단
|
|
# 2) JDK 8 설치 (Temurin 8 — arko는 source/target 1.7이라 17/21로는 컴파일 불가)
|
|
# 3) Tomcat 9 설치 (HTTP 8088, AJP 비활성, 셧다운 8105)
|
|
# 4) 디렉토리/환경설정 뼈대
|
|
# 5) systemd 서비스 등록
|
|
# 6) nginx 가상호스트 등록
|
|
# 7) Gitea Actions runner(act_runner) 설치 — 등록 토큰은 수동 입력
|
|
#
|
|
# 주의: DB(csv 스키마)는 이미 서버 MariaDB(127.0.0.1:3306)에 존재하므로 이 스크립트는 건드리지 않는다.
|
|
set -euo pipefail
|
|
|
|
APP_HOME=/opt/arko-dev
|
|
JDK_DIR=$APP_HOME/jdk8
|
|
TOMCAT_DIR=$APP_HOME/tomcat
|
|
TOMCAT_VER=9.0.120
|
|
HTTP_PORT=8088
|
|
SHUTDOWN_PORT=8105
|
|
DOMAIN=csv.zioinfo.co.kr
|
|
SRC_DIR=$(cd "$(dirname "$0")" && pwd)
|
|
|
|
log() { echo -e "\n[$(date +'%F %T')] === $* ==="; }
|
|
|
|
# ------------------------------------------------------------ 1. 사전 점검
|
|
log "1. 사전 점검"
|
|
FREE_MB=$(df -m / | awk 'NR==2 {print $4}')
|
|
AVAIL_MB=$(free -m | awk '/^Mem:/ {print $7}')
|
|
echo "디스크 여유: ${FREE_MB}MB / 메모리 여유: ${AVAIL_MB}MB"
|
|
if [ "$FREE_MB" -lt 2000 ]; then
|
|
echo "중단: 디스크 여유 ${FREE_MB}MB. JDK8(180MB)+Tomcat(20MB)+WAR(200MB)+전개본(200MB)+백업(400MB) ≈ 1GB에 여유분까지 최소 2GB 필요."
|
|
echo " 정리 후보: journalctl --vacuum-time=7d / /var/log 오래된 로그 / /root/.m2 미사용 아티팩트"
|
|
exit 1
|
|
fi
|
|
if [ "$AVAIL_MB" -lt 1200 ]; then
|
|
echo "경고: 메모리 여유 ${AVAIL_MB}MB. Tomcat 힙 768m + Maven 빌드 1g가 동시에 뜨면 OOM 위험."
|
|
echo " 빌드와 기동이 겹치지 않게 하거나 스왑을 확보할 것."
|
|
fi
|
|
|
|
# ------------------------------------------------------------ 2. JDK 8
|
|
log "2. JDK 8 설치"
|
|
if [ -x "$JDK_DIR/bin/javac" ]; then
|
|
echo "이미 설치됨: $("$JDK_DIR/bin/java" -version 2>&1 | head -1)"
|
|
else
|
|
mkdir -p "$JDK_DIR"
|
|
# Ubuntu 24.04 공식 저장소에는 openjdk-8이 없다(noble에서 제거). Temurin 8 tarball을 직접 받는다.
|
|
TEMURIN_URL="https://api.adoptium.net/v3/binary/latest/8/ga/linux/x64/jdk/hotspot/normal/eclipse"
|
|
echo "다운로드: $TEMURIN_URL"
|
|
curl -fsSL "$TEMURIN_URL" -o /tmp/temurin8.tar.gz
|
|
tar -xzf /tmp/temurin8.tar.gz -C "$JDK_DIR" --strip-components=1
|
|
rm -f /tmp/temurin8.tar.gz
|
|
"$JDK_DIR/bin/java" -version
|
|
fi
|
|
|
|
# ------------------------------------------------------------ 3. Tomcat 9
|
|
log "3. Tomcat 9 설치"
|
|
if [ -x "$TOMCAT_DIR/bin/catalina.sh" ]; then
|
|
echo "이미 설치됨: $TOMCAT_DIR"
|
|
else
|
|
mkdir -p "$TOMCAT_DIR"
|
|
TC_URL="https://archive.apache.org/dist/tomcat/tomcat-9/v${TOMCAT_VER}/bin/apache-tomcat-${TOMCAT_VER}.tar.gz"
|
|
echo "다운로드: $TC_URL"
|
|
curl -fsSL "$TC_URL" -o /tmp/tomcat9.tar.gz
|
|
tar -xzf /tmp/tomcat9.tar.gz -C "$TOMCAT_DIR" --strip-components=1
|
|
rm -f /tmp/tomcat9.tar.gz
|
|
chmod +x "$TOMCAT_DIR"/bin/*.sh
|
|
# 기본 안내 웹앱 제거 — 개발서버라도 외부 노출되므로 남기지 않는다
|
|
rm -rf "$TOMCAT_DIR"/webapps/{ROOT,docs,examples,host-manager,manager}
|
|
fi
|
|
|
|
log "3-1. server.xml 포트 조정 (HTTP $HTTP_PORT / 셧다운 $SHUTDOWN_PORT / AJP 비활성)"
|
|
SERVER_XML=$TOMCAT_DIR/conf/server.xml
|
|
if ! grep -q "port=\"$HTTP_PORT\"" "$SERVER_XML"; then
|
|
cp -n "$SERVER_XML" "$SERVER_XML.orig"
|
|
sed -i "s/port=\"8005\" shutdown=\"SHUTDOWN\"/port=\"$SHUTDOWN_PORT\" shutdown=\"SHUTDOWN\"/" "$SERVER_XML"
|
|
sed -i "s/port=\"8080\" protocol=\"HTTP\/1.1\"/port=\"$HTTP_PORT\" protocol=\"HTTP\/1.1\" address=\"127.0.0.1\" URIEncoding=\"UTF-8\" maxThreads=\"100\" compression=\"on\"/" "$SERVER_XML"
|
|
# AJP 커넥터는 Tomcat 9 기본 배포본이 이미 주석 처리해 두므로 건드리지 않는다.
|
|
# (한 번 더 <!-- 를 붙이면 주석 중첩으로 "--" 가 생겨 XML 파싱이 깨지고 Tomcat이 기동하지 못한다)
|
|
python3 -c "import xml.dom.minidom; xml.dom.minidom.parse('$SERVER_XML'); print('server.xml XML 검증 OK')"
|
|
echo "조정 완료 (원본: $SERVER_XML.orig)"
|
|
else
|
|
echo "이미 조정됨"
|
|
fi
|
|
|
|
# nginx가 X-Forwarded-* 를 넘기므로 Tomcat이 원 클라이언트 IP/프로토콜을 인식하게 한다
|
|
if ! grep -q "RemoteIpValve" "$SERVER_XML"; then
|
|
sed -i 's|<Host name="localhost" appBase="webapps"|<Valve className="org.apache.catalina.valves.RemoteIpValve" remoteIpHeader="X-Forwarded-For" protocolHeader="X-Forwarded-Proto" />\n <Host name="localhost" appBase="webapps"|' "$SERVER_XML" || true
|
|
fi
|
|
|
|
# ------------------------------------------------- 4. 디렉토리 / 환경설정
|
|
log "4. 디렉토리 및 환경설정"
|
|
mkdir -p "$APP_HOME"/{bin,config,backup,logs,upload,incoming,runner}
|
|
install -m 750 "$SRC_DIR/arko-dev-deploy.sh" "$APP_HOME/bin/arko-dev-deploy.sh"
|
|
echo "배포 스크립트 설치: $APP_HOME/bin/arko-dev-deploy.sh"
|
|
|
|
if [ -f "$APP_HOME/config/globals-dev.properties" ]; then
|
|
echo "환경설정 이미 존재: $APP_HOME/config/globals-dev.properties"
|
|
else
|
|
cat <<'WARN'
|
|
|
|
!! 수동 작업 필요 !!
|
|
globals-dev.properties / globals-live.properties 는 .gitignore 대상이라 저장소에 없다.
|
|
이 두 파일이 없으면 Spring 루트 컨텍스트 로딩 단계에서 기동이 실패한다.
|
|
|
|
로컬 arko_renual/src/main/resources/egovframework/egovProps/ 의 두 파일을
|
|
/opt/arko-dev/config/ 로 올린 뒤, 개발서버 값으로 아래 항목을 반드시 수정할 것:
|
|
|
|
Globals.Url = jdbc:mysql://127.0.0.1:3306/csv?serverTimezone=Asia/Seoul&useSSL=false&allowPublicKeyRetrieval=true
|
|
Globals.UserName = csv
|
|
Globals.Password = (서버 MariaDB의 csv 계정 비밀번호)
|
|
운영 도메인(csv.culture.go.kr)이 박힌 항목 → csv.zioinfo.co.kr 로 교체
|
|
메일/SMS 발송 계정 → 개발서버에서 실제 발송되지 않도록 비활성 또는 테스트 값으로 교체
|
|
|
|
WARN
|
|
fi
|
|
|
|
# ------------------------------------------------------- 5. systemd 서비스
|
|
log "5. systemd 서비스 등록"
|
|
install -m 644 "$SRC_DIR/arko-dev.service" /etc/systemd/system/arko-dev.service
|
|
systemctl daemon-reload
|
|
systemctl enable arko-dev.service
|
|
echo "등록 완료 (기동은 최초 배포 후: systemctl start arko-dev)"
|
|
|
|
# ---------------------------------------------------------- 6. nginx
|
|
log "6. nginx 가상호스트 등록"
|
|
install -m 644 "$SRC_DIR/$DOMAIN.conf" "/etc/nginx/sites-available/$DOMAIN.conf"
|
|
ln -sfn "/etc/nginx/sites-available/$DOMAIN.conf" "/etc/nginx/sites-enabled/$DOMAIN.conf"
|
|
if nginx -t; then
|
|
systemctl reload nginx
|
|
echo "nginx 반영 완료"
|
|
else
|
|
rm -f "/etc/nginx/sites-enabled/$DOMAIN.conf"
|
|
echo "nginx 설정 오류 → 링크 제거하고 중단"
|
|
exit 1
|
|
fi
|
|
|
|
cat <<EOF
|
|
|
|
SSL 발급은 DNS A 레코드($DOMAIN → 101.79.17.164)가 등록된 뒤에 실행할 것:
|
|
certbot --nginx -d $DOMAIN
|
|
|
|
EOF
|
|
|
|
# ------------------------------------------ 7. Gitea Actions runner
|
|
log "7. Gitea Actions runner (act_runner)"
|
|
if [ -x /usr/local/bin/act_runner ]; then
|
|
echo "이미 설치됨: $(/usr/local/bin/act_runner --version 2>&1 | head -1)"
|
|
else
|
|
ACT_VER=0.2.11
|
|
curl -fsSL "https://gitea.com/gitea/act_runner/releases/download/v${ACT_VER}/act_runner-${ACT_VER}-linux-amd64" \
|
|
-o /usr/local/bin/act_runner
|
|
chmod +x /usr/local/bin/act_runner
|
|
/usr/local/bin/act_runner --version
|
|
fi
|
|
|
|
mkdir -p "$APP_HOME/runner"
|
|
if [ ! -f "$APP_HOME/runner/.runner" ]; then
|
|
cat <<EOF
|
|
|
|
!! 수동 작업 필요 — runner 등록 !!
|
|
Gitea 웹에서 등록 토큰을 발급받은 뒤(저장소 > Settings > Actions > Runners > Create new runner),
|
|
아래를 실행할 것:
|
|
|
|
cd $APP_HOME/runner
|
|
act_runner register --no-interactive \\
|
|
--instance https://git.zioinfo.co.kr \\
|
|
--token <등록토큰> \\
|
|
--name arko-dev-runner \\
|
|
--labels arko-dev:host
|
|
|
|
라벨의 :host 가 핵심 — 이 서버는 디스크 여유가 없어 도커 이미지를 받을 수 없으므로
|
|
반드시 host 모드(서버에 설치된 JDK8/Maven 직접 사용)로 등록한다.
|
|
|
|
등록 후 서비스 파일(arko-dev-runner.service)을 설치하고 기동:
|
|
install -m 644 $SRC_DIR/arko-dev-runner.service /etc/systemd/system/
|
|
systemctl daemon-reload && systemctl enable --now arko-dev-runner
|
|
|
|
EOF
|
|
else
|
|
echo "runner 이미 등록됨"
|
|
fi
|
|
|
|
log "완료"
|
|
cat <<EOF
|
|
남은 수동 작업:
|
|
1. /opt/arko-dev/config/ 에 globals-dev/live.properties 배치 (DB·도메인 수정)
|
|
2. Gitea runner 등록 (위 안내)
|
|
3. csv.zioinfo.co.kr A 레코드 등록 → certbot으로 SSL 발급
|
|
4. Gitea 저장소에 .gitea/workflows/deploy-dev.yml push → 자동 배포 시작
|
|
EOF
|