🏛️ 홍익인간CMS 개발자 매뉴얼

Version 202506 | Updated 2025-06-12
🌐 언어 선택: 🇰🇷 한국어 🇲🇳 Монгол 🇺🇸 English

10. 🚀 배포 및 운영

10.1 배포 워크플로우

홍익인간CMS의 개발부터 운영까지의 워크플로우를 이해하는 것은 효율적인 프로젝트 관리를 위해 중요합니다. 일반적인 워크플로우는 다음과 같습니다.

10.1.1 개발 서버 배포

📝 소스코드 커밋

개발 완료된 코드 SVN/Git 저장소에 커밋

🔨 빌드 및 패키징

  • Maven을 사용하여 프로젝트 빌드
  • WAR 파일 생성

🚀 개발 서버 배포

  • 개발 서버에 WAR 파일 배포
  • 설정 파일 환경에 맞게 수정

🧪 개발 서버 테스트

  • 기능 테스트
  • 통합 테스트
  • 성능 테스트

10.1.2 테스트 서버 배포

🚀 테스트 서버 배포

  • 테스트 서버에 WAR 파일 배포
  • 설정 파일 환경에 맞게 수정

🔍 QA 테스트

  • 기능 테스트
  • 회귀 테스트
  • 성능 테스트
  • 보안 테스트

🔧 이슈 수정

  • 발견된 이슈 수정
  • 수정 사항 재배포 및 테스트

10.1.3 운영 서버 배포

📋 배포 계획 수립

  • 배포 일정 및 절차 수립
  • 롤백 계획 수립

🚀 운영 서버 배포

  • 운영 서버에 WAR 파일 배포
  • 설정 파일 환경에 맞게 수정
  • 데이터베이스 스키마 변경 적용

✅ 배포 검증

  • 주요 기능 동작 확인
  • 모니터링 시스템 확인

10.1.4 운영 및 유지보수

📊 모니터링

  • 시스템 상태 모니터링
  • 로그 모니터링
  • 성능 모니터링

🚨 이슈 대응

  • 운영 중 발생하는 이슈 대응
  • 긴급 패치 적용

🔧 정기 유지보수

  • 정기 패치 적용
  • 성능 최적화
  • 보안 업데이트

10.2 배포 전략

홍익인간CMS를 효과적으로 배포하기 위한 전략을 알아보겠습니다.

10.2.1 수동 배포

가장 기본적인 배포 방식으로, 수동으로 WAR 파일을 서버에 배포합니다.

배포 스크립트 예시 (제안 코드)

[제안 코드] 홍익인간CMS 배포 스크립트 예시

#!/bin/bash
# [제안 코드] 홍익인간CMS 배포 스크립트 예시

# 변수 설정
TOMCAT_HOME="/opt/tomcat"
APP_NAME="humanframe"
WAR_FILE="${APP_NAME}.war"
BACKUP_DIR="${TOMCAT_HOME}/backup"
TIMESTAMP=$(date +%Y%m%d%H%M%S)

# 로그 함수
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}

# 시작 로그
log "배포 시작"

# Tomcat 상태 확인
if pgrep -f tomcat > /dev/null; then
    log "Tomcat 중지 중..."
    ${TOMCAT_HOME}/bin/shutdown.sh
    
    # Tomcat 종료 대기
    count=0
    while pgrep -f tomcat > /dev/null; do
        sleep 1
        count=$((count+1))
        if [ $count -gt 60 ]; then
            log "Tomcat 종료 시간 초과. 강제 종료 시도..."
            pkill -9 -f tomcat
            break
        fi
    done
    log "Tomcat 중지 완료"
else
    log "Tomcat이 이미 중지되어 있습니다."
fi

# 백업 디렉토리 생성
if [ ! -d "${BACKUP_DIR}" ]; then
    log "백업 디렉토리 생성: ${BACKUP_DIR}"
    mkdir -p "${BACKUP_DIR}"
fi

