diff --git a/.gitea/workflows/eapim-admin-ci.yml b/.gitea/workflows/eapim-admin-ci.yml
new file mode 100644
index 0000000..c0d7b08
--- /dev/null
+++ b/.gitea/workflows/eapim-admin-ci.yml
@@ -0,0 +1,140 @@
+name: eapim-admin CI
+
+on:
+ push:
+ branches:
+ - master
+ - develop
+ - stage
+ - feats/ci-test
+
+jobs:
+ build:
+ runs-on: [self-hosted, linux, eapim-admin]
+ env:
+ JAVA_HOME: /apps/opts/jdk8
+ JAVA_HOME_TOMCAT: /apps/opts/jdk17
+ CATALINA_BASE: /prod/eapim/adminportal
+ CATALINA_HOME: /prod/eapim/apache-tomcat-9.0.116
+ CATALINA_PID: /prod/eapim/adminportal/temp/catalina.pid
+ DEPLOY_HTTP_PORT: "30120"
+ defaults:
+ run:
+ working-directory: eapim-admin
+
+ steps:
+ - name: Checkout eapim-admin (trigger SHA)
+ uses: http://172.30.1.50:3000/actions/checkout@v4
+ with:
+ path: eapim-admin
+
+ - name: Checkout sibling modules (master)
+ working-directory: ${{ github.workspace }}
+ run: |
+ set -e
+ mkdir -p eapim-online
+
+ # eapim-online/* — 5 modules referenced from settings.gradle
+ for REPO in elink-online-core elink-online-core-jpa elink-online-transformer elink-online-common elink-online-emsclient; do
+ rm -rf "eapim-online/$REPO"
+ git clone --depth=1 --branch master \
+ http://oauth2:${{ secrets.CI_TOKEN }}@172.30.1.50:3000/djb-eapim/$REPO.git \
+ "eapim-online/$REPO"
+ done
+
+ # standalone siblings
+ for REPO in elink-portal-common eapim-admin-djb; do
+ rm -rf "$REPO"
+ git clone --depth=1 --branch master \
+ http://oauth2:${{ secrets.CI_TOKEN }}@172.30.1.50:3000/djb-eapim/$REPO.git \
+ "$REPO"
+ done
+
+ - name: Verify toolchain
+ run: |
+ java -version
+ gradle --version
+
+ - name: Gradle build (no tests)
+ run: gradle clean build -x test --no-daemon
+
+ - name: Upload WAR artifact
+ uses: http://172.30.1.50:3000/actions/upload-artifact@v3
+ with:
+ name: eapim-admin-war-${{ github.sha }}
+ path: eapim-admin/build/libs/eapim-admin.war
+ if-no-files-found: error
+
+ - name: Sync systemd user unit
+ working-directory: ${{ github.workspace }}
+ run: |
+ install -D -m 644 eapim-admin/deploy/systemd/eapim-admin.service \
+ "$HOME/.config/systemd/user/eapim-admin.service"
+ systemctl --user daemon-reload
+ systemctl --user enable eapim-admin 2>/dev/null || true
+
+ - name: Stop tomcat (pre-clean)
+ working-directory: ${{ github.workspace }}
+ run: |
+ # 1) systemd 관리 인스턴스 정지 (이번 워크플로가 띄운 것)
+ systemctl --user stop eapim-admin 2>/dev/null || true
+
+ # 2) systemd 외부 detached 인스턴스 정리
+ if [ -f "$CATALINA_PID" ] && kill -0 "$(cat $CATALINA_PID)" 2>/dev/null; then
+ JAVA_HOME=$JAVA_HOME_TOMCAT "$CATALINA_HOME/bin/shutdown.sh" 30 -force || true
+ for i in $(seq 1 30); do
+ [ -f "$CATALINA_PID" ] && kill -0 "$(cat $CATALINA_PID)" 2>/dev/null || break
+ sleep 1
+ done
+ fi
+ rm -f "$CATALINA_PID"
+
+ - name: Deploy war as /monitoring
+ working-directory: ${{ github.workspace }}
+ run: |
+ DEPLOY_DIR="$CATALINA_BASE/webapps"
+ rm -rf "$DEPLOY_DIR/monitoring" "$DEPLOY_DIR/monitoring.war"
+ cp eapim-admin/build/libs/eapim-admin.war "$DEPLOY_DIR/monitoring.war"
+ ls -la "$DEPLOY_DIR"
+
+ - name: Start tomcat and readiness probe (timeout 120s)
+ working-directory: ${{ github.workspace }}
+ run: |
+ LOG="$CATALINA_BASE/logs/catalina.$(date +%Y-%m-%d).log"
+ BEFORE=0
+ [ -f "$LOG" ] && BEFORE=$(stat -c %s "$LOG")
+
+ # systemd 가 Tomcat 을 새 cgroup 으로 띄움 — runner step 종료와 무관하게 살아남음
+ systemctl --user start eapim-admin
+
+ DEADLINE=$(($(date +%s) + 120))
+ STATUS=000
+ while [ $(date +%s) -lt $DEADLINE ]; do
+ STATUS=$(curl -sS -o /dev/null -w '%{http_code}' --max-time 3 \
+ "http://localhost:$DEPLOY_HTTP_PORT/monitoring/login.do" 2>/dev/null || echo "000")
+ case "$STATUS" in
+ 200|302|401)
+ echo "Readiness OK (/monitoring/login.do HTTP $STATUS)"
+ break
+ ;;
+ esac
+
+ if [ -f "$LOG" ] && tail -c +$((BEFORE+1)) "$LOG" | grep -qE "Application listener .* Exception|SEVERE.*startup.Catalina"; then
+ echo "::error::Startup error detected in log"
+ tail -c +$((BEFORE+1)) "$LOG" | tail -80
+ exit 1
+ fi
+ sleep 2
+ done
+
+ case "$STATUS" in
+ 200|302|401) ;;
+ *)
+ echo "::error::Readiness probe failed within 120s (last HTTP status: $STATUS)"
+ [ -f "$LOG" ] && tail -c +$((BEFORE+1)) "$LOG" | tail -100
+ exit 1
+ ;;
+ esac
+
+ echo "--- key boot log lines ---"
+ tail -c +$((BEFORE+1)) "$LOG" | grep -E "Server startup|Deployment of web" | head -10 || true
diff --git a/WebContent/WEB-INF/applicationContext-udpip.xml b/WebContent/WEB-INF/applicationContext-udpip.xml
index b473faf..58279fc 100644
--- a/WebContent/WEB-INF/applicationContext-udpip.xml
+++ b/WebContent/WEB-INF/applicationContext-udpip.xml
@@ -115,7 +115,7 @@
-
+
diff --git a/deploy/systemd/eapim-admin.service b/deploy/systemd/eapim-admin.service
new file mode 100644
index 0000000..b6da903
--- /dev/null
+++ b/deploy/systemd/eapim-admin.service
@@ -0,0 +1,51 @@
+# DJBank EAPIM Admin — user-scope systemd unit
+#
+# Install (one-time, on the host as `djb`):
+# sudo loginctl enable-linger djb # allow services to outlive ssh logout
+# mkdir -p ~/.config/systemd/user
+# # workflow copies this file in on each deploy; for first boot you can also do:
+# # cp /prod/.../deploy/systemd/eapim-admin.service ~/.config/systemd/user/
+# systemctl --user daemon-reload
+# systemctl --user enable eapim-admin
+# systemctl --user start eapim-admin
+#
+# Why this exists:
+# - `catalina.sh start` + `nohup &` does NOT escape the Gitea Actions runner
+# process group. When the workflow step finishes, the runner sends SIGTERM
+# to the process tree and Tomcat dies seconds after boot.
+# - Running Tomcat as a systemd user service detaches lifecycle from the
+# runner entirely. The workflow just calls `systemctl --user restart` and
+# systemd owns the process.
+
+[Unit]
+Description=DJBank EAPIM Admin (Tomcat 9)
+After=network-online.target
+Wants=network-online.target
+
+[Service]
+Type=simple
+
+Environment=JAVA_HOME=/apps/opts/jdk17
+Environment=CATALINA_BASE=/prod/eapim/adminportal
+Environment=CATALINA_HOME=/prod/eapim/apache-tomcat-9.0.116
+Environment=CATALINA_PID=/prod/eapim/adminportal/temp/catalina.pid
+
+# `catalina.sh run` keeps Tomcat in the foreground so systemd can supervise it.
+ExecStart=/prod/eapim/apache-tomcat-9.0.116/bin/catalina.sh run
+
+# Graceful shutdown via Tomcat's shutdown port, 30s window.
+ExecStop=/prod/eapim/apache-tomcat-9.0.116/bin/catalina.sh stop 30
+
+# Tomcat returns 143 on SIGTERM during normal stop — treat as success.
+SuccessExitStatus=143
+TimeoutStartSec=180
+TimeoutStopSec=60
+
+Restart=on-failure
+RestartSec=10
+
+# Memory / fd limits — adjust as needed.
+LimitNOFILE=65535
+
+[Install]
+WantedBy=default.target
diff --git a/src/main/resources/hotswap-agent.properties b/src/main/resources/hotswap-agent.properties
index cc2d7ce..fa14761 100644
--- a/src/main/resources/hotswap-agent.properties
+++ b/src/main/resources/hotswap-agent.properties
@@ -5,13 +5,20 @@
# \uC790\uB3D9 \uD56B\uC2A4\uC651 \uD65C\uC131\uD654
autoHotswap=true
-# \uB85C\uAE45 \uB808\uBCA8 (TRACE, DEBUG, INFO, WARNING, ERROR)
-LOGGER.level=INFO
+# \uB85C\uADF8 \uB808\uBCA8 (TRACE, DEBUG, INFO, WARNING, ERROR)
+LOGGER=INFO
+
+# \uB85C\uADF8 \uD30C\uC77C \uACBD\uB85C (\uC9C0\uC815 \uC2DC \uCF58\uC194 \uB300\uC2E0 \uD30C\uC77C\uB85C \uCD9C\uB825)
+LOGFILE=/Users/rinjae/eactive/djb-eapim/djb-eapim/eapim-admin/logs/hotswap-agent.log
+LOGFILE.append=true
+
+# \uC2DC\uAC01 \uD3EC\uB9F7
+LOGGER_DATETIME_FORMAT=yyyy-MM-dd HH:mm:ss.SSS
# ============================================================
# \uBA85\uC2DC\uC801 \uD50C\uB7EC\uADF8\uC778 \uBE44\uD65C\uC131\uD654 (\uC27C\uD45C \uAD6C\uBD84)
# ============================================================
-disabledPlugins=org.hotswap.agent.plugin.ibatis.IBatisPlugin,org.hotswap.agent.plugin.mybatis.MyBatisPlugin
+disabledPlugins=IBatis,MyBatis
# ============================================================
# Core Plugin \uD65C\uC131\uD654
diff --git a/src/main/resources/logback-dev.xml b/src/main/resources/logback-dev.xml
index 5e5b9c3..aace92d 100644
--- a/src/main/resources/logback-dev.xml
+++ b/src/main/resources/logback-dev.xml
@@ -4,7 +4,7 @@
-
+
diff --git a/src/main/resources/logback-local.xml b/src/main/resources/logback-local.xml
index 63b833d..00b1dd8 100644
--- a/src/main/resources/logback-local.xml
+++ b/src/main/resources/logback-local.xml
@@ -4,7 +4,7 @@
-
+
diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml
index 99ddf16..7c40395 100644
--- a/src/main/resources/logback.xml
+++ b/src/main/resources/logback.xml
@@ -4,7 +4,7 @@
-
+