Files
sam-docs/deploys/ops-manual/01-server-overview.md

343 lines
14 KiB
Markdown
Raw Normal View History

# 1. 서버 인프라 개요
[목차로 돌아가기](./README.md)
---
## 운영서버 (sam-prod)
### 서버 사양
| 항목 | 값 |
|------|-----|
| IP | 211.117.60.189 |
| 호스트명 | sam-prod |
| OS | Ubuntu 24.04.4 LTS |
| 커널 | 6.8.0-100-generic |
| CPU | 2 vCPU |
| RAM | 8GB |
| Swap | 4GB |
| 디스크 | 98GB (여유 79GB) |
| 사용자 | hskwon (SSH 키 인증, sudo NOPASSWD) |
### 도메인 목록
| 도메인 | 서비스 | 백엔드 | 포트 |
|--------|--------|--------|------|
| sam.it.kr | Next.js 15 프론트엔드 | PM2 cluster x2 | 3000 |
| api.sam.it.kr | Laravel 12 API | PHP-FPM api pool | unix socket |
| mng.codebridge-x.com | Laravel 12 Admin | PHP-FPM admin pool | unix socket |
| sales.codebridge-x.com | Plain PHP 레거시 | PHP-FPM sales pool | unix socket |
| codebridge-x.com (+ www) | 정적 랜딩페이지 | Nginx direct | 80/443 |
| stage.sam.it.kr | Next.js Stage | PM2 fork x1 | 3100 |
| stage-api.sam.it.kr | Laravel API Stage | PHP-FPM api-stage pool | unix socket |
모든 도메인은 Let's Encrypt SSL 적용 (알림: develop@codebridge-x.com).
### 서비스 현황
| 서비스 | 버전 | 포트 | 상태 |
|--------|------|------|------|
| Nginx | 1.24.0 | 80/443 | active |
| PHP-FPM | 8.4.18 | unix socket (4개 pool) | active |
| MySQL | 8.4.8 | 3306 | active |
| Redis | 7.0.15 | 6379 (localhost) | active |
| PM2 | 6.0.14 | 3000 (cluster x2), 3100 (fork x1) | active |
| Supervisor | - | - | active (queue worker x2) |
| node_exporter | 1.8.2 | 9100 | active |
| Certbot | 2.9.0 | - | timer active |
| fail2ban | - | - | active |
### 주요 디렉토리
```
/home/webservice/
api/ Laravel API (운영) - releases/shared 구조
current -> releases/...
releases/
shared/ (.env, storage/)
api-stage/ Laravel API (Stage) - 동일 구조
mng/ Laravel Admin - 동일 구조
sales/ Plain PHP 레거시 (.env, uploads/)
react/ Next.js 운영 - releases/shared 구조
react-stage/ Next.js Stage - 동일 구조
landing/ 정적 랜딩페이지
ecosystem.config.js PM2 설정
```
### 주요 설정 파일
| 구분 | 경로 |
|------|------|
| Nginx 메인 설정 | /etc/nginx/nginx.conf |
| Nginx 사이트 설정 | /etc/nginx/sites-available/*.conf |
| Nginx 보안 스니펫 | /etc/nginx/snippets/security.conf |
| PHP-FPM Pool (API) | /etc/php/8.4/fpm/pool.d/api.conf |
| PHP-FPM Pool (Admin) | /etc/php/8.4/fpm/pool.d/admin.conf |
| PHP-FPM Pool (Sales) | /etc/php/8.4/fpm/pool.d/sales.conf |
| PHP-FPM Pool (API Stage) | /etc/php/8.4/fpm/pool.d/api-stage.conf |
| MySQL 튜닝 | /etc/mysql/mysql.conf.d/sam-tuning.cnf |
| Redis | /etc/redis/redis.conf |
| Supervisor | /etc/supervisor/conf.d/sam-queue.conf |
| PM2 | /home/webservice/ecosystem.config.js |
| API .env | /home/webservice/api/shared/.env |
| MNG .env | /home/webservice/mng/shared/.env |
| Sales .env | /home/webservice/sales/.env |
### 메모리 배분
| 서비스 | 할당 | 설정 |
|--------|------|------|
| MySQL 8.4 | ~2GB | innodb_buffer_pool_size=2G |
| Redis | ~0.5GB | maxmemory 512mb |
| PHP-FPM (API) | ~0.8GB | max_children=10 |
| PHP-FPM (Admin) | ~0.3GB | max_children=5 |
| PHP-FPM (Sales) | ~0.2GB | max_children=3 |
| PHP-FPM (API-Stage) | ~0.2GB | max_children=3 |
| Next.js 운영 (PM2 cluster×2) | ~0.6GB | max-old-space-size=256 |
| Next.js Stage (PM2 fork×1) | ~0.15GB | max-old-space-size=128 |
| Supervisor (Queue Worker) | ~0.1GB | numprocs=2 |
| Nginx | ~0.1GB | worker_connections 1024 |
| node_exporter | ~10MB | - |
| OS + 여유 | ~2.9GB | 스왑 4GB |
### 방화벽 (UFW) 규칙
| 포트 | 프로토콜 | 허용 범위 | 용도 |
|------|----------|-----------|------|
| 22 | TCP | Anywhere | SSH |
| 80 | TCP | Anywhere | HTTP |
| 443 | TCP | Anywhere | HTTPS |
| 9100 | TCP | 110.10.147.46 only | node_exporter (Prometheus) |
| 3306 | TCP | 110.10.147.46 only | MySQL 백업 (CI/CD 서버) |
### 데이터베이스 사용자
| 사용자 | 인증 방식 | 권한 | 용도 |
|--------|-----------|------|------|
| codebridge@localhost | 비밀번호 | sam, sam_stage, sam_stat, codebridge | 애플리케이션 |
| hskwon@localhost | auth_socket | ALL (WITH GRANT OPTION) | 관리자 |
| root@localhost | auth_socket | ALL | 시스템 (sudo mysql) |
| sam_backup@110.10.147.46 | 비밀번호 | SELECT, LOCK TABLES (sam, sam_stat) | CI/CD 백업 |
---
## CI/CD 서버 (sam-cicd)
### 서버 사양
| 항목 | 값 |
|------|-----|
| IP | 110.10.147.46 |
| SSH 별칭 | sam-cicd |
| OS | Ubuntu 24.04.4 LTS |
| Kernel | 6.8.0-41-generic |
| CPU | 4 vCPU |
| RAM | 8GB (Swap 4GB) |
| Disk | 98GB (사용 15GB / 여유 79GB) |
| 사용자 | hskwon (SSH 키 인증, sudo NOPASSWD) |
### 도메인 매핑
| 도메인 | 서비스 | 백엔드 포트 | SSL |
|--------|--------|------------|-----|
| git.sam.it.kr | Gitea | :3000 | Let's Encrypt |
| ci.sam.it.kr | Jenkins | :8080 | Let's Encrypt |
| monitor.sam.it.kr | Grafana | :3100 | Let's Encrypt |
### 서비스 현황
| 서비스 | 버전 | 포트 | 도메인 |
|--------|------|------|--------|
| Nginx | 1.24.0 | 80/443 | 리버스 프록시 |
| Jenkins | LTS (2.541.2) | 8080 | ci.sam.it.kr |
| Gitea | 1.22.6 | 3000 | git.sam.it.kr |
| MySQL | 8.4.8 | 3306 | - |
| Prometheus | 2.51.0 | 9090 | - (localhost only) |
| Grafana | - | 3100 | monitor.sam.it.kr |
| node_exporter | 1.8.2 | 9100 | - |
| Java | OpenJDK 21.0.10 | - | Jenkins 런타임 |
| Certbot | - | - | SSL 자동 갱신 |
| fail2ban | - | - | SSH 보호 |
### 메모리 배분
| 서비스 | 할당 | 설정 |
|--------|------|------|
| Jenkins | ~2.0GB | -Xmx2048m |
| MySQL | ~1.5GB | innodb_buffer_pool_size=1536M |
| Gitea | ~0.5GB | Go 기반 |
| Prometheus | ~0.5GB | retention 30d |
| Grafana | ~0.3GB | - |
| Nginx | ~0.1GB | - |
| node_exporter | ~10MB | - |
| OS + 여유 | ~3.1GB | Swap 4GB |
### 주요 설정 파일
| 설정 | 경로 |
|------|------|
| Nginx 사이트 | /etc/nginx/sites-available/{ci,git,monitor}.sam.it.kr |
| Jenkins 홈 | /var/lib/jenkins/ |
| Jenkins JVM 설정 | /etc/systemd/system/jenkins.service.d/override.conf |
| Jenkins Agent | /var/lib/jenkins-agent/ (workspace, agent.jar) |
| Jenkins Agent 서비스 | /etc/systemd/system/jenkins-agent.service |
| Jenkins 환경파일 | /var/lib/jenkins/env-files/react/.env.{develop,stage,main} |
| Gitea 설정 | /etc/gitea/app.ini |
| Gitea 저장소 | /var/lib/gitea/data/repositories/ |
| Gitea 로그 | /var/lib/gitea/log/ |
| Prometheus 설정 | /etc/prometheus/prometheus.yml |
| Prometheus 데이터 | /var/lib/prometheus/ |
| Grafana 설정 | /etc/grafana/grafana.ini |
| MySQL 튜닝 | /etc/mysql/mysql.conf.d/sam-tuning.cnf |
| fail2ban 설정 | /etc/fail2ban/ |
| SSL 인증서 | /etc/letsencrypt/live/ |
| 백업 스크립트 | /home/hskwon/scripts/backup-db.sh |
| 백업 저장소 | /home/hskwon/backups/mysql/ |
### 방화벽 (UFW) 규칙
| 포트 | 프로토콜 | 용도 |
|------|---------|------|
| 22/tcp | ALLOW | SSH |
| 80/tcp | ALLOW | HTTP |
| 443/tcp | ALLOW | HTTPS |
---
## 개발서버 (sam-dev)
### 서버 사양
| 항목 | 값 |
|------|-----|
| IP | 114.203.209.83 |
| 호스트명 | sam-dev |
| OS | Ubuntu 24.04.2 LTS |
| 사용자 | hskwon (SSH 키 인증, sudo NOPASSWD) |
### 서비스 현황
| 서비스 | 포트 | 상태 |
|--------|------|------|
| Nginx | 80/443 | active |
| Apache | 8080 | active (레거시) |
| MySQL 8.4 | 3306 (localhost) | active |
| Gitea | 3000 | active |
| Next.js (PM2) | 3001 | active |
| fail2ban | - | active |
### 방화벽 (UFW) 규칙
| 포트 | 프로토콜 | 용도 |
|------|---------|------|
| 22/tcp | ALLOW | SSH |
| 80/tcp | ALLOW | HTTP |
| 443/tcp | ALLOW | HTTPS |
| 3000/tcp | ALLOW | Gitea |
> MySQL(3306), Apache(8080), Next.js(3001), CUPS(631) 등은 외부 차단
### 주요 디렉토리
```
/home/webservice/
react/ Next.js 프론트엔드
api/ Laravel API
mng/ Laravel Admin
sales/ Plain PHP 레거시
/data/GIT/samproject/ Gitea bare repositories
```
---
## 아키텍처 다이어그램
### 운영서버
```
┌──────────────────────────────────────────────────────────┐
│ 운영서버 (2 vCPU / 8GB) │
│ Ubuntu 24.04 / IP: 211.117.60.189 │
│ │
│ ┌──────────┐ ┌───────────┐ ┌───────────────────────┐ │
│ │ Nginx │ │ Certbot │ │ UFW (22,80,443,9100) │ │
│ └────┬─────┘ └───────────┘ └───────────────────────┘ │
│ │ │
│ ┌────┴───────────────────────────────────────────────┐ │
│ │ sam.it.kr ──────────→ Next.js (PM2 cluster, :3000)│ │
│ │ api.sam.it.kr ──────→ PHP-FPM (api pool) │ │
│ │ mng.codebridge-x.com ──→ PHP-FPM (admin pool) │ │
│ │ sales.codebridge-x.com → PHP-FPM (sales pool) │ │
│ │ stage.sam.it.kr ────→ Next.js (PM2 fork, :3100) │ │
│ │ stage-api.sam.it.kr → PHP-FPM (api-stage pool) │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ┌────────────┐ ┌────────────┐ ┌─────────────────┐ │
│ │ MySQL 8.4 │ │ Redis │ │ Supervisor │ │
│ │ (Master) │ │ (캐시/큐) │ │ (Queue Worker) │ │
│ └────────────┘ └────────────┘ └─────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ node_exporter (:9100) → CI/CD Prometheus │ │
│ └─────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────────┘
```
### CI/CD 서버
```
┌──────────────────────────────────────────────────────────┐
│ CI/CD서버 (2 vCPU / 8GB) │
│ Ubuntu 24.04 / IP: 110.10.147.46 │
│ │
│ ┌──────────┐ ┌───────────┐ ┌───────────────────────┐ │
│ │ Nginx │ │ Certbot │ │ UFW (22,80,443) │ │
│ └────┬─────┘ └───────────┘ └───────────────────────┘ │
│ │ │
│ ┌────┴───────────────────────────────────────────────┐ │
│ │ git.sam.it.kr ──────────→ Gitea (:3000) │ │
│ │ ci.sam.it.kr ───────────→ Jenkins (:8080) │ │
│ │ monitor.sam.it.kr ──────→ Grafana (:3100) │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ┌────────────┐ ┌────────────┐ ┌────────────────────┐ │
│ │ Gitea │ │ Jenkins │ │ MySQL 8.4 │ │
│ │ (운영 Git) │ │ (CI/CD) │ │ (Gitea DB + 백업) │ │
│ └────────────┘ └────────────┘ └────────────────────┘ │
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ Prometheus │ │ Grafana │ │
│ │ (:9090) │ │ (:3100) │ │
│ └──────────────┘ └──────────────┘ │
└──────────────────────────────────────────────────────────┘
```
### 도메인 환경 분리
| 서비스 | 운영 | Stage | 개발 |
|--------|------|-------|------|
| Front | sam.it.kr | stage.sam.it.kr | dev.codebridge-x.com |
| API | api.sam.it.kr | stage-api.sam.it.kr | api.codebridge-x.com |
| Admin | mng.codebridge-x.com | - | admin.codebridge-x.com |
| Sales | sales.codebridge-x.com | - | salesdev.codebridge-x.com |
| Landing | codebridge-x.com | - | - |
### 타이틀 접두사 (환경 구분)
브라우저 탭에서 환경을 즉시 구분할 수 있도록 타이틀에 접두사를 표시한다.
| 환경 | 접두사 | 예시 |
|------|--------|------|
| 로컬 | `[L]` | `[L]SAM_MNG` |
| 개발 | `[D]` | `[D]SAM_SYSTEM` |
| 운영 | 없음 | `SAM_SYSTEM` |
**설정 위치:**
| 프로젝트 | 방식 | 설정 파일 |
|---------|------|----------|
| mng | `.env``APP_NAME`에 접두사 포함 | 로컬: `mng/.env`, 개발: `/home/webservice/mng/.env` |
| api | `.env``APP_NAME`에 접두사 포함 | 로컬: `api/.env`, 개발: `/home/webservice/api/.env` |
| react | 코드에서 `NEXT_PUBLIC_APP_ENV` 값으로 자동 판별 | CI/CD: `/var/lib/jenkins/env-files/react/.env.develop` |