# 기존 애플리케이션 백업
if [ -d "${TOMCAT_HOME}/webapps/ROOT" ]; then
    log "기존 애플리케이션 백업 중..."
    tar -czf "${BACKUP_DIR}/ROOT_${TIMESTAMP}.tar.gz" -C "${TOMCAT_HOME}/webapps" ROOT
    log "백업 완료: ${BACKUP_DIR}/ROOT_${TIMESTAMP}.tar.gz"
fi

# 기존 애플리케이션 삭제
log "기존 애플리케이션 삭제 중..."
rm -rf "${TOMCAT_HOME}/webapps/ROOT"
rm -f "${TOMCAT_HOME}/webapps/ROOT.war"

# 새 애플리케이션 배포
log "새 애플리케이션 배포 중..."
cp "${WAR_FILE}" "${TOMCAT_HOME}/webapps/ROOT.war"

# Tomcat 시작
log "Tomcat 시작 중..."
${TOMCAT_HOME}/bin/startup.sh

# 배포 완료 확인
log "배포 완료. 로그 확인 중..."
tail -f "${TOMCAT_HOME}/logs/catalina.out"

10.2.2 자동화된 배포

Jenkins, Ansible 등의 도구를 사용하여 배포 과정을 자동화할 수 있습니다.

Jenkins 파이프라인 예시
pipeline {
    agent any
    
    stages {
        stage('Checkout') {
            steps {
                checkout scm
            }
        }
        
        stage('Build') {
            steps {
                sh 'mvn clean package -DskipTests'
            }
        }
        
        stage('Test') {
            steps {
                sh 'mvn test'
            }
        }
        
        stage('Deploy to Dev') {
            when {
                branch 'develop'
            }
            steps {
                sh 'ansible-playbook deploy-dev.yml'
            }
        }
        
        stage('Deploy to Test') {
            when {
                branch 'release/*'
            }
            steps {
                sh 'ansible-playbook deploy-test.yml'
            }
        }
        
        stage('Deploy to Production') {
            when {
                branch 'master'
            }
            steps {
                input 'Deploy to production?'
                sh 'ansible-playbook deploy-prod.yml'
            }
        }
    }
    
    post {
        always {
            junit '**/target/surefire-reports/*.xml'
        }
        success {
            echo 'Deployment successful!'
        }
        failure {
            echo 'Deployment failed!'
            mail to: 'team@example.com',
                 subject: "Failed Pipeline: ${currentBuild.fullDisplayName}",
                 body: "Something is wrong with ${env.BUILD_URL}"
        }
    }
}

10.2.3 무중단 배포

서비스 중단 없이 애플리케이션을 배포하는 방법입니다.

블루-그린 배포

🔵 두 개의 환경 준비

  • 블루 환경: 현재 운영 중인 환경
  • 그린 환경: 새로운 버전을 배포할 환경

🟢 그린 환경에 배포

  • 새로운 버전을 그린 환경에 배포
  • 그린 환경에서 테스트 수행

🔄 트래픽 전환

로드 밸런서 설정을 변경하여 트래픽을 그린 환경으로 전환

🔵 블루 환경 업데이트

  • 블루 환경을 새로운 버전으로 업데이트
  • 다음 배포를 위한 대기 환경으로 유지

카나리 배포

🐤 새 버전 일부 배포

새로운 버전을 일부 서버에만 배포

📊 트래픽 일부 전환

일부 트래픽(예: 5%)을 새 버전으로 전환

🔍 모니터링 및 검증

  • 새 버전의 성능 및 안정성 모니터링
  • 문제가 없으면 트래픽 비율 점진적 증가

✅ 완전 전환

모든 트래픽을 새 버전으로 전환

10.3 배포 시 확인할 설정 사항

홍익인간CMS를 배포할 때 반드시 확인해야 할 설정 사항들이 있습니다. 이러한 설정을 올바르게 구성하지 않으면 시스템이 제대로 동작하지 않을 수 있습니다.

10.3.1 context-properties.xml 설정

적용할 서버 용도에 맞는 프로필(개발-dev, 운영-prd) 내 각 설정 항목을 실 서버에 맞게 수정해야 합니다.

