개발서버(csv.zioinfo.co.kr) 배포 구성 및 Gitea Actions 파이프라인 추가
- 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/에 두고 배포 시 주입한다.
This commit is contained in:
parent
1288fc6396
commit
7c574922d8
8
.gitattributes
vendored
Normal file
8
.gitattributes
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
# 배포/CI 파일은 리눅스 서버에서 그대로 실행되므로 개행을 LF로 고정한다.
|
||||
# (CRLF로 커밋되면 서버에서 "bad interpreter: /bin/bash^M" 로 죽는다)
|
||||
# 나머지 소스는 기존 방식 그대로 두기 위해 경로를 한정한다.
|
||||
deploy/dev/*.sh text eol=lf
|
||||
deploy/dev/*.service text eol=lf
|
||||
deploy/dev/*.yaml text eol=lf
|
||||
deploy/dev/*.conf text eol=lf
|
||||
.gitea/workflows/*.yml text eol=lf
|
||||
118
.gitea/workflows/deploy-dev.yml
Normal file
118
.gitea/workflows/deploy-dev.yml
Normal file
@ -0,0 +1,118 @@
|
||||
# arko_renual — 개발서버(csv.zioinfo.co.kr) 자동 배포 파이프라인
|
||||
#
|
||||
# ┌ 설계 배경 ─────────────────────────────────────────────────────────────┐
|
||||
# │ 이 서버(zio-server)는 2코어 / 메모리 여유 1G에 40개 이상의 서비스가 │
|
||||
# │ 동거한다. 실제로 구축 중 39분간 응답 불능 후 재부팅된 이력이 있다. │
|
||||
# │ 그래서 Maven 빌드(힙 1G)는 서버에서 돌리지 않는다. │
|
||||
# └────────────────────────────────────────────────────────────────────────┘
|
||||
#
|
||||
# [개발자 PC] bash deploy/dev/build-and-upload.sh → 빌드 + WAR 업로드
|
||||
# [개발자 PC] git push origin master → 이 워크플로 자동 실행
|
||||
# [서버] ROOT 재전개 + 환경설정 주입 + 재기동 + 헬스체크(+실패 시 롤백)
|
||||
#
|
||||
# 수동 실행(workflow_dispatch)으로 재배포·롤백도 가능하다.
|
||||
name: deploy-dev
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
paths-ignore: # 문서만 바뀐 커밋으로 재배포하지 않는다
|
||||
- '**.md'
|
||||
- '**.docx'
|
||||
- '**.pptx'
|
||||
- 'docs/**'
|
||||
- '_workspace_privacy/**'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
action:
|
||||
description: '수행할 작업'
|
||||
required: true
|
||||
default: 'deploy'
|
||||
type: choice
|
||||
options:
|
||||
- deploy
|
||||
- rollback
|
||||
|
||||
concurrency:
|
||||
group: arko-dev-deploy
|
||||
cancel-in-progress: false # 배포 도중 취소되면 ROOT가 반쪽 상태로 남는다
|
||||
|
||||
env:
|
||||
APP_HOME: /opt/arko-dev
|
||||
INCOMING_WAR: /opt/arko-dev/incoming/arko.war
|
||||
SITE_URL: https://csv.zioinfo.co.kr/
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: arko-dev
|
||||
timeout-minutes: 20
|
||||
|
||||
steps:
|
||||
- name: 사전 점검
|
||||
run: |
|
||||
set -e
|
||||
echo "트리거: ${{ gitea.event_name }} / 작업: ${{ inputs.action || 'deploy' }}"
|
||||
df -h "$APP_HOME" | tail -1
|
||||
free -h | head -2
|
||||
uptime
|
||||
|
||||
- name: WAR 확인
|
||||
if: ${{ inputs.action != 'rollback' }}
|
||||
run: |
|
||||
set -e
|
||||
if [ ! -f "$INCOMING_WAR" ]; then
|
||||
echo "::error::업로드된 WAR이 없다: $INCOMING_WAR"
|
||||
echo "개발자 PC에서 'bash deploy/dev/build-and-upload.sh' 를 먼저 실행할 것."
|
||||
exit 1
|
||||
fi
|
||||
ls -lh "$INCOMING_WAR"
|
||||
WAR_EPOCH=$(stat -c %Y "$INCOMING_WAR")
|
||||
echo "WAR 빌드 시각: $(date -d @$WAR_EPOCH '+%F %T')"
|
||||
|
||||
# WAR이 이번 커밋보다 오래되었으면 옛 산출물을 배포하는 것이다.
|
||||
# 문서/CI 파일만 바뀐 커밋도 있으므로 실패시키지 않고 경고만 남긴다.
|
||||
COMMIT_EPOCH=$(git log -1 --format=%ct 2>/dev/null || echo 0)
|
||||
if [ "$COMMIT_EPOCH" -gt "$WAR_EPOCH" ]; then
|
||||
AGE_MIN=$(( (COMMIT_EPOCH - WAR_EPOCH) / 60 ))
|
||||
echo "::warning::업로드된 WAR이 이번 커밋보다 ${AGE_MIN}분 오래됐다. 소스 변경이 포함된 커밋이라면 build-and-upload.sh 로 다시 올릴 것."
|
||||
fi
|
||||
|
||||
- name: 배포
|
||||
if: ${{ inputs.action != 'rollback' }}
|
||||
run: |
|
||||
set -e
|
||||
bash "$APP_HOME/bin/arko-dev-deploy.sh" "$INCOMING_WAR"
|
||||
|
||||
- name: 롤백
|
||||
if: ${{ inputs.action == 'rollback' }}
|
||||
run: |
|
||||
set -e
|
||||
LATEST=$(ls -1t "$APP_HOME"/backup/ROOT_*.tar.gz 2>/dev/null | head -1 || true)
|
||||
if [ -z "$LATEST" ]; then
|
||||
echo "::error::롤백할 백업이 없다"
|
||||
exit 1
|
||||
fi
|
||||
echo "롤백 대상: $LATEST"
|
||||
systemctl stop arko-dev
|
||||
rm -rf "$APP_HOME/tomcat/webapps/ROOT"
|
||||
tar -xzf "$LATEST" -C "$APP_HOME/tomcat/webapps"
|
||||
systemctl start arko-dev
|
||||
|
||||
- name: 결과 확인
|
||||
run: |
|
||||
set -e
|
||||
CODE=000
|
||||
for i in $(seq 1 60); do
|
||||
CODE=$(curl -s -o /dev/null -w "%{http_code}" --max-time 10 http://127.0.0.1:8088/ || echo 000)
|
||||
if [ "$CODE" = "200" ] || [ "$CODE" = "302" ]; then break; fi
|
||||
sleep 3
|
||||
done
|
||||
echo "Tomcat 직접 → HTTP $CODE"
|
||||
|
||||
EXT=$(curl -s -o /dev/null -w "%{http_code}" --max-time 20 "$SITE_URL" || echo 000)
|
||||
echo "$SITE_URL → HTTP $EXT"
|
||||
|
||||
case "$CODE" in
|
||||
200|302) echo "배포 정상" ;;
|
||||
*) echo "::error::Tomcat 응답 없음 (HTTP $CODE)"; exit 1 ;;
|
||||
esac
|
||||
197
deploy/dev/00-server-setup.sh
Normal file
197
deploy/dev/00-server-setup.sh
Normal file
@ -0,0 +1,197 @@
|
||||
#!/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
|
||||
120
deploy/dev/README.md
Normal file
120
deploy/dev/README.md
Normal file
@ -0,0 +1,120 @@
|
||||
# arko_renual 개발서버 배포 · CI/CD (csv.zioinfo.co.kr)
|
||||
|
||||
## 대상 환경
|
||||
|
||||
| 항목 | 값 |
|
||||
|------|-----|
|
||||
| 서버 | `zio-server` / 101.79.17.164 (Ubuntu 24.04.1, 2코어, 메모리 7.8G, 디스크 99G) |
|
||||
| 도메인 | `csv.zioinfo.co.kr` → nginx(443) → Tomcat(127.0.0.1:8088) |
|
||||
| 저장소 | `https://git.zioinfo.co.kr/somang4819/arko_renual.git` (Gitea 1.22.3) |
|
||||
| CI/CD | Gitea Actions + act_runner (**host 모드**, 같은 서버에서 빌드·배포) |
|
||||
| JDK | **8 (Temurin)** — `source/target 1.7`이라 서버 기본 JDK 17/21로는 컴파일 불가 |
|
||||
| DB | 서버 MariaDB 10.11 `127.0.0.1:3306` 스키마 `csv` (**이미 존재**, 188테이블/실데이터) |
|
||||
| 배포 형태 | **ROOT 전개 필수** — JSP가 `/new/css/...` 처럼 컨텍스트 경로 없이 하드코딩 |
|
||||
|
||||
## 파일 구성
|
||||
|
||||
| 파일 | 설치 위치 | 역할 |
|
||||
|------|-----------|------|
|
||||
| `00-server-setup.sh` | (1회 실행) | JDK8·Tomcat9·디렉토리·systemd·nginx·act_runner 구축 |
|
||||
| `arko-dev-deploy.sh` | `/opt/arko-dev/bin/` | WAR 검증 → 백업 → 재전개 → 설정주입 → 기동 → 헬스체크(실패 시 롤백) |
|
||||
| `arko-dev.service` | `/etc/systemd/system/` | Tomcat 9 서비스 (힙 768m) |
|
||||
| `arko-dev-runner.service` | `/etc/systemd/system/` | Gitea Actions runner (host 모드) |
|
||||
| `runner-config.yaml` | `/opt/arko-dev/runner/config.yaml` | 러너 설정 (동시 1개, 캐시 off) |
|
||||
| `csv.zioinfo.co.kr.conf` | `/etc/nginx/sites-available/` | 리버스 프록시 |
|
||||
| `../../.gitea/workflows/deploy-dev.yml` | 저장소 | master push → 빌드·배포 |
|
||||
|
||||
## 서버 디렉토리 배치
|
||||
|
||||
```
|
||||
/opt/arko-dev/
|
||||
├── jdk8/ Temurin 8 (빌드·런타임 공용)
|
||||
├── tomcat/ Tomcat 9 — webapps/ROOT 에 전개
|
||||
├── config/ globals-dev.properties, globals-live.properties ← git에 없음, 서버에만 보관
|
||||
├── bin/ arko-dev-deploy.sh
|
||||
├── backup/ ROOT_<타임스탬프>.tar.gz (최근 3개 유지)
|
||||
├── upload/ 업로드 파일 (재배포로 사라지지 않도록 ROOT/file 에 심볼릭 링크)
|
||||
├── runner/ act_runner 작업 디렉토리
|
||||
└── logs/ deploy.log
|
||||
```
|
||||
|
||||
## 구축 절차
|
||||
|
||||
```bash
|
||||
# 1. 산출물 업로드
|
||||
scp -r deploy/dev root@101.79.17.164:/tmp/arko-deploy
|
||||
|
||||
# 2. 서버 구축 (멱등 — 다시 실행해도 안전)
|
||||
ssh root@101.79.17.164 'bash /tmp/arko-deploy/00-server-setup.sh'
|
||||
|
||||
# 3. 환경설정 배치 (.gitignore 대상이라 저장소에 없음 — 없으면 기동 실패)
|
||||
scp src/main/resources/egovframework/egovProps/globals-{dev,live}.properties \
|
||||
root@101.79.17.164:/opt/arko-dev/config/
|
||||
# → 서버에서 DB(127.0.0.1:3306/csv)·도메인(csv.zioinfo.co.kr)·메일/SMS 값 수정
|
||||
|
||||
# 4. Gitea runner 등록 (토큰은 Gitea 웹에서 발급)
|
||||
ssh root@101.79.17.164 'cd /opt/arko-dev/runner && \
|
||||
act_runner register --no-interactive --instance https://git.zioinfo.co.kr \
|
||||
--token <등록토큰> --name arko-dev-runner --labels arko-dev:host && \
|
||||
install -m 644 /tmp/arko-deploy/runner-config.yaml /opt/arko-dev/runner/config.yaml && \
|
||||
install -m 644 /tmp/arko-deploy/arko-dev-runner.service /etc/systemd/system/ && \
|
||||
systemctl daemon-reload && systemctl enable --now arko-dev-runner'
|
||||
|
||||
# 5. DNS A 레코드 등록 (사용자 작업): csv.zioinfo.co.kr → 101.79.17.164
|
||||
# 등록 후 SSL 발급
|
||||
ssh root@101.79.17.164 'certbot --nginx -d csv.zioinfo.co.kr'
|
||||
|
||||
# 6. 워크플로 push → 이후 master push마다 자동 배포
|
||||
git add .gitea/workflows/deploy-dev.yml deploy/
|
||||
git commit -m "개발서버 배포 및 Gitea Actions 파이프라인 추가"
|
||||
git push origin master
|
||||
```
|
||||
|
||||
## 평상시 배포 흐름
|
||||
|
||||
```bash
|
||||
# 1) 개발자 PC에서 빌드 + WAR 업로드
|
||||
bash deploy/dev/build-and-upload.sh
|
||||
|
||||
# 2) push → Gitea Actions(deploy-dev)가 자동 배포
|
||||
git push origin master
|
||||
# 진행 상황: https://git.zioinfo.co.kr/somang4819/arko_renual/actions
|
||||
```
|
||||
|
||||
빌드는 개발자 PC에서만 한다. 서버(2코어/메모리 여유 1G)에서 Maven을 돌리면
|
||||
다른 40여 개 서비스까지 흔들리기 때문이다.
|
||||
|
||||
**push 없이 즉시 반영:**
|
||||
```bash
|
||||
bash deploy/dev/build-and-upload.sh --deploy
|
||||
```
|
||||
|
||||
**재배포·롤백:** Gitea 웹 > Actions > deploy-dev > Run workflow > `deploy` 또는 `rollback`
|
||||
|
||||
## 운영 명령
|
||||
|
||||
```bash
|
||||
systemctl status arko-dev # 상태
|
||||
journalctl -u arko-dev -f # 서비스 로그
|
||||
tail -f /opt/arko-dev/tomcat/logs/catalina.out
|
||||
tail -f /opt/arko-dev/logs/deploy.log
|
||||
|
||||
# 수동 롤백
|
||||
systemctl stop arko-dev
|
||||
rm -rf /opt/arko-dev/tomcat/webapps/ROOT
|
||||
tar -xzf /opt/arko-dev/backup/ROOT_<타임스탬프>.tar.gz -C /opt/arko-dev/tomcat/webapps
|
||||
systemctl start arko-dev
|
||||
```
|
||||
|
||||
## 알려진 제약 · 주의
|
||||
|
||||
1. **서버 자원이 빠듯하다.** 조사 시점 기준 디스크 99%(여유 1.8G), 메모리 여유 1.3G, 부하 평균 11~17, 40개 이상 서비스 동거.
|
||||
구축 전 디스크 정리가 사실상 필수다(`journalctl --vacuum-time=7d`, `/var/log` 정리 등).
|
||||
`00-server-setup.sh`는 여유 2.5GB 미만이면 스스로 중단한다.
|
||||
2. **WAR가 192MB다.** 전개본·백업까지 하면 배포 1회에 약 600MB를 쓴다. 백업은 3개까지만 유지한다.
|
||||
3. **globals-dev/live.properties는 저장소에 없다**(`.gitignore`). 서버 `config/`에 두고 배포 때 주입한다.
|
||||
`context-datasource.xml`이 `globals-dev.properties`만 읽으므로 이 파일이 없으면 기동 자체가 실패한다.
|
||||
4. **ROOT 배포만 가능하다.** `/arko` 같은 서브 컨텍스트로 올리면 CSS/JS/이미지가 전부 404난다.
|
||||
5. **DB는 기존 `csv` 스키마를 그대로 쓴다.** 실데이터(회원 75,301건 등)가 들어 있으므로
|
||||
개인정보보호 신규 테이블(SFR-001~004) 적용 여부와 마스킹 필요성은 별도 확인이 필요하다.
|
||||
6. **JDK 17/21로는 빌드되지 않는다.** `maven-compiler-plugin`이 `source/target 1.7`이고 JDK 9+는 1.7을 지원하지 않는다.
|
||||
126
deploy/dev/arko-dev-deploy.sh
Normal file
126
deploy/dev/arko-dev-deploy.sh
Normal file
@ -0,0 +1,126 @@
|
||||
#!/usr/bin/env bash
|
||||
# arko_renual 개발서버 배포 스크립트 (csv.zioinfo.co.kr)
|
||||
#
|
||||
# 서버에 설치 위치: /opt/arko-dev/bin/arko-dev-deploy.sh
|
||||
# 호출 주체 : Gitea Actions (.gitea/workflows/deploy-dev.yml) 또는 수동 실행
|
||||
#
|
||||
# 전제:
|
||||
# - JDK 8 : /opt/arko-dev/jdk8 (Temurin 8, 빌드/런타임 공용)
|
||||
# - Tomcat: /opt/arko-dev/tomcat (Tomcat 9, HTTP 8088)
|
||||
# - 환경설정: /opt/arko-dev/config/globals-dev.properties, globals-live.properties
|
||||
# (git에 없는 gitignore 대상 파일 — 서버에만 보관하고 배포 때 주입)
|
||||
#
|
||||
# 동작:
|
||||
# 1) WAR 검증 2) 현재 ROOT 백업(최근 3개 유지) 3) Tomcat 중지
|
||||
# 4) ROOT 재전개 5) 서버 보관 globals 주입 6) Tomcat 기동 7) 헬스체크
|
||||
#
|
||||
# 실패 시 자동 롤백(직전 백업 복구 + 재기동).
|
||||
set -euo pipefail
|
||||
|
||||
APP_HOME=/opt/arko-dev
|
||||
TOMCAT_HOME=$APP_HOME/tomcat
|
||||
CONFIG_DIR=$APP_HOME/config
|
||||
BACKUP_DIR=$APP_HOME/backup
|
||||
LOG_DIR=$APP_HOME/logs
|
||||
SERVICE=arko-dev
|
||||
HEALTH_URL=http://127.0.0.1:8088/
|
||||
HEALTH_TIMEOUT=180 # 초. arko는 첫 기동 시 JSP 컴파일로 60~90초 소요
|
||||
KEEP_BACKUPS=3
|
||||
|
||||
WAR_SRC=${1:-}
|
||||
TS=$(date +%Y%m%d_%H%M%S)
|
||||
|
||||
log() { echo "[$(date +'%F %T')] $*" | tee -a "$LOG_DIR/deploy.log"; }
|
||||
die() { log "ERROR: $*"; exit 1; }
|
||||
|
||||
mkdir -p "$BACKUP_DIR" "$LOG_DIR"
|
||||
|
||||
# ---------------------------------------------------------------- 1. WAR 검증
|
||||
[ -n "$WAR_SRC" ] || die "사용법: $0 <arko.war 경로>"
|
||||
[ -f "$WAR_SRC" ] || die "WAR 파일 없음: $WAR_SRC"
|
||||
unzip -l "$WAR_SRC" > /dev/null 2>&1 || die "WAR 파일이 손상됨: $WAR_SRC"
|
||||
unzip -l "$WAR_SRC" | grep -q "WEB-INF/web.xml" || die "WEB-INF/web.xml 없음 — 정상 WAR 아님"
|
||||
WAR_SIZE=$(du -h "$WAR_SRC" | cut -f1)
|
||||
log "배포 시작: $WAR_SRC ($WAR_SIZE)"
|
||||
|
||||
# 디스크 여유 확인 — 전개본 + 백업까지 고려해 WAR 3배 필요
|
||||
NEED_KB=$(( $(du -k "$WAR_SRC" | cut -f1) * 3 ))
|
||||
FREE_KB=$(df -k "$APP_HOME" | awk 'NR==2 {print $4}')
|
||||
[ "$FREE_KB" -gt "$NEED_KB" ] || die "디스크 부족: 여유 $((FREE_KB/1024))MB, 필요 $((NEED_KB/1024))MB"
|
||||
|
||||
# ------------------------------------------------------------- 2. 현재본 백업
|
||||
if [ -d "$TOMCAT_HOME/webapps/ROOT" ]; then
|
||||
log "현재 ROOT 백업 → $BACKUP_DIR/ROOT_$TS.tar.gz"
|
||||
tar -czf "$BACKUP_DIR/ROOT_$TS.tar.gz" -C "$TOMCAT_HOME/webapps" ROOT
|
||||
# 오래된 백업 정리 (디스크 여유가 빠듯한 서버라 필수)
|
||||
ls -1t "$BACKUP_DIR"/ROOT_*.tar.gz 2>/dev/null | tail -n +$((KEEP_BACKUPS+1)) | xargs -r rm -f
|
||||
fi
|
||||
|
||||
# --------------------------------------------------------------- 3. Tomcat 중지
|
||||
log "Tomcat 중지"
|
||||
systemctl stop "$SERVICE" || true
|
||||
for i in $(seq 1 30); do
|
||||
pgrep -f "$TOMCAT_HOME" > /dev/null || break
|
||||
sleep 1
|
||||
done
|
||||
pgrep -f "$TOMCAT_HOME" > /dev/null && { log "정상 종료 실패 → 강제 종료"; pkill -9 -f "$TOMCAT_HOME" || true; sleep 2; }
|
||||
|
||||
# --------------------------------------------------------------- 4. ROOT 재전개
|
||||
# arko는 JSP가 리소스를 /new/css/... 처럼 컨텍스트 경로 없이 하드코딩하므로 반드시 ROOT 배포
|
||||
log "ROOT 재전개"
|
||||
rm -rf "$TOMCAT_HOME/webapps/ROOT" "$TOMCAT_HOME/webapps/ROOT.war"
|
||||
rm -rf "$TOMCAT_HOME/work/Catalina/localhost/_" # 이전 JSP 컴파일 캐시 제거
|
||||
mkdir -p "$TOMCAT_HOME/webapps/ROOT"
|
||||
unzip -q "$WAR_SRC" -d "$TOMCAT_HOME/webapps/ROOT"
|
||||
|
||||
# ------------------------------------------------- 5. 서버 보관 환경설정 주입
|
||||
# globals-{dev,live}.properties는 .gitignore 대상이라 저장소/WAR에 없음.
|
||||
# context-datasource.xml은 globals-dev.properties만 읽으므로 이 주입이 없으면 기동 실패.
|
||||
PROPS_DEST="$TOMCAT_HOME/webapps/ROOT/WEB-INF/classes/egovframework/egovProps"
|
||||
mkdir -p "$PROPS_DEST"
|
||||
for f in globals-dev.properties globals-live.properties; do
|
||||
[ -f "$CONFIG_DIR/$f" ] || die "서버 환경설정 없음: $CONFIG_DIR/$f"
|
||||
cp -f "$CONFIG_DIR/$f" "$PROPS_DEST/$f"
|
||||
log "환경설정 주입: $f"
|
||||
done
|
||||
chmod 640 "$PROPS_DEST"/globals-*.properties
|
||||
|
||||
# 업로드 파일 보관소는 재배포로 날아가면 안 되므로 심볼릭 링크로 외부 고정
|
||||
if [ -d "$APP_HOME/upload" ]; then
|
||||
rm -rf "$TOMCAT_HOME/webapps/ROOT/file"
|
||||
ln -s "$APP_HOME/upload" "$TOMCAT_HOME/webapps/ROOT/file"
|
||||
log "업로드 디렉토리 링크: $APP_HOME/upload"
|
||||
fi
|
||||
|
||||
chown -R arko:arko "$TOMCAT_HOME/webapps/ROOT" 2>/dev/null || true
|
||||
|
||||
# ------------------------------------------------------------------ 6. 기동
|
||||
log "Tomcat 기동"
|
||||
systemctl start "$SERVICE"
|
||||
|
||||
# --------------------------------------------------------------- 7. 헬스체크
|
||||
log "헬스체크 (최대 ${HEALTH_TIMEOUT}초 — 첫 요청은 JSP 컴파일로 느림)"
|
||||
OK=0
|
||||
for i in $(seq 1 "$HEALTH_TIMEOUT"); do
|
||||
CODE=$(curl -s -o /dev/null -w "%{http_code}" --max-time 10 "$HEALTH_URL" || echo 000)
|
||||
if [ "$CODE" = "200" ] || [ "$CODE" = "302" ]; then OK=1; log "헬스체크 통과 (HTTP $CODE, ${i}초)"; break; fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
if [ "$OK" != "1" ]; then
|
||||
log "헬스체크 실패 — 롤백 시작"
|
||||
tail -50 "$TOMCAT_HOME/logs/catalina.out" 2>/dev/null | tee -a "$LOG_DIR/deploy.log" || true
|
||||
LATEST_BACKUP=$(ls -1t "$BACKUP_DIR"/ROOT_*.tar.gz 2>/dev/null | head -1 || true)
|
||||
if [ -n "$LATEST_BACKUP" ]; then
|
||||
systemctl stop "$SERVICE" || true
|
||||
rm -rf "$TOMCAT_HOME/webapps/ROOT"
|
||||
tar -xzf "$LATEST_BACKUP" -C "$TOMCAT_HOME/webapps"
|
||||
systemctl start "$SERVICE"
|
||||
log "롤백 완료: $LATEST_BACKUP"
|
||||
else
|
||||
log "롤백할 백업 없음 (최초 배포)"
|
||||
fi
|
||||
die "배포 실패"
|
||||
fi
|
||||
|
||||
log "배포 완료: $WAR_SRC → ROOT ($WAR_SIZE)"
|
||||
29
deploy/dev/arko-dev-runner.service
Normal file
29
deploy/dev/arko-dev-runner.service
Normal file
@ -0,0 +1,29 @@
|
||||
# Gitea Actions runner (host 모드) — arko_renual 개발 배포 전용
|
||||
# 설치 위치: /etc/systemd/system/arko-dev-runner.service
|
||||
#
|
||||
# host 모드이므로 도커 없이 서버에 설치된 JDK8/Maven을 직접 쓴다.
|
||||
# (이 서버는 디스크 여유가 없어 러너용 도커 이미지를 받을 수 없다)
|
||||
[Unit]
|
||||
Description=Gitea Actions runner for arko_renual DEV (host mode)
|
||||
After=network.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
WorkingDirectory=/opt/arko-dev/runner
|
||||
ExecStart=/usr/local/bin/act_runner daemon --config /opt/arko-dev/runner/config.yaml
|
||||
|
||||
# 빌드 스텝에서 JDK8을 우선 쓰도록 PATH를 고정
|
||||
Environment="JAVA_HOME=/opt/arko-dev/jdk8"
|
||||
Environment="PATH=/opt/arko-dev/jdk8/bin:/usr/local/bin:/usr/bin:/bin"
|
||||
|
||||
# 배포 스크립트가 systemctl을 호출하므로 root로 구동한다
|
||||
# (이 서버의 다른 서비스들도 모두 root 구동 방식이다)
|
||||
User=root
|
||||
Group=root
|
||||
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
39
deploy/dev/arko-dev.service
Normal file
39
deploy/dev/arko-dev.service
Normal file
@ -0,0 +1,39 @@
|
||||
# arko_renual 개발서버 Tomcat 서비스
|
||||
# 설치 위치: /etc/systemd/system/arko-dev.service
|
||||
#
|
||||
# 이 서버(zio-server)의 기존 서비스들과 같은 방식(systemd 직접 관리)을 따른다.
|
||||
# 메모리 여유가 1.3G 수준이라 힙을 768m로 제한한다 — 부족하면 서버 전체가 스왑/OOM으로 흔들린다.
|
||||
[Unit]
|
||||
Description=arko_renual DEV (Tomcat 9, csv.zioinfo.co.kr, :8088)
|
||||
After=network.target mariadb.service
|
||||
Wants=mariadb.service
|
||||
|
||||
[Service]
|
||||
Type=forking
|
||||
|
||||
Environment="JAVA_HOME=/opt/arko-dev/jdk8"
|
||||
Environment="CATALINA_HOME=/opt/arko-dev/tomcat"
|
||||
Environment="CATALINA_BASE=/opt/arko-dev/tomcat"
|
||||
Environment="CATALINA_PID=/opt/arko-dev/tomcat/temp/tomcat.pid"
|
||||
# -Xmx768m: 서버 가용 메모리 기준 상한. 늘리려면 free -h 먼저 확인할 것
|
||||
# headless: 이미지 처리(썸네일) 시 X11 없는 환경에서 죽지 않도록
|
||||
# Asia/Seoul: 로그·배치 시각을 서버 다른 서비스와 맞춘다
|
||||
Environment="CATALINA_OPTS=-Xms256m -Xmx768m -XX:MaxMetaspaceSize=256m -Djava.awt.headless=true -Duser.timezone=Asia/Seoul -Dfile.encoding=UTF-8"
|
||||
|
||||
ExecStart=/opt/arko-dev/tomcat/bin/startup.sh
|
||||
ExecStop=/opt/arko-dev/tomcat/bin/shutdown.sh 30 -force
|
||||
|
||||
# arko는 첫 기동 시 JSP 컴파일로 60~90초가 걸린다
|
||||
TimeoutStartSec=300
|
||||
TimeoutStopSec=90
|
||||
|
||||
Restart=on-failure
|
||||
RestartSec=15
|
||||
|
||||
# 배포 스크립트가 webapps/ROOT를 갈아끼우므로 파일 접근 제약은 걸지 않는다
|
||||
User=root
|
||||
Group=root
|
||||
UMask=0027
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
116
deploy/dev/build-and-upload.sh
Normal file
116
deploy/dev/build-and-upload.sh
Normal file
@ -0,0 +1,116 @@
|
||||
#!/usr/bin/env bash
|
||||
# arko_renual — 로컬 빌드 → 개발서버 WAR 업로드 (개발자 PC에서 실행)
|
||||
#
|
||||
# 표준 흐름:
|
||||
# 1) bash deploy/dev/build-and-upload.sh 빌드 + WAR 업로드
|
||||
# 2) git push origin master → Gitea Actions가 자동 배포
|
||||
#
|
||||
# 옵션:
|
||||
# --build-only 빌드만 (업로드 안 함)
|
||||
# --no-build 업로드만 (기존 target/arko.war 사용)
|
||||
# --deploy 업로드 후 서버 배포까지 직접 실행 (push 없이 즉시 반영할 때)
|
||||
#
|
||||
# 서버(2코어/메모리 여유 1G)에서 Maven을 돌리지 않기 위한 구조다.
|
||||
# 빌드는 개발자 PC에서, 서버는 전개만 한다.
|
||||
set -euo pipefail
|
||||
|
||||
# ------------------------------------------------------------------ 설정
|
||||
SERVER_IP=101.79.17.164
|
||||
SERVER_USER=root
|
||||
SERVER_PW='1q2w3e!Q'
|
||||
HOSTKEY="SHA256:Zm5aAv5DJ/EnKiObKSadOxA5nKuXgToCGhNiyhVhAjY"
|
||||
REMOTE_INCOMING=/opt/arko-dev/incoming
|
||||
REMOTE_DEPLOY=/opt/arko-dev/bin/arko-dev-deploy.sh
|
||||
SITE_URL=https://csv.zioinfo.co.kr/
|
||||
|
||||
# arko는 maven-compiler-plugin이 source/target 1.7 → JDK 8로만 빌드된다 (17/21 불가)
|
||||
JDK8_HOME=${JDK8_HOME:-"C:/Program Files/Java/jdk1.8.0_202"}
|
||||
|
||||
PROJECT_ROOT=$(cd "$(dirname "$0")/../.." && pwd)
|
||||
WAR="$PROJECT_ROOT/target/arko.war"
|
||||
|
||||
DO_BUILD=1
|
||||
DO_UPLOAD=1
|
||||
DO_DEPLOY=0 # 기본은 업로드까지만 — 배포는 git push가 Gitea Actions로 트리거한다
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--build-only) DO_UPLOAD=0 ;;
|
||||
--no-build) DO_BUILD=0 ;;
|
||||
--deploy) DO_DEPLOY=1 ;;
|
||||
*) echo "사용법: $0 [--build-only] [--no-build] [--deploy]"; exit 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
log() { echo -e "\n[$(date +'%F %T')] === $* ==="; }
|
||||
|
||||
# PuTTY plink/pscp 사용 (Windows 기본 ssh는 비밀번호 자동입력이 안 된다)
|
||||
PLINK() { plink -batch -hostkey "$HOSTKEY" -pw "$SERVER_PW" "$SERVER_USER@$SERVER_IP" "$@"; }
|
||||
PSCP() { pscp -batch -hostkey "$HOSTKEY" -pw "$SERVER_PW" "$@"; }
|
||||
|
||||
# ------------------------------------------------------------------ 1. 빌드
|
||||
if [ "$DO_BUILD" = "1" ]; then
|
||||
log "1. 로컬 빌드 (JDK 8)"
|
||||
[ -x "$JDK8_HOME/bin/javac" ] || { echo "JDK 8을 찾을 수 없다: $JDK8_HOME (JDK8_HOME 환경변수로 지정)"; exit 1; }
|
||||
export JAVA_HOME="$JDK8_HOME"
|
||||
cd "$PROJECT_ROOT"
|
||||
mvn -B -ntp clean package -DskipTests
|
||||
|
||||
[ -f "$WAR" ] || { echo "WAR 생성 실패: $WAR"; exit 1; }
|
||||
|
||||
# 바이트코드 버전 확인 — 51(0x33)=Java7. JDK 17/21로 잘못 빌드되면 서버에서 못 뜬다
|
||||
CLS=$(find target/classes -name "*.class" | head -1)
|
||||
VER=$(od -An -t d1 -j 7 -N 1 "$CLS" | tr -d ' ')
|
||||
echo "바이트코드 major=$VER (51이어야 정상)"
|
||||
[ "$VER" = "51" ] || { echo "경고: JDK 8이 아닌 컴파일러로 빌드된 것으로 보인다"; exit 1; }
|
||||
ls -lh "$WAR"
|
||||
fi
|
||||
|
||||
[ "$DO_UPLOAD" = "1" ] || { log "빌드만 수행하고 종료"; exit 0; }
|
||||
[ -f "$WAR" ] || { echo "WAR이 없다: $WAR (--no-build 이면 먼저 빌드할 것)"; exit 1; }
|
||||
|
||||
# ------------------------------------------------------------- 2. 업로드
|
||||
log "2. 서버 업로드 ($(du -h "$WAR" | cut -f1))"
|
||||
PLINK "mkdir -p $REMOTE_INCOMING"
|
||||
|
||||
# 서버 디스크 여유 확인 — WAR 3배(업로드+전개+백업)가 필요하다
|
||||
FREE_MB=$(PLINK "df -m $REMOTE_INCOMING | awk 'NR==2 {print \$4}'" | tr -d '\r')
|
||||
WAR_MB=$(( $(du -k "$WAR" | cut -f1) / 1024 ))
|
||||
echo "서버 여유 ${FREE_MB}MB / WAR ${WAR_MB}MB"
|
||||
[ "$FREE_MB" -gt $(( WAR_MB * 3 )) ] || { echo "서버 디스크 부족"; exit 1; }
|
||||
|
||||
# 전송 중 중단되어도 반쪽 WAR이 배포되지 않도록 임시 이름으로 올린 뒤 교체
|
||||
PSCP "$WAR" "$SERVER_USER@$SERVER_IP:$REMOTE_INCOMING/arko.war.uploading"
|
||||
PLINK "mv -f $REMOTE_INCOMING/arko.war.uploading $REMOTE_INCOMING/arko.war && ls -lh $REMOTE_INCOMING/arko.war"
|
||||
|
||||
# ------------------------------------------------------------- 3. 배포
|
||||
if [ "$DO_DEPLOY" != "1" ]; then
|
||||
log "업로드 완료 — 배포는 git push 가 트리거한다"
|
||||
cat <<EOF
|
||||
|
||||
다음 단계:
|
||||
git push origin master → Gitea Actions(deploy-dev)가 자동 배포
|
||||
진행 상황: https://git.zioinfo.co.kr/somang4819/arko_renual/actions
|
||||
|
||||
push 없이 즉시 반영하려면: $0 --no-build --deploy
|
||||
EOF
|
||||
exit 0
|
||||
fi
|
||||
|
||||
log "3. 서버 배포 (--deploy)"
|
||||
PLINK "bash $REMOTE_DEPLOY $REMOTE_INCOMING/arko.war"
|
||||
|
||||
# ------------------------------------------------------------- 4. 확인
|
||||
log "4. 접속 확인"
|
||||
LOCAL_CODE=$(PLINK "curl -s -o /dev/null -w '%{http_code}' --max-time 15 http://127.0.0.1:8088/" | tr -d '\r')
|
||||
echo "Tomcat 직접 → HTTP $LOCAL_CODE"
|
||||
EXT_CODE=$(curl -s -o /dev/null -w "%{http_code}" --max-time 20 "$SITE_URL" || echo 000)
|
||||
echo "$SITE_URL → HTTP $EXT_CODE"
|
||||
|
||||
case "$LOCAL_CODE" in
|
||||
200|302) echo -e "\n배포 완료" ;;
|
||||
*) echo -e "\n배포 실패 — 서버 로그 확인: plink ... 'tail -50 /opt/arko-dev/tomcat/logs/catalina.out'"; exit 1 ;;
|
||||
esac
|
||||
|
||||
if [ "$EXT_CODE" = "000" ]; then
|
||||
echo "참고: 외부 도메인 미응답 — csv.zioinfo.co.kr A 레코드 등록/SSL 발급 여부를 확인할 것"
|
||||
fi
|
||||
52
deploy/dev/csv.zioinfo.co.kr.conf
Normal file
52
deploy/dev/csv.zioinfo.co.kr.conf
Normal file
@ -0,0 +1,52 @@
|
||||
# csv.zioinfo.co.kr — arko_renual 개발서버 리버스 프록시
|
||||
# 설치 위치: /etc/nginx/sites-available/csv.zioinfo.co.kr.conf
|
||||
# → /etc/nginx/sites-enabled/ 에 심볼릭 링크
|
||||
#
|
||||
# 이 서버의 다른 사이트(itms/camp/kintex 등)와 동일한 패턴:
|
||||
# HTTP로 먼저 작성 → `certbot --nginx -d csv.zioinfo.co.kr` 이 SSL 블록을 주입
|
||||
#
|
||||
# 선행 조건: csv.zioinfo.co.kr A 레코드 → 101.79.17.164 (현재 미등록 상태)
|
||||
|
||||
server {
|
||||
server_name csv.zioinfo.co.kr;
|
||||
|
||||
# 자원봉사 활동사진·첨부파일 업로드가 있어 기본 1m로는 부족하다
|
||||
client_max_body_size 100m;
|
||||
|
||||
# 개발서버이므로 검색엔진 색인 차단
|
||||
add_header X-Robots-Tag "noindex, nofollow" always;
|
||||
|
||||
access_log /var/log/nginx/csv.zioinfo.co.kr.access.log;
|
||||
error_log /var/log/nginx/csv.zioinfo.co.kr.error.log;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:8088;
|
||||
proxy_http_version 1.1;
|
||||
|
||||
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_set_header X-Forwarded-Host $host;
|
||||
proxy_set_header X-Forwarded-Port $server_port;
|
||||
|
||||
# arko는 첫 요청에서 JSP를 컴파일하고, 통계·엑셀 다운로드가 오래 걸린다
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 300s;
|
||||
proxy_read_timeout 300s;
|
||||
|
||||
proxy_buffering on;
|
||||
proxy_buffer_size 16k;
|
||||
proxy_buffers 8 16k;
|
||||
}
|
||||
|
||||
# 정적 리소스는 Tomcat이 그대로 서빙하되 브라우저 캐시만 짧게 준다(개발서버라 길게 잡지 않음)
|
||||
location ~* ^/(images|css|js|fonts|new)/ {
|
||||
proxy_pass http://127.0.0.1:8088;
|
||||
proxy_set_header Host $host;
|
||||
expires 10m;
|
||||
add_header Cache-Control "public, max-age=600";
|
||||
}
|
||||
|
||||
listen 80;
|
||||
}
|
||||
33
deploy/dev/runner-config.yaml
Normal file
33
deploy/dev/runner-config.yaml
Normal file
@ -0,0 +1,33 @@
|
||||
# act_runner 설정 — /opt/arko-dev/runner/config.yaml
|
||||
#
|
||||
# 이 서버는 2코어 / 메모리 여유 약 1.3GB / 디스크 99% 사용 상태다.
|
||||
# 러너가 서버를 흔들지 않도록 동시 실행 1개, 캐시 비활성으로 묶어둔다.
|
||||
log:
|
||||
level: info
|
||||
|
||||
runner:
|
||||
file: .runner
|
||||
# 동시 작업 1개 — 2코어 서버에서 Maven 빌드가 겹치면 서버 전체가 응답 불능이 된다
|
||||
capacity: 1
|
||||
timeout: 40m
|
||||
# 스텝에서 쓰는 환경변수 파일 (필요 시 DB 비밀번호 등을 여기 두지 말고 서버 config/에 둘 것)
|
||||
envs_file: ""
|
||||
fetch_timeout: 5s
|
||||
fetch_interval: 10s
|
||||
labels:
|
||||
# host 모드 = 도커 없이 서버에 설치된 JDK8/Maven 직접 사용
|
||||
- "arko-dev:host"
|
||||
|
||||
cache:
|
||||
# 캐시 서버는 디스크를 계속 먹으므로 끈다
|
||||
enabled: false
|
||||
|
||||
container:
|
||||
# host 모드만 쓰므로 컨테이너 설정은 사용하지 않음
|
||||
network: ""
|
||||
privileged: false
|
||||
docker_host: "-"
|
||||
|
||||
host:
|
||||
# 작업 디렉토리 — 저장소 체크아웃(약 230MB)이 여기 놓인다
|
||||
workdir_parent: /opt/arko-dev/runner/work
|
||||
Loading…
Reference in New Issue
Block a user