docs: [ops] 인프라 운영 매뉴얼 대규모 업데이트

- CI/CD 서버 스펙 변경 반영 (8vCPU/16GB)
- 개발서버 DB 백업 문서화 (sam-db-backup.sh)
- CI/CD 백업 경로/대상 업데이트 (/data/, codebridge 추가, root 크론)
- MNG Jenkinsfile storage/logs 심링크 수정 반영
- 마이그레이션 정책 추가 (sam→API, codebridge→MNG)
- MNG 배포 후 500 에러 트러블슈팅 사례 추가
- Laravel Scheduler 섹션 추가 (API+MNG, www-data)
- deploy 전용 계정 전환 계획 문서 추가
This commit is contained in:
2026-03-19 20:19:40 +09:00
parent 9ee199d8e1
commit aac602e04d
7 changed files with 764 additions and 53 deletions

View File

@@ -4,6 +4,38 @@
---
## 마이그레이션 정책
### 원칙
| 대상 DB | 마이그레이션 위치 | 실행 주체 | 비고 |
|---------|-----------------|----------|------|
| **sam** DB | `api/database/migrations/` | API Jenkinsfile | sam DB 스키마/데이터 변경은 API에서만 |
| **codebridge** DB | `mng/database/migrations/` | MNG Jenkinsfile | codebridge DB 변경은 MNG에서만 |
### 이력 관리
- API와 MNG 모두 `sam.migrations` 테이블에 이력 기록 (Laravel 기본 동작)
- 양쪽에서 `php artisan migrate --force`를 실행해도 **파일명이 겹치지 않으면 충돌 없음**
- Laravel은 자기 폴더의 파일만 스캔하고, `sam.migrations`에 이미 있으면 skip
```
sam.migrations 테이블:
1 (API 실행) ✓ ← API migrate 시: 이미 있으니 skip
2 (API 실행) ✓
3 (MNG 실행) ✓ ← API는 이 파일이 없으므로 모름 (무관)
4 (API 실행) ✓
5 (MNG 실행) ✓ ← MNG migrate 시: 이미 있으니 skip
```
### 주의사항
- `--force`는 production 환경에서 확인 프롬프트를 건너뛰는 옵션 (순서 충돌과 무관)
- 파일명(타임스탬프)이 겹치지 않도록 주의
- sam DB를 변경하는 마이그레이션은 **반드시 API에서** 작성 (MNG에서 sam DB 변경 금지)
---
## [운영] MySQL 접속
```bash
@@ -42,32 +74,82 @@ mysqldump -u hskwon --single-transaction --routines --triggers --all-databases |
mysqldump -u hskwon --single-transaction sam 테이블명 > /tmp/sam_테이블명_$(date +%Y%m%d_%H%M%S).sql
```
### [CI/CD] 자동 백업 (운영 DB)
### [개발] 자동 백업
CI/CD 서버 crontab에서 매일 03:00에 원격 백업 수행. sam_backup 사용자로 운영 DB에 접속.
개발서버 `/etc/crontab`에서 root로 매일 04:30 실행.
**스크립트:** /home/hskwon/scripts/backup-db.sh
**저장소:** /home/hskwon/backups/mysql/
**보존:** 14일
| 항목 | 값 |
|------|-----|
| 스크립트 | `/home/webservice/api/scripts/backup/sam-db-backup.sh` |
| 설정 파일 | `/home/webservice/api/scripts/backup/backup.conf` (chmod 600) |
| 저장소 | `/data/backup/mysql/daily/YYYY-MM-DD/` |
| 대상 DB | sam, sam_stat, codebridge |
| 보존 | daily 14일, weekly 28일 (일요일 자동 복사) |
| 로그 | `/data/backup/mysql/logs/backup.log` |
| 상태 파일 | `/data/backup/mysql/.backup_status` (JSON) |
```bash
# 수동 원격 백업
ssh sam-prod "mysqldump --single-transaction --routines sam" | gzip \
> /home/hskwon/backups/mysql/sam_production_$(date +%Y%m%d).sql.gz
# 수동 실행
sudo /home/webservice/api/scripts/backup/sam-db-backup.sh
# 백업 확인
ls -lh /data/backup/mysql/daily/$(date +%Y-%m-%d)/
cat /data/backup/mysql/.backup_status
# 로그 확인
tail -20 /data/backup/mysql/logs/backup.log
```
### [CI/CD] Gitea DB 백업
### [개발] 수동 백업
```bash
mysqldump --single-transaction --routines --triggers gitea \
| gzip > /home/hskwon/backups/mysql/gitea_$(date +%Y%m%d_%H%M%S).sql.gz
# 개별 DB (codebridge 사용자)
mysqldump -ucodebridge -p --single-transaction --routines --triggers --no-tablespaces sam | gzip > /tmp/sam_$(date +%Y%m%d_%H%M%S).sql.gz
mysqldump -ucodebridge -p --single-transaction --routines --triggers --no-tablespaces codebridge | gzip > /tmp/codebridge_$(date +%Y%m%d_%H%M%S).sql.gz
```
### [개발] DB 복구
```bash
# 전체 DB 복구
gunzip -c /data/backup/mysql/daily/2026-03-19/sam_20260319_0430.sql.gz | mysql -ucodebridge -p sam
# sam_stat 복구
gunzip -c /data/backup/mysql/daily/2026-03-19/sam_stat_20260319_0430.sql.gz | mysql -ucodebridge -p sam_stat
# 주간 백업에서 복구 (7일 이전)
ls /data/backup/mysql/weekly/
gunzip -c /data/backup/mysql/weekly/sam_YYYYMMDD_HHMM_week.sql.gz | mysql -ucodebridge -p sam
```
### [CI/CD] 자동 백업 (운영 DB + Gitea)
CI/CD 서버 `/etc/crontab`에서 root로 매일 03:00 실행. sam_backup 사용자로 운영 DB에 원격 접속.
| 항목 | 값 |
|------|-----|
| 스크립트 | `/data/scripts/backup-db.sh` |
| 인증 파일 | `/data/scripts/.sam_backup.cnf` (chmod 600) |
| 저장소 | `/data/backups/mysql/` |
| 실행 사용자 | root (`/etc/crontab`) |
| 대상 DB | gitea (로컬, auth_socket), sam + sam_stat + codebridge (운영 원격) |
| 보존 | 14일 |
| 로그 | `/data/backups/mysql/backup.log` |
```bash
# 수동 실행
/data/scripts/backup-db.sh
# 백업 확인
ls -lht /data/backups/mysql/ | head -10
tail -10 /data/backups/mysql/backup.log
```
### 백업 파일 외부 전송
```bash
# 운영서버 -> CI/CD 서버
scp /tmp/sam_*.sql.gz sam-cicd:/home/hskwon/backups/mysql/
scp /tmp/sam_*.sql.gz sam-cicd:/data/backups/mysql/
```
---