필수 설정(변경) 항목

옵션 설정 항목

context-properties.xml 예시
<beans profile="dev">
    <bean id="propertiesService" class="org.egovframe.rte.fdl.property.impl.EgovPropertyServiceImpl">
        <property name="properties">
            <props>
                <prop key="GLOBAL_SITE_DOMAIN">http://dev.example.com</prop>
                <prop key="WEB_DIR">/home/dev/humanframe</prop>
                <prop key="THEME_PATH">/home/dev/humanframe/theme</prop>
            </props>
        </property>
    </bean>
</beans>

<beans profile="prd">
    <bean id="propertiesService" class="org.egovframe.rte.fdl.property.impl.EgovPropertyServiceImpl">
        <property name="properties">
            <props>
                <prop key="GLOBAL_SITE_DOMAIN">http://www.example.com</prop>
                <prop key="WEB_DIR">/home/prod/humanframe</prop>
                <prop key="THEME_PATH">/home/prod/humanframe/theme</prop>
            </props>
        </property>
    </bean>
</beans>

10.3.2 DBMS JNDI 설정

CMS 내에서 사용중인 기본 JNDI 이름은 "cmsdb"입니다. 관련 설정은 context-datasource.xml에서 확인 및 변경 가능합니다.

Tomcat 사용 시 context.xml 설정 예시
<Resource name="jdbc/cmsdb" 
          auth="Container" 
          type="javax.sql.DataSource"
          maxTotal="100" 
          maxIdle="30" 
          maxWaitMillis="10000"
          username="cmsuser" 
          password="cmspassword" 
          driverClassName="com.mysql.cj.jdbc.Driver"
          url="jdbc:mysql://localhost:3306/cmsdb?serverTimezone=UTC"/>
ℹ️

기타 WAS 서버 설정

각 서버 제품별 JNDI 설정 방법에 따라 설정을 추가해야 합니다.

10.3.3 Spring Profile 설정

WAS 서버 구동 시 Spring Profile을 적용하여 구동해야 합니다.

VM arguments 설정

-Dspring.profiles.active=prd (운영) 또는 -Dspring.profiles.active=dev (개발)

Tomcat 사용 시 설정 예시

/bin/catalina.sh 파일 내부에 설정
# CMS PROFILE
JAVA_OPTS="$JAVA_OPTS -Dspring.profiles.active=prd"

10.3.4 웹에디터 설정

에디터-webeditorplus를 사용하는 경우, ImagePath.jsp 파일의 경로 설정을 확인해야 합니다.

ImagePath.jsp 설정 예시
<%
String imagePhysicalPath = "";
String activeProfiles = System.getProperty("spring.profiles.active");
if("local".equalsIgnoreCase(activeProfiles)) {
    imagePhysicalPath = "D:\\H-CMS-2.2\\workspace\\humanframe";
} else if("dev".equalsIgnoreCase(activeProfiles)) {
    imagePhysicalPath = "/home/dev/humanframe";
} else {
    imagePhysicalPath = "/home/prod/humanframe";
}
%>
⚠️

중요사항

imagePhysicalPath 변수가 실제 서버의 절대적 경로와 일치하는지 확인하고, 필요시 수정해야 합니다.

10.4 환경별 설정 관리

홍익인간CMS는 Spring 프로필을 활용하여 환경별로 다른 설정을 적용할 수 있습니다.

10.4.1 프로필 설정

프로필 정의 (context-properties.xml)
<beans profile="local">
    <!-- 로컬 환경 설정 -->
</beans>

<beans profile="dev">
    <!-- 개발 환경 설정 -->
</beans>

<beans profile="test">
    <!-- 테스트 환경 설정 -->
</beans>

<beans profile="prd">
    <!-- 운영 환경 설정 -->
</beans>

프로필 활성화 방법

☕ JVM 옵션으로 활성화

-Dspring.profiles.active=dev

🌐 web.xml에서 활성화

