Compare commits
7 Commits
1ea9e64667
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| f09ef6f193 | |||
| 194d695928 | |||
| 97fa4d8390 | |||
| be5b2ad6e6 | |||
| d97d13c219 | |||
| aeef3b63cb | |||
| e17b1f0f1f |
Vendored
+46
@@ -0,0 +1,46 @@
|
|||||||
|
pipeline {
|
||||||
|
agent { label 'mac-mini' }
|
||||||
|
|
||||||
|
environment {
|
||||||
|
NAS = "happyhome@jisangs.synology.me"
|
||||||
|
NAS_PORT = "21022"
|
||||||
|
NAS_TMP = "/volume1/docker/service/jisangs/chocomae-stage/tmp"
|
||||||
|
ARCHIVE = "chocomae-build-${BUILD_NUMBER}.tar.gz"
|
||||||
|
}
|
||||||
|
|
||||||
|
stages {
|
||||||
|
stage('Package') {
|
||||||
|
steps {
|
||||||
|
sh 'chmod +x deploy/stage-jenkins/*.sh && ./deploy/stage-jenkins/package.sh'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Upload') {
|
||||||
|
steps {
|
||||||
|
sh '''
|
||||||
|
ssh -p ${NAS_PORT} ${NAS} "mkdir -p ${NAS_TMP}"
|
||||||
|
scp -O -P ${NAS_PORT} ${ARCHIVE} deploy/stage-jenkins/remote_deploy.sh ${NAS}:${NAS_TMP}/
|
||||||
|
'''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Deploy') {
|
||||||
|
steps {
|
||||||
|
sh '''
|
||||||
|
ssh -p ${NAS_PORT} ${NAS} \
|
||||||
|
"bash ${NAS_TMP}/remote_deploy.sh ${ARCHIVE}"
|
||||||
|
'''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
post {
|
||||||
|
always {
|
||||||
|
sh 'rm -fv ${ARCHIVE} || true'
|
||||||
|
}
|
||||||
|
success {
|
||||||
|
echo "✓ chocomae-stage 배포 성공 (build #${BUILD_NUMBER})"
|
||||||
|
}
|
||||||
|
failure {
|
||||||
|
echo "✗ 배포 실패 — Deploy stage였다면 NAS에서 자동 롤백됨. Console Output 확인"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
FROM php:7.3-apache
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get install -y libonig-dev \
|
||||||
|
&& docker-php-ext-install mysqli mbstring \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
RUN a2enmod rewrite
|
||||||
|
|
||||||
|
RUN { \
|
||||||
|
echo '<Directory /var/www/html>'; \
|
||||||
|
echo ' AllowOverride All'; \
|
||||||
|
echo '</Directory>'; \
|
||||||
|
echo ''; \
|
||||||
|
echo '<FilesMatch "\.(php|html|htm|inc)$">'; \
|
||||||
|
echo ' SetHandler application/x-httpd-php'; \
|
||||||
|
echo '</FilesMatch>'; \
|
||||||
|
} > /etc/apache2/conf-available/chocomae.conf \
|
||||||
|
&& a2enconf chocomae
|
||||||
|
|
||||||
|
ENV TZ=Asia/Seoul
|
||||||
|
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
||||||
|
|
||||||
|
RUN printf '#!/bin/sh\ncp /var/www/html/mouse_typing/index.html /var/www/html/index.html\nexec "$@"\n' \
|
||||||
|
> /usr/local/bin/entrypoint.sh \
|
||||||
|
&& chmod +x /usr/local/bin/entrypoint.sh
|
||||||
|
|
||||||
|
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
|
||||||
|
CMD ["apache2-foreground"]
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
BASE_DIR=/volume1/docker/service/jisangs/chocomae-stage
|
||||||
|
CHOCOMAE_DIR=$BASE_DIR/chocomae
|
||||||
|
|
||||||
|
echo "=== [1/3] git pull ==="
|
||||||
|
git -C $CHOCOMAE_DIR pull
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "git pull 실패. 배포 중단."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "=== [2/3] service_db_setting.php 복사 ==="
|
||||||
|
cp $BASE_DIR/service_db_setting.php $CHOCOMAE_DIR/src/web/server/setup/service_db_setting.php
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "service_db_setting.php 복사 실패. 배포 중단."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "=== [3/3] docker compose up ==="
|
||||||
|
docker compose -f $BASE_DIR/docker-compose.stage.yml up -d
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "docker compose up 실패. 배포 중단."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "=== 배포 완료 ==="
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
version: '3'
|
||||||
|
|
||||||
|
services:
|
||||||
|
chocomae-stage:
|
||||||
|
build: .
|
||||||
|
image: chocomae-stage:latest
|
||||||
|
container_name: chocomae-stage
|
||||||
|
hostname: chocomae-stage
|
||||||
|
volumes:
|
||||||
|
- ./chocomae:/var/www/html/mouse_typing
|
||||||
|
environment:
|
||||||
|
- TZ=Asia/Seoul
|
||||||
|
networks:
|
||||||
|
- proxy-network
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
networks:
|
||||||
|
proxy-network:
|
||||||
|
external: true
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# 배포 환경 설정 — 모든 스크립트가 공유
|
||||||
|
|
||||||
|
NAS_USER="happyhome"
|
||||||
|
NAS_HOST="jisangs.synology.me"
|
||||||
|
NAS_SSH_PORT="21022"
|
||||||
|
|
||||||
|
NAS_BASE="/volume1/docker/service/jisangs/chocomae-stage"
|
||||||
|
NAS_TMP_DIR="${NAS_BASE}/tmp"
|
||||||
|
NAS_BACKUP_DIR="${NAS_BASE}/backup"
|
||||||
|
STAGE_HTML_DIR="${NAS_BASE}/html"
|
||||||
|
STAGE_DEPLOY_DIR="${STAGE_HTML_DIR}/mouse_typing"
|
||||||
|
STAGE_CONTAINER_NAME="chocomae-stage-http" # 실제 컨테이너명 확인
|
||||||
|
|
||||||
|
# BUILD_NUMBER는 Jenkins가 주입 — 로컬 수동 실행 시엔 manual-시각 사용
|
||||||
|
ARCHIVE_NAME="chocomae-build-${BUILD_NUMBER:-manual-$(date +%Y%m%d%H%M%S)}.tar.gz"
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
source "${SCRIPT_DIR}/config.sh"
|
||||||
|
|
||||||
|
EXCLUDES=(
|
||||||
|
".DS_Store" ".git" ".idea" ".claude" ".gitignore"
|
||||||
|
"__pycache__" "*.pyc" "node_modules" "venv"
|
||||||
|
"*.zip" "*.tar" "*.tar.gz" "*.pdf" "*.psd" "*.log"
|
||||||
|
"src/web/server/setup/service_db_setting.php"
|
||||||
|
)
|
||||||
|
|
||||||
|
TAR_EXCLUDE_ARGS=()
|
||||||
|
for pattern in "${EXCLUDES[@]}"; do
|
||||||
|
TAR_EXCLUDE_ARGS+=(--exclude="${pattern}")
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "=== 압축: ${ARCHIVE_NAME} ==="
|
||||||
|
tar czf "${ARCHIVE_NAME}" "${TAR_EXCLUDE_ARGS[@]}" \
|
||||||
|
index.html \
|
||||||
|
src \
|
||||||
|
resources
|
||||||
|
|
||||||
|
ls -lh "${ARCHIVE_NAME}"
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# NAS에서 실행되는 배포 본체
|
||||||
|
# 사용법: remote_deploy.sh <ARCHIVE_NAME>
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# 비대화형 SSH 세션은 PATH가 축소되어 /usr/local/bin(docker)이 빠짐
|
||||||
|
export PATH="/usr/local/bin:${PATH}"
|
||||||
|
|
||||||
|
ARCHIVE_NAME="$1"
|
||||||
|
|
||||||
|
NAS_BASE="/volume1/docker/service/jisangs/chocomae-stage"
|
||||||
|
NAS_TMP_DIR="${NAS_BASE}/tmp"
|
||||||
|
NAS_BACKUP_DIR="${NAS_BASE}/backup"
|
||||||
|
STAGE_HTML_DIR="${NAS_BASE}/html"
|
||||||
|
STAGE_DEPLOY_DIR="${STAGE_HTML_DIR}/mouse_typing"
|
||||||
|
STAGE_CONTAINER_NAME="chocomae-stage"
|
||||||
|
|
||||||
|
TIMESTAMP=$(date +%Y%m%d%H%M%S)
|
||||||
|
NEW_DIR="${STAGE_DEPLOY_DIR}_new"
|
||||||
|
OLD_DIR="${STAGE_DEPLOY_DIR}_old"
|
||||||
|
|
||||||
|
# ---------- 롤백 함수 ----------
|
||||||
|
SWAPPED=0
|
||||||
|
rollback() {
|
||||||
|
echo "!!! 배포 실패 — 롤백 시작 !!!"
|
||||||
|
if [ "${SWAPPED}" -eq 1 ] && [ -d "${OLD_DIR}" ]; then
|
||||||
|
# 교체 이후 실패 → 구버전 복원
|
||||||
|
rm -rf "${STAGE_DEPLOY_DIR}"
|
||||||
|
mv "${OLD_DIR}" "${STAGE_DEPLOY_DIR}"
|
||||||
|
echo "구버전 디렉토리 복원 완료"
|
||||||
|
fi
|
||||||
|
rm -rf "${NEW_DIR}"
|
||||||
|
docker start "${STAGE_CONTAINER_NAME}" 2>/dev/null || true
|
||||||
|
echo "!!! 롤백 완료 — 빌드는 실패로 처리됨 !!!"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
trap rollback ERR
|
||||||
|
|
||||||
|
# ---------- 1. 새 버전을 옆에서 완성 (서비스 무영향 구간) ----------
|
||||||
|
echo "=== [1/5] 새 버전 준비: ${NEW_DIR} ==="
|
||||||
|
rm -rf "${NEW_DIR}"
|
||||||
|
mkdir -p "${NEW_DIR}"
|
||||||
|
tar xzf "${NAS_TMP_DIR}/${ARCHIVE_NAME}" -C "${NEW_DIR}"
|
||||||
|
|
||||||
|
echo "=== [2/5] stage 설정 적용 ==="
|
||||||
|
cp -v "${NEW_DIR}/src/game/lib/global/global_variables_debug.js" \
|
||||||
|
"${NEW_DIR}/src/game/lib/global/global_variables.js"
|
||||||
|
cp -v "${NEW_DIR}/src/web/server/setup/NA_service_db_setting.php" \
|
||||||
|
"${NEW_DIR}/src/web/server/setup/service_db_setting.php"
|
||||||
|
|
||||||
|
DB_CONFIG="${NEW_DIR}/src/web/server/setup/service_db_setting.php"
|
||||||
|
sed -i 's/$db_host = "localhost";/$db_host = "mariadb.jisangs.com";/' "${DB_CONFIG}"
|
||||||
|
sed -i 's/$db_port = 3306;/$db_port = 30001;/' "${DB_CONFIG}"
|
||||||
|
|
||||||
|
echo "--- 치환 결과 검증 ---"
|
||||||
|
grep -n "db_host\|db_port" "${DB_CONFIG}"
|
||||||
|
grep -q 'mariadb.jisangs.com' "${DB_CONFIG}" || { echo "db_host 치환 실패"; exit 1; }
|
||||||
|
grep -q '30001' "${DB_CONFIG}" || { echo "db_port 치환 실패"; exit 1; }
|
||||||
|
|
||||||
|
# ---------- 2. 현재 버전 백업 ----------
|
||||||
|
echo "=== [3/5] 현재 버전 백업 ==="
|
||||||
|
mkdir -p "${NAS_BACKUP_DIR}"
|
||||||
|
if [ -d "${STAGE_HTML_DIR}" ]; then
|
||||||
|
tar czf "${NAS_BACKUP_DIR}/chocomae-stage-backup-${TIMESTAMP}.tar.gz" \
|
||||||
|
-C "$(dirname "${STAGE_HTML_DIR}")" "$(basename "${STAGE_HTML_DIR}")"
|
||||||
|
fi
|
||||||
|
# 7개 초과 백업은 오래된 순으로 정리
|
||||||
|
ls -t "${NAS_BACKUP_DIR}"/chocomae-stage-backup-*.tar.gz 2>/dev/null | tail -n +8 | xargs -r rm -fv
|
||||||
|
|
||||||
|
# ---------- 3. 순간 교체 (서비스 중단 최소 구간) ----------
|
||||||
|
echo "=== [4/5] 컨테이너 중지 및 교체 ==="
|
||||||
|
docker stop "${STAGE_CONTAINER_NAME}"
|
||||||
|
|
||||||
|
if [ -d "${STAGE_DEPLOY_DIR}" ]; then
|
||||||
|
mv "${STAGE_DEPLOY_DIR}" "${OLD_DIR}"
|
||||||
|
fi
|
||||||
|
mv "${NEW_DIR}" "${STAGE_DEPLOY_DIR}"
|
||||||
|
SWAPPED=1
|
||||||
|
|
||||||
|
# index.html은 html 루트에 위치
|
||||||
|
mv -v "${STAGE_DEPLOY_DIR}/index.html" "${STAGE_HTML_DIR}/index.html"
|
||||||
|
|
||||||
|
docker start "${STAGE_CONTAINER_NAME}"
|
||||||
|
|
||||||
|
echo "--- 컨테이너 상태 확인 ---"
|
||||||
|
sleep 3
|
||||||
|
docker ps --filter "name=${STAGE_CONTAINER_NAME}" --format "{{.Names}}: {{.Status}}" | grep -q "Up" \
|
||||||
|
|| { echo "컨테이너 기동 실패"; exit 1; }
|
||||||
|
docker ps --filter "name=${STAGE_CONTAINER_NAME}" --format "table {{.Names}}\t{{.Status}}"
|
||||||
|
|
||||||
|
# ---------- 4. 정리 ----------
|
||||||
|
echo "=== [5/5] 정리 ==="
|
||||||
|
trap - ERR # 여기부터는 실패해도 롤백 불필요
|
||||||
|
rm -rf "${OLD_DIR}"
|
||||||
|
rm -fv "${NAS_TMP_DIR}/${ARCHIVE_NAME}"
|
||||||
|
rm -fv "${NAS_TMP_DIR}/remote_deploy.sh"
|
||||||
|
|
||||||
|
echo "=== 배포 완료 (backup: ${TIMESTAMP}) ==="
|
||||||
Reference in New Issue
Block a user