Files
sam-docs/dev/deploys/ops-manual/04-service-cicd.md
권혁성 db63fcff85 refactor: [docs] 팀별 폴더 구조 재편 (공유/개발/프론트/기획)
- 개발팀 전용 폴더 dev/ 생성 (standards, guides, quickstart, changes, deploys, data, history, dev_plans 이동)
- 프론트엔드 전용 폴더 frontend/ 생성 (api/ → frontend/api-specs/)
- 기획팀 폴더 requests/ 생성
- plans/ → dev/dev_plans/ 이름 변경
- README.md 신규 (사람용 안내), INDEX.md 재작성 (Claude Code용)
- resources.md 신규 (노션 링크용, assets/brochure 이관 예정)
- CURRENT_WORKS.md 삭제, TODO.md → dev/ 이동
- 전체 참조 경로 업데이트

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 16:46:03 +09:00

363 lines
8.7 KiB
Markdown

# 4. CI/CD 서비스 관리
[목차로 돌아가기](./README.md) | 서버: sam-cicd (110.10.147.46)
---
## Jenkins
**서비스 제어:**
```bash
sudo systemctl start jenkins
sudo systemctl stop jenkins
sudo systemctl restart jenkins
sudo systemctl status jenkins
```
**설정 파일:**
| 파일 | 용도 |
|------|------|
| /var/lib/jenkins/ | Jenkins 홈 (jobs, plugins, credentials) |
| /etc/systemd/system/jenkins.service.d/override.conf | JVM 메모리 설정 |
| /var/lib/jenkins/env-files/ | 배포 환경변수 (.env 파일) |
| /var/lib/jenkins-agent/ | Agent 워크스페이스 (빌드 실행 격리) |
| /etc/systemd/system/jenkins-agent.service | Agent systemd 서비스 |
**JVM 메모리 설정:**
```bash
# /etc/systemd/system/jenkins.service.d/override.conf
# Environment="JAVA_OPTS=-Xmx2048m -Xms512m -Djava.awt.headless=true"
# 변경 후 적용
sudo systemctl daemon-reload
sudo systemctl restart jenkins
```
**로그:**
```bash
sudo journalctl -u jenkins -f
sudo journalctl -u jenkins --since "2 hours ago" --no-pager
```
**웹 UI:** https://ci.sam.it.kr (관리자: hskwon)
### Credential 관리
| Credential ID | 유형 | 용도 |
|--------------|------|------|
| deploy-ssh-key | SSH Username with private key | 운영/개발서버 SSH 배포 |
| gitea-api-token | Username with password | Gitea API 연동 (token을 username, 비밀번호 빈값) |
**Credential 위치:** Jenkins 관리 > Credentials > System > Global credentials
**SSH 키 경로:** /var/lib/jenkins/.ssh/id_ed25519
**환경변수 파일:**
```
/var/lib/jenkins/env-files/
react/
.env.develop # 개발서버용
.env.stage # Stage용
.env.main # 운영용
```
### 설치된 주요 플러그인
- Gitea Plugin -- Gitea Webhook 연동
- SSH Agent Plugin -- SSH 키 기반 배포
- Pipeline / Workflow Aggregator -- Jenkinsfile 지원
- Pipeline Stage View -- 파이프라인 시각화
- Blue Ocean -- 모던 UI
- NodeJS Plugin -- Node.js 도구 관리 (22.22.0)
플러그인 업데이트 후 Jenkins 재시작이 필요한 경우: `sudo systemctl restart jenkins`
### Build Agent (분산 빌드)
Built-in Node의 executor는 0으로 설정되어 있으며, 빌드는 로컬 Agent(`local-agent`)에서 실행된다.
| 항목 | 값 |
|------|-----|
| Agent 이름 | local-agent |
| Workspace | /var/lib/jenkins-agent/ |
| Executor 수 | 2 |
| 라벨 | build |
| 연결 방식 | WebSocket (Inbound) |
**서비스 제어:**
```bash
sudo systemctl start jenkins-agent
sudo systemctl stop jenkins-agent
sudo systemctl restart jenkins-agent
sudo systemctl status jenkins-agent
# Agent 로그
sudo journalctl -u jenkins-agent -f
```
> **참고**: Jenkins 마스터 재시작 시 Agent가 자동 재연결된다. Agent가 연결 실패하면 `sudo systemctl restart jenkins-agent`로 수동 재시작.
### Workspace 정리
```bash
# Agent workspace 용량 확인
sudo du -sh /var/lib/jenkins-agent/workspace/*
# 특정 workspace 삭제
sudo rm -rf /var/lib/jenkins-agent/workspace/<JOB_NAME>
# 전체 workspace 정리 (빌드 중이 아닌지 확인 후)
sudo rm -rf /var/lib/jenkins-agent/workspace/*
# 레거시 Built-in workspace (이전 빌드 잔존 시)
sudo du -sh /var/lib/jenkins/workspace/*
sudo rm -rf /var/lib/jenkins/workspace/*
# 임시 파일 정리
sudo find /tmp -name "jenkins*" -mtime +7 -delete
```
---
## Gitea
**서비스 제어:**
```bash
sudo systemctl start gitea
sudo systemctl stop gitea
sudo systemctl restart gitea
sudo systemctl status gitea
```
**설정 파일:**
| 파일 | 용도 |
|------|------|
| /etc/gitea/app.ini | 메인 설정 |
| /var/lib/gitea/data/repositories/ | Git 저장소 데이터 |
| /var/lib/gitea/log/ | Gitea 로그 |
| /var/lib/gitea/custom/ | 커스텀 설정 |
**주요 설정 (app.ini):**
```ini
[server]
DOMAIN = git.sam.it.kr
HTTP_PORT = 3000
ROOT_URL = https://git.sam.it.kr/
[service]
DISABLE_REGISTRATION = true # 회원가입 비활성화
REQUIRE_SIGNIN_VIEW = true # 로그인 필수
```
**로그:**
```bash
sudo journalctl -u gitea -f
sudo tail -f /var/lib/gitea/log/gitea.log
```
**웹 UI:** https://git.sam.it.kr (관리자: hskwon)
### 저장소 현황
| Organization | 저장소 | 설명 |
|-------------|--------|------|
| SamProject | sam-api | Laravel REST API |
| SamProject | sam-manage | Laravel Admin (mng) |
| SamProject | sam-react-prod | Next.js 프론트엔드 |
| SamProject | sam-sales | 영업자 사이트 (레거시) |
### 사용자/조직 관리
- 사이트 관리: https://git.sam.it.kr/-/admin
- 사용자 관리: https://git.sam.it.kr/-/admin/users
- 조직 관리: https://git.sam.it.kr/-/admin/orgs
**CLI로 사용자 추가:**
```bash
sudo -u git /usr/local/bin/gitea admin user create \
--config /etc/gitea/app.ini \
--username 사용자명 \
--password 비밀번호 \
--email 이메일 \
--admin # 관리자 권한 (선택)
```
### Webhook 설정
각 저장소에 Jenkins Webhook이 설정되어 있다.
| 항목 | 값 |
|------|-----|
| URL | https://ci.sam.it.kr/gitea-webhook/post |
| Content Type | application/json |
| Events | Push Events |
**Webhook 확인/테스트:** 저장소 > Settings > Webhooks
### 개발서버 동기화 (post-receive hook)
개발서버 Gitea에서 CI/CD Gitea로 자동 동기화:
**Hook 위치 (개발서버):** `/data/GIT/samproject/<repo>.git/hooks/post-receive.d/push-to-cicd`
**토큰 파일 (개발서버):** `/data/GIT/.cicd-env` (chmod 600, owner: git)
| 저장소 | 동기화 브랜치 | 비고 |
|--------|-------------|------|
| sam-react-prod | main, develop | post-update hook 비활성화 (CI/CD가 개발서버 배포 담당) |
| sam-api | main | develop은 기존 post-update hook 유지 |
| sam-sales | main | |
| sam-manage | main | 2026-02-24 hook 추가 |
> **참고:** react의 개발서버 배포는 Jenkins CI/CD 파이프라인이 처리한다.
> 기존 post-update hook의 git pull 방식(`pull_react.sh`)은 비활성화됨 (2026-02-24).
> 스크립트 위치: `/home/webservice/script/pull_react.sh`
**동기화 로그 확인:**
```bash
ssh sam-dev "tail -20 /home/webservice/logs/cicd_push_react-prod.log"
ssh sam-dev "tail -20 /home/webservice/logs/cicd_push_api.log"
ssh sam-dev "tail -20 /home/webservice/logs/cicd_push_sales.log"
ssh sam-dev "tail -20 /home/webservice/logs/cicd_push_manage.log"
```
---
## Prometheus
**서비스 제어:**
```bash
sudo systemctl start prometheus
sudo systemctl stop prometheus
sudo systemctl restart prometheus
sudo systemctl status prometheus
```
**설정 파일:**
| 파일 | 용도 |
|------|------|
| /etc/prometheus/prometheus.yml | 스크래핑 설정 |
| /var/lib/prometheus/ | 시계열 데이터 |
**바인딩:** 127.0.0.1:9090 (외부 접근 차단)
**데이터 보존:** 30일 (--storage.tsdb.retention.time=30d)
**설정 변경 후 적용:**
```bash
promtool check config /etc/prometheus/prometheus.yml # 문법 검사
sudo systemctl restart prometheus
# 또는 설정 리로드 (재시작 없이)
curl -X POST http://localhost:9090/-/reload
```
---
## Grafana
**서비스 제어:**
```bash
sudo systemctl start grafana-server
sudo systemctl stop grafana-server
sudo systemctl restart grafana-server
sudo systemctl status grafana-server
```
**설정 파일:**
| 파일 | 용도 |
|------|------|
| /etc/grafana/grafana.ini | 메인 설정 |
| /var/lib/grafana/ | 대시보드 데이터, 플러그인 |
**주요 설정:**
```ini
[server]
http_port = 3100
domain = monitor.sam.it.kr
[users]
allow_sign_up = false
```
**웹 UI:** https://monitor.sam.it.kr
---
## MySQL (CI/CD)
```bash
sudo systemctl status mysql
sudo systemctl restart mysql
# 접속
mysql # hskwon (auth_socket)
sudo mysql # root (auth_socket)
```
**주요 튜닝 설정:**
```ini
innodb_buffer_pool_size = 1536M
max_connections = 50
slow_query_log = 1
long_query_time = 2
```
**데이터베이스:** gitea (Gitea 데이터)
---
## Nginx (CI/CD)
```bash
sudo nginx -t && sudo systemctl reload nginx # 무중단 리로드
sudo systemctl restart nginx
sudo systemctl status nginx
```
**사이트 설정:**
| 파일 | 서비스 |
|------|--------|
| /etc/nginx/sites-available/git.sam.it.kr | Gitea 리버스 프록시 |
| /etc/nginx/sites-available/ci.sam.it.kr | Jenkins 리버스 프록시 |
| /etc/nginx/sites-available/monitor.sam.it.kr | Grafana 리버스 프록시 |
**git.sam.it.kr 주요 설정:**
```nginx
client_max_body_size 500M; # 대용량 Git push 허용
proxy_request_buffering off; # 스트리밍 전송 (413 방지)
```
---
## node_exporter / Certbot / fail2ban / UFW
운영서버와 동일한 명령어 체계. [운영서버 서비스 관리](./03-service-prod.md) 참조.
**UFW 규칙 (CI/CD):**
| 포트 | 프로토콜 | 용도 |
|------|---------|------|
| 22/tcp | ALLOW | SSH |
| 80/tcp | ALLOW | HTTP |
| 443/tcp | ALLOW | HTTPS |