<context-param>
    <param-name>spring.profiles.active</param-name>
    <param-value>dev</param-value>
</context-param>

🔧 환경 변수로 활성화

export SPRING_PROFILES_ACTIVE=dev

10.4.2 환경별 설정 파일

데이터소스 설정

context-datasource.xml
<beans profile="local">
    <jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/localdb" />
</beans>

<beans profile="dev">
    <jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/devdb" />
</beans>

<beans profile="test">
    <jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/testdb" />
</beans>

<beans profile="prd">
    <jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/proddb" />
</beans>

프로퍼티 설정

환경별 프로퍼티 설정 예시
<beans profile="local">
    <bean id="propertiesService" class="org.egovframe.rte.fdl.property.impl.EgovPropertyServiceImpl">
        <property name="properties">
            <props>
                <prop key="WEB_DIR">C:/dev/workspace/humanframe</prop>
                <prop key="FILE_UPLOAD_DIR">/data</prop>
                <prop key="LOG_PATH">/logs</prop>
            </props>
        </property>
    </bean>
</beans>

<beans profile="prd">
    <bean id="propertiesService" class="org.egovframe.rte.fdl.property.impl.EgovPropertyServiceImpl">
        <property name="properties">
            <props>
                <prop key="WEB_DIR">/home/prod/humanframe</prop>
                <prop key="FILE_UPLOAD_DIR">/data</prop>
                <prop key="LOG_PATH">/logs</prop>
            </props>
        </property>
    </bean>
</beans>

10.5 백업 및 복구

시스템 장애 발생 시 신속하게 복구할 수 있도록 백업 및 복구 전략을 수립해야 합니다.

10.5.1 데이터베이스 백업

MySQL 백업

# 전체 데이터베이스 백업
mysqldump -u username -p --all-databases > backup_$(date +%Y%m%d).sql

# 특정 데이터베이스 백업
mysqldump -u username -p humanframe > humanframe_$(date +%Y%m%d).sql

# 압축 백업
mysqldump -u username -p humanframe | gzip > humanframe_$(date +%Y%m%d).sql.gz

Oracle 백업

# exp 유틸리티 사용
exp username/password@sid file=backup_$(date +%Y%m%d).dmp full=y

# expdp 유틸리티 사용
expdp username/password@sid directory=DATA_PUMP_DIR dumpfile=backup_$(date +%Y%m%d).dmp full=y

10.5.2 파일 시스템 백업

rsync를 사용한 백업

# 전체 애플리케이션 디렉토리 백업
rsync -avz --delete /home/humanframe/app/ /backup/humanframe/app/

# 업로드 파일만 백업
rsync -avz --delete /home/humanframe/data/ /backup/humanframe/data/

tar를 사용한 백업

# 전체 애플리케이션 디렉토리 백업
tar -czf /backup/humanframe_$(date +%Y%m%d).tar.gz /home/humanframe/

# 증분 백업
tar -czf /backup/humanframe_$(date +%Y%m%d).tar.gz -g /backup/humanframe.snar /home/humanframe/

10.5.3 자동화된 백업

cron을 사용한 자동 백업

/etc/cron.d/humanframe-backup
0 2 * * * root /home/humanframe/scripts/backup.sh
backup.sh 스크립트
#!/bin/bash

# 변수 설정
DATE=$(date +%Y%m%d)
BACKUP_DIR=/backup/humanframe
DB_USER=username
DB_PASS=password
DB_NAME=humanframe
APP_DIR=/home/humanframe

# 디렉토리 생성
mkdir -p $BACKUP_DIR/$DATE

# 데이터베이스 백업
mysqldump -u $DB_USER -p$DB_PASS $DB_NAME | gzip > $BACKUP_DIR/$DATE/db_$DATE.sql.gz

# 파일 시스템 백업
tar -czf $BACKUP_DIR/$DATE/app_$DATE.tar.gz $APP_DIR/app
tar -czf $BACKUP_DIR/$DATE/data_$DATE.tar.gz $APP_DIR/data

