zioinfo-mail/workspace/guardia-docs/19_zio서버_운영가이드.md
DESKTOP-TKLFCPR\ython cfe2901a55 refactor(structure): consolidate all projects under workspace/
- itsm/    -> workspace/guardia-itsm/
- manager/ -> workspace/guardia-manager/
- app/     -> workspace/guardia-messenger/
- manual/  -> workspace/guardia-docs/

workspace/zioinfo-web/ unchanged.
git mv preserves full commit history.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 23:50:56 +09:00

733 lines
17 KiB
Markdown

# zio-server 운영 가이드
> **서버**: zio-server | **IP**: zioinfo.co.kr
> **작성일**: 2026-05-30 | **대상**: 서버 운영자 / 개발자
---
## 1. 서비스 접속 주소
| 서비스 | URL | 계정 |
|--------|-----|------|
| 지오정보기술 홈페이지 | **https://zioinfo.co.kr** | — |
| 홈페이지 관리자 | https://zioinfo.co.kr/admin | admin / Admin@2026! |
| GUARDiA ITSM | **https://zioinfo.co.kr:8001** | admin / 1111 |
| GUARDiA Manager | **https://zioinfo.co.kr:8090** | admin / Admin@zioinfo2026! |
| GUARDiA 개방망 | **https://zioinfo.co.kr:8443** | API Key 인증 |
| Gitea (Git 서버) | **https://zioinfo.co.kr:3000** | zio / Zio@Admin2026! |
| Jenkins (CI/CD) | **https://zioinfo.co.kr:8080** | admin / `c753461ad51f4b85901e90bff6612f84` | Admin@2026!
---
## 2. 서버 접속
```bash
# SSH 키 인증 (권장)
ssh -i "zio-server-key.pem" root@zioinfo.co.kr
# 비밀번호 인증
ssh root@zioinfo.co.kr
# 비밀번호: 1q2w3e!Q
```
---
## 3. 서비스 관리
### 3-1. 전체 상태 확인
```bash
# 모든 서비스 상태 한 번에 확인
for svc in nginx zioinfo zioinfo-deploy guardia gitea jenkins postgresql ollama; do
status=$(systemctl is-active $svc 2>/dev/null)
printf "%-22s %s\n" $svc $status
done
```
### 3-2. 개별 서비스 명령
```bash
# 서비스 시작 / 중지 / 재시작 / 상태
systemctl start <서비스명>
systemctl stop <서비스명>
systemctl restart <서비스명>
systemctl status <서비스명>
# 부팅 자동시작 설정 / 해제
systemctl enable <서비스명>
systemctl disable <서비스명>
```
**서비스명 목록:**
| 서비스명 | 설명 |
|---------|------|
| `nginx` | 웹 프록시 서버 |
| `zioinfo` | 지오정보기술 홈페이지 (Spring Boot, 포트 8082) |
| `zioinfo-deploy` | CI/CD 웹훅 서버 (포트 9999) |
| `guardia` | GUARDiA ITSM (FastAPI, 포트 8001) |
| `gitea` | Git 서버 (포트 3000) |
| `jenkins` | CI/CD 파이프라인 (포트 8080) |
| `postgresql` | 데이터베이스 (포트 5432) |
| `ollama` | LLM 엔진 (포트 11434) |
---
## 4. 로그 확인
```bash
# Spring Boot 홈페이지 로그
tail -f /var/log/zioinfo/spring.log
# CI/CD 배포 로그 (실시간)
tail -f /var/log/zioinfo/deploy.log
# GUARDiA ITSM 로그
tail -f /opt/guardia/logs/guardia.log
tail -f /opt/guardia/logs/error.log
# Nginx 접근 로그
tail -f /var/log/nginx/access.log
tail -f /var/log/nginx/error.log
# systemd 서비스 로그 (최근 50줄)
journalctl -u zioinfo -n 50 --no-pager
journalctl -u guardia -n 50 --no-pager
journalctl -u gitea -n 50 --no-pager
# 실시간 로그 스트리밍
journalctl -u zioinfo -f
```
---
## 5. 홈페이지 배포 (CI/CD)
### 5-1. 자동 배포 흐름
```
로컬 코드 수정
git add . && git commit -m "메시지"
git push gitea main:main ← Gitea에 push
Gitea 웹훅 → localhost:9999 호출
자동 빌드 파이프라인 실행:
① git pull (소스 갱신)
② npm build (React 빌드)
③ mvn package (Spring Boot JAR 빌드)
④ 파일 복사 (JAR → /opt/zioinfo/app, 정적 → /var/www/zioinfo)
⑤ systemctl restart zioinfo
배포 완료 (약 2~4분 소요)
```
### 5-2. 로컬에서 Gitea push
```bash
# 최초 remote 설정 (1회)
cd workspace/zioinfo-web
git remote add gitea http://zio:Zio%40Admin2026%21@zioinfo.co.kr:3000/zio/zioinfo-web.git
# 이후 배포
git add .
git commit -m "feat: 변경 내용 설명"
git push gitea main:main
```
### 5-3. 배포 상태 모니터링
```bash
# 배포 로그 실시간 확인
ssh root@zioinfo.co.kr "tail -f /var/log/zioinfo/deploy.log"
# 배포 완료 후 서비스 상태
ssh root@zioinfo.co.kr "systemctl is-active zioinfo && curl -s -o /dev/null -w 'HTTP %{http_code}' http://localhost:8082/api/company"
```
### 5-4. 수동 배포 (긴급 시)
```bash
# 서버에서 직접 수동 배포
ssh root@zioinfo.co.kr
# 소스 갱신
cd /opt/zioinfo/src && git pull origin main
# React 빌드
cd frontend && npm ci && npm run build
# Spring Boot 빌드
cd ../backend && mvn clean package -DskipTests -q
# 배포
cp target/zioinfo-web-*.jar /opt/zioinfo/app/app.jar
cp -r src/main/resources/static/. /var/www/zioinfo/
systemctl restart zioinfo
```
---
## 6. GUARDiA ITSM 관리
### 6-1. 서비스 재시작
```bash
systemctl restart guardia
journalctl -u guardia -n 20 --no-pager
```
### 6-2. Python 패키지 업데이트
```bash
source /opt/guardia/venv/bin/activate
pip install -r /opt/guardia/app/requirements.txt
deactivate
systemctl restart guardia
```
### 6-3. 환경변수 설정
```bash
# .env 파일 편집
nano /opt/guardia/app/.env
# 주요 항목:
# DATABASE_URL=postgresql+asyncpg://guardia:G@urd1a_2026!@localhost:5432/guardia_db
# OLLAMA_BASE_URL=http://localhost:11434
# LLM_MODEL=llama3:8b
# SECRET_KEY=<JWT 시크릿>
```
---
## 7. 데이터베이스 관리
### 7-1. PostgreSQL 접속
```bash
# postgres 관리자로 접속
sudo -u postgres psql
# guardia DB 접속
psql -h 127.0.0.1 -U guardia -d guardia_db
비밀번호: G@urd1a_2026!
# gitea DB 접속
psql -h 127.0.0.1 -U gitea -d gitea_db
비밀번호: G1tea_2026!
```
### 7-2. 데이터베이스 백업
```bash
# 전체 백업
pg_dump -U guardia guardia_db > /opt/guardia/backups/guardia_$(date +%Y%m%d).sql
pg_dump -U gitea gitea_db > /opt/gitea/backup/gitea_$(date +%Y%m%d).sql
# 복원
psql -U guardia guardia_db < /opt/guardia/backups/guardia_20260530.sql
```
### 7-3. 홈페이지 SQLite 백업
```bash
# SQLite DB 파일 직접 복사
cp /opt/zioinfo/app/data/zioinfo.db /opt/zioinfo/app/data/zioinfo_$(date +%Y%m%d).db.bak
```
---
## 8. Nginx 관리
### 8-1. 설정 테스트 및 리로드
```bash
# 설정 문법 검사
nginx -t
# 무중단 리로드 (설정 변경 반영)
systemctl reload nginx
# 설정 파일 위치
ls /etc/nginx/sites-available/
```
### 8-2. 사이트 설정 파일
| 파일 | 역할 |
|------|------|
| `/etc/nginx/sites-available/zioinfo` | 홈페이지 (포트 80 → 8082) |
| `/etc/nginx/sites-available/guardia` | GUARDiA (포트 9001 → 8001) |
| `/etc/nginx/sites-available/gitea` | Gitea (포트 3001 → 3000) |
| `/etc/nginx/sites-available/jenkins` | Jenkins (포트 8088 → 8080) |
### 8-3. Nginx 설정 변경 절차
```bash
# 1. 설정 파일 편집
nano /etc/nginx/sites-available/zioinfo
# 2. 문법 검사
nginx -t
# 3. 적용
systemctl reload nginx
```
---
## 9. Gitea 관리
### 9-1. 저장소 관리
```bash
# API로 저장소 목록 확인
curl -s http://localhost:3000/api/v1/repos/search -u "zio:Zio@Admin2026!" \
| python3 -c "import json,sys; [print(r['full_name']) for r in json.load(sys.stdin)['data']]"
# 저장소 직접 경로
ls /var/lib/gitea/data/repositories/zio/
```
### 9-2. 웹훅 확인
```bash
# zioinfo-web 웹훅 목록
curl -s http://localhost:3000/api/v1/repos/zio/zioinfo-web/hooks \
-u "zio:Zio@Admin2026!" | python3 -m json.tool
```
### 9-3. 설정 파일
```bash
# Gitea 설정 편집
nano /etc/gitea/app.ini
systemctl restart gitea
```
---
## 10. Jenkins 초기 설정 (최초 1회)
Jenkins는 브라우저에서 초기 설정을 완료해야 합니다.
### 10-1. 초기 설정 절차
1. 브라우저에서 `https://zioinfo.co.kr:8080` 접속
2. 초기 비밀번호 입력 (아래 값 복사):
```
c753461ad51f4b85901e90bff6612f84
```
서버에서 재확인:
```bash
cat /var/lib/jenkins/secrets/initialAdminPassword
```
3. **"Install suggested plugins"** 선택
4. 추가 플러그인 설치:
- **Pipeline** (워크플로우 파이프라인)
- **Git** (Git 연동)
- **Gitea** (Gitea 웹훅 연동)
5. 관리자 계정 생성: `admin / Admin@2026!`
6. Jenkins URL 설정: `https://zioinfo.co.kr:8080`
### 10-2. 파이프라인 Job 생성
초기 설정 완료 후:
```
Jenkins → New Item → "zioinfo-web" → Pipeline 선택
→ Pipeline 탭 → Definition: "Pipeline script from SCM"
→ SCM: Git
→ Repository URL: http://localhost:3000/zio/zioinfo-web.git
→ Branch: main
→ Script Path: Jenkinsfile
→ 저장
```
---
## 11. Ollama / LLM 관리
### 11-1. 모델 관리
```bash
# 설치된 모델 목록
ollama list
# 모델 다운로드 (4.7GB, 시간 소요)
ollama pull llama3:8b
# 모델 테스트
ollama run llama3:8b "안녕하세요, 간단한 테스트입니다."
# API 호출 테스트
curl http://localhost:11434/api/generate \
-d '{"model":"llama3:8b","prompt":"Hello","stream":false}'
```
### 11-2. 서비스 재시작
```bash
systemctl restart ollama
# 재시작 후 약 10~30초 대기 (모델 로딩)
```
---
## 12. 리소스 모니터링
### 12-1. 실시간 모니터링
```bash
# 전체 리소스 현황
htop
# 디스크 사용량
df -h
# 메모리 사용량
free -h
# 포트 사용 현황
ss -tlnp
# 프로세스별 리소스
ps aux --sort=-%cpu | head -15
ps aux --sort=-%mem | head -15
```
### 12-2. 서비스별 리소스 현황
| 서비스 | CPU | RAM |
|--------|-----|-----|
| Nginx | ~0.1% | ~50 MB |
| Spring Boot (홈페이지) | ~0.5% | ~400 MB |
| GUARDiA ITSM (FastAPI) | ~0.5% | ~300 MB |
| PostgreSQL | ~0.3% | ~256 MB |
| Ollama + Llama3:8b | ~1.0% (유휴) | ~4.7 GB |
| Jenkins | ~0.2% | ~512 MB |
| Gitea | ~0.1% | ~150 MB |
| **합계** | **~2.7%** | **~6.4 GB** |
---
## 13. 보안 운영
### 13-1. SSH 보안 강화 (권장)
```bash
# root 비밀번호 로그인 비활성화 (키 인증만 허용)
sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
systemctl restart sshd
```
### 13-2. 방화벽 규칙 관리
```bash
# 현재 규칙 확인
ufw status numbered
# 규칙 추가
ufw allow <포트>/tcp
# 규칙 삭제
ufw delete <번호>
# 특정 IP만 허용 (예: 관리자 IP)
ufw allow from 203.xxx.xxx.xxx to any port 8080
```
### 13-3. SSL/HTTPS 설정 (도메인 보유 시)
```bash
# Let's Encrypt 인증서 발급
apt install certbot python3-certbot-nginx
certbot --nginx -d zioinfo.co.kr -d www.zioinfo.co.kr
# 자동 갱신 확인
certbot renew --dry-run
```
---
## 14. 장애 대응
### 14-1. 홈페이지 접속 불가
```bash
# 1. Nginx 상태 확인
systemctl status nginx
nginx -t
# 2. Spring Boot 상태 확인
systemctl status zioinfo
curl -s http://localhost:8082/api/company
# 3. 로그 확인
tail -50 /var/log/zioinfo/spring.log
# 4. 재시작
systemctl restart zioinfo
systemctl restart nginx
```
### 14-2. 배포 실패
```bash
# 1. 배포 로그 확인
tail -50 /var/log/zioinfo/deploy.log
# 2. CI/CD 서버 상태
systemctl status zioinfo-deploy
# 3. 소스 상태 확인
git -C /opt/zioinfo/src status
git -C /opt/zioinfo/src log --oneline -5
# 4. 수동 배포 실행 (5-4절 참고)
```
### 14-3. GUARDiA ITSM 오류
```bash
# 1. 서비스 상태
systemctl status guardia
tail -20 /opt/guardia/logs/error.log
# 2. PostgreSQL 연결 확인
psql -h 127.0.0.1 -U guardia -d guardia_db -c "SELECT 1"
# 3. 재시작
systemctl restart guardia
```
### 14-4. 데이터베이스 연결 오류
```bash
# PostgreSQL 상태
systemctl status postgresql
sudo -u postgres psql -c "\l"
# 재시작
systemctl restart postgresql
# 연결 확인
psql -h 127.0.0.1 -U guardia -d guardia_db -c "SELECT count(*) FROM pg_tables"
```
### 14-5. 메모리 부족
```bash
# 메모리 사용량 확인
free -h
ps aux --sort=-%mem | head -10
# 가장 많이 사용하는 서비스 재시작 (Ollama가 대부분 점유)
systemctl restart ollama
# Swap 임시 설정 (재부팅 시 사라짐)
fallocate -l 4G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
```
---
## 15. 백업 및 복구
### 15-1. 정기 백업 스크립트
```bash
#!/bin/bash
# /opt/backup/daily_backup.sh
DATE=$(date +%Y%m%d_%H%M)
BACKUP_DIR="/opt/backup/${DATE}"
mkdir -p "$BACKUP_DIR"
# DB 백업
sudo -u postgres pg_dump guardia_db > "$BACKUP_DIR/guardia_db.sql"
sudo -u postgres pg_dump gitea_db > "$BACKUP_DIR/gitea_db.sql"
# SQLite 백업
cp /opt/zioinfo/app/data/zioinfo.db "$BACKUP_DIR/zioinfo.db"
# 설정 파일 백업
cp -r /etc/nginx/sites-available "$BACKUP_DIR/nginx/"
cp -r /etc/gitea "$BACKUP_DIR/gitea/"
cp /opt/guardia/app/.env "$BACKUP_DIR/guardia.env"
# 30일 이전 백업 삭제
find /opt/backup -maxdepth 1 -type d -mtime +30 -exec rm -rf {} \;
echo "백업 완료: $BACKUP_DIR"
```
```bash
# cron 등록 (매일 새벽 2시)
crontab -e
# 추가:
0 2 * * * /opt/backup/daily_backup.sh >> /var/log/backup.log 2>&1
```
---
## 16. 자주 쓰는 명령어 모음
```bash
# ── 전체 서비스 상태 ──────────────────────────────
for s in nginx zioinfo guardia gitea jenkins postgresql ollama; do
printf "%-15s %s\n" $s $(systemctl is-active $s)
done
# ── 포트 사용 현황 ────────────────────────────────
ss -tlnp | awk '{print $4}' | sort
# ── 디스크 / 메모리 ──────────────────────────────
df -h / && free -h
# ── 홈페이지 API 테스트 ───────────────────────────
curl -s http://localhost/api/company | python3 -m json.tool
# ── 홈페이지 관리자 로그인 테스트 ────────────────
curl -s -X POST http://localhost/api/admin/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"Admin@2026!"}' \
| python3 -c "import json,sys; d=json.load(sys.stdin); print('Token:', d.get('token','FAIL')[:20]+'...')"
# ── Gitea 저장소 목록 ─────────────────────────────
curl -s http://localhost:3000/api/v1/repos/search \
-u "zio:Zio@Admin2026!" | python3 -c \
"import json,sys; [print(r['full_name']) for r in json.load(sys.stdin)['data']]"
# ── 배포 수동 트리거 ─────────────────────────────
curl -s -X POST http://localhost:9999/ \
-H "Content-Type: application/json" -d '{}'
# ── Ollama 모델 확인 ─────────────────────────────
ollama list
# ── 최근 에러 로그 ───────────────────────────────
journalctl -p err --since "1 hour ago" --no-pager
```
---
## 17. 업데이트 및 유지보수
### 17-1. 시스템 패키지 업데이트
```bash
apt-get update && apt-get upgrade -y
# 주의: 업데이트 전 서비스 상태 확인 필수
# 커널 업데이트 시 재부팅 필요
```
### 17-2. 애플리케이션 업데이트
```bash
# Gitea 업데이트
wget -q https://dl.gitea.com/gitea/X.X.X/gitea-X.X.X-linux-amd64 \
-O /opt/gitea/bin/gitea
chmod +x /opt/gitea/bin/gitea
systemctl restart gitea
# Ollama 업데이트
curl -fsSL https://ollama.com/install.sh | sh
systemctl restart ollama
```
### 17-3. LLM 모델 업데이트
```bash
# 새 버전 모델 다운로드
ollama pull llama3:8b
# 구 버전 삭제
ollama rm llama3:7b
```
---
## 방화벽 (ufw + NCloud ACG) — 2026-05-31 정리 완료
### 현재 ufw 규칙 (12개)
| # | 포트 | 서비스 | 목적 |
|---|------|--------|------|
| 1 | 22/tcp | SSH | 서버 관리 |
| 2 | 80/tcp | Nginx | HTTP → HTTPS 자동 리다이렉트 |
| 3 | 443/tcp | Nginx + Let's Encrypt | HTTPS 홈페이지 |
| 4 | 8080/tcp | Jenkins | CI/CD 파이프라인 |
| 5 | 8001/tcp | GUARDiA ITSM | ITSM API 서버 |
| 6 | 3000/tcp | Gitea | Git 저장소 |
| 7 | 9999/tcp | CI/CD Webhook | 자동 배포 수신 |
| 8 | 8443/tcp | Nginx 개방망 | GUARDiA 개방망 HTTPS |
| 9 | 8090/tcp | GUARDiA Manager | 관리자 포털 |
| 10 | 25/tcp | Postfix | SMTP 수신 |
| 11 | 587/tcp | Postfix | SMTP 인증 발신 |
| 12 | 993/tcp | Dovecot | IMAPS |
### NCloud ACG 동일 규칙 적용 필요
NCloud Console → Server → Network ACG → 인바운드 규칙에 위 12개 포트(TCP, 0.0.0.0/0) 등록.
### HTTPS 전환 구조 (2026-05-31)
모든 서비스가 Let's Encrypt 인증서로 HTTPS 서빙. Nginx가 SSL 종료 후 내부 포트로 프록시.
| 공개 포트 | 프로토콜 | Nginx → 내부 포트 | 서비스 |
|----------|---------|------------------|--------|
| 80 | HTTP | → HTTPS 301 | 홈페이지 리다이렉트 |
| 443 | HTTPS | 127.0.0.1:8082 | 지오정보기술 홈페이지 |
| 8001 | HTTPS | 127.0.0.1:9001 | GUARDiA ITSM |
| 8090 | HTTPS | 127.0.0.1:8002 + /var/www/manager | GUARDiA Manager |
| 8443 | HTTPS | 127.0.0.1:9001 | GUARDiA 개방망 |
| 3000 | HTTPS | 127.0.0.1:9003 | Gitea |
| 8080 | HTTPS | 127.0.0.1:9080 | Jenkins |
### 내부 전용 포트 (외부 차단)
| 포트 | 서비스 | 비고 |
|------|--------|------|
| 5432 | PostgreSQL | 127.0.0.1 only |
| 11434 | Ollama | 127.0.0.1 only |
| 8002 | GUARDiA Manager Backend | 127.0.0.1 only |
| 8082 | Spring Boot | Nginx 뒤 내부 |
### 제거된 규칙 (2026-05-31)
`8088, 9001, 8082, 8002, 995, 143, 110, 3001` — 중복·평문·미사용
### ufw 상태 확인
```bash
ufw status numbered
```
### SSL 인증서 (Let's Encrypt)
```bash
# 인증서 목록 확인
certbot certificates
# 갱신 테스트
certbot renew --dry-run
# 수동 갱신
certbot renew
```
| 항목 | 내용 |
|------|------|
| 도메인 | zioinfo.co.kr |
| 만료일 | 2026-08-29 |
| 자동갱신 | certbot.timer (하루 2회) |
---
*문서 버전: 1.0 | 최종 수정: 2026-05-30*