# 오래된 백업 삭제 (30일 이상)
find $BACKUP_DIR -type d -mtime +30 -exec rm -rf {} \;

# 로그 기록
echo "Backup completed at $(date)" >> $BACKUP_DIR/backup.log

10.5.4 복구 절차

데이터베이스 복구

# MySQL 복구
mysql -u username -p humanframe < backup_20240101.sql

# 압축 파일에서 복구
gunzip -c backup_20240101.sql.gz | mysql -u username -p humanframe

파일 시스템 복구

# tar 파일에서 복구
tar -xzf /backup/humanframe_20240101.tar.gz -C /

# rsync를 사용한 복구
rsync -avz /backup/humanframe/app/ /home/humanframe/app/

10.6 모니터링 및 유지보수

시스템의 안정적인 운영을 위해 모니터링 및 유지보수 방안을 수립해야 합니다.

10.6.1 시스템 모니터링

모니터링 대상

🖥️ 서버 자원

  • CPU 사용률
  • 메모리 사용률
  • 디스크 사용률
  • 네트워크 트래픽

🌐 애플리케이션

  • 응답 시간
  • 오류 발생 횟수
  • 동시 접속자 수
  • 트랜잭션 처리량

🗄️ 데이터베이스

  • 쿼리 실행 시간
  • 연결 수
  • 테이블 크기
  • 인덱스 사용 현황

모니터링 도구

📊추천 모니터링 도구

  • Prometheus + Grafana: 메트릭 수집 및 시각화, 알림 설정
  • ELK 스택: 로그 수집 및 분석, 이상 징후 탐지
  • Pinpoint/Scouter: 애플리케이션 성능 모니터링, 트랜잭션 추적

10.6.2 로그 관리

로그 수집 및 분석

📥 로그 수집

  • Filebeat, Fluentd 등을 사용하여 로그 수집
  • 중앙 로그 서버로 전송

💾 로그 저장

  • Elasticsearch에 로그 저장
  • 로그 보관 기간 설정

📊 로그 분석

  • Kibana를 사용하여 로그 시각화 및 분석
  • 로그 패턴 분석을 통한 이상 징후 탐지

로그 로테이션

/etc/logrotate.d/humanframe
/home/humanframe/logs/*.log {
    daily
    missingok
    rotate 30
    compress
    delaycompress
    notifempty
    create 0640 tomcat tomcat
    sharedscripts
    postrotate
        /bin/kill -USR1 $(cat /home/humanframe/tomcat/logs/catalina.pid 2>/dev/null) 2>/dev/null || true
    endscript
}

10.6.3 정기 유지보수

유지보수 항목

🔄 패치 및 업데이트

  • 보안 패치 적용
  • 라이브러리 업데이트
  • 기능 개선

⚡ 성능 최적화

  • 데이터베이스 인덱스 최적화
  • 쿼리 튜닝
  • 캐시 설정 조정

🧹 데이터 정리

  • 불필요한 데이터 삭제
  • 로그 파일 정리
  • 임시 파일 정리

🔒 보안 점검

  • 취약점 스캔
  • 접근 권한 검토
  • 보안 설정 검토

유지보수 일정

주기 점검 항목
일일 점검 시스템 상태 확인, 오류 로그 확인, 백업 완료 여부 확인
주간 점검 성능 지표 분석, 디스크 공간 확인, 보안 로그 검토
월간 점검 데이터베이스 최적화, 불필요한 데이터 정리, 보안 패치 적용
분기별 점검 전체 시스템 점검, 성능 테스트, 재해 복구 테스트
🎯

배포 및 운영 핵심 포인트

  • 체계적인 배포 프로세스: 개발 → 테스트 → 운영 단계별 검증
  • 환경별 설정 관리: Spring Profile을 활용한 환경별 설정 분리
  • 자동화된 백업: 정기적인 데이터베이스 및 파일 시스템 백업
  • 지속적인 모니터링: 시스템 상태 및 성능 지표 모니터링
  • 정기 유지보수: 보안 패치, 성능 최적화, 데이터 정리