- Path-based 라우팅을 서브도메인 기반으로 전환 (tkfb/tkreport/tkqc.technicalkorea.net) - 3개 시스템 프론트엔드에 SSO 쿠키 인증 통합 (domain=.technicalkorea.net, localStorage 폴백) - Gateway: 포털+로그인+System1 프록시, 쿠키 SSO 설정 - System 1: 토큰키 통일, nginx.conf 생성, 신고페이지 리다이렉트 - System 2: api-base.js/app-init.js 생성, getSSOToken() 통합 - System 3: TokenManager 쿠키 지원, 중앙 로그인 리다이렉트 - docker-compose.yml에 cloudflared 서비스 추가 - DEPLOY-GUIDE.md 배포 가이드 작성 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
253 lines
8.1 KiB
Markdown
253 lines
8.1 KiB
Markdown
# TK Factory Services - NAS 배포 가이드
|
|
|
|
> 최종 업데이트: 2026-02-09
|
|
|
|
## 아키텍처 개요
|
|
|
|
```
|
|
Cloudflare Tunnel
|
|
|
|
|
+--------------+--------------+
|
|
| | |
|
|
tkfb.techni.. tkreport.techni.. tkqc.techni..
|
|
| | |
|
|
tk-gateway:80 tk-system2-web:80 tk-system3-web:80
|
|
(포털+S1) (S2 신고) (S3 부적합)
|
|
| | |
|
|
system1-api:3005 system2-api:3005 system3-api:8000
|
|
| | |
|
|
+--- MariaDB --+ PostgreSQL
|
|
(공유)
|
|
```
|
|
|
|
### 서브도메인 라우팅
|
|
|
|
| 서브도메인 | Cloudflare Tunnel 대상 | 역할 |
|
|
|-----------|----------------------|------|
|
|
| `tkfb.technicalkorea.net` | `http://tk-gateway:80` | 통합 포털 + System 1 (공장관리) |
|
|
| `tkreport.technicalkorea.net` | `http://tk-system2-web:80` | System 2 (신고) |
|
|
| `tkqc.technicalkorea.net` | `http://tk-system3-web:80` | System 3 (부적합관리) |
|
|
|
|
### SSO 인증 방식
|
|
|
|
- 로그인: `tkfb.technicalkorea.net/login`에서 통합 로그인
|
|
- 토큰 저장: 쿠키 (`domain=.technicalkorea.net`, 7일 만료) + localStorage 이중 저장
|
|
- 시스템 간 이동: 쿠키가 서브도메인 간 자동 공유되므로 재로그인 불필요
|
|
|
|
### Docker 서비스 (13개)
|
|
|
|
| 서비스 | 컨테이너명 | 포트 |
|
|
|--------|-----------|------|
|
|
| MariaDB | tk-mariadb | 30306:3306 |
|
|
| PostgreSQL | tk-postgres | 30432:5432 |
|
|
| Redis | tk-redis | - |
|
|
| SSO Auth | tk-sso-auth | 30050:3000 |
|
|
| System 1 API | tk-system1-api | 30005:3005 |
|
|
| System 1 Web | tk-system1-web | 30080:80 |
|
|
| System 1 FastAPI | tk-system1-fastapi | 30008:8000 |
|
|
| System 2 API | tk-system2-api | 30105:3005 |
|
|
| System 2 Web | tk-system2-web | 30180:80 |
|
|
| System 3 API | tk-system3-api | 30200:8000 |
|
|
| System 3 Web | tk-system3-web | 30280:80 |
|
|
| phpMyAdmin | tk-phpmyadmin | 30880:80 |
|
|
| Cloudflared | tk-cloudflared | - |
|
|
| Gateway | tk-gateway | 30000:80 |
|
|
|
|
---
|
|
|
|
## 배포 전 준비 (로컬)
|
|
|
|
### 1. .env 파일 생성
|
|
|
|
```bash
|
|
cp .env.example .env
|
|
vi .env
|
|
```
|
|
|
|
필수 설정값:
|
|
|
|
```
|
|
# NAS 기존 TK-FB의 DB 패스워드와 동일하게 설정
|
|
MYSQL_ROOT_PASSWORD=<기존 tkfb_db root 패스워드>
|
|
MYSQL_PASSWORD=<기존 tkfb_db hyungi_user 패스워드>
|
|
|
|
# 새로 생성할 SSO 시크릿 (32자 이상 랜덤 문자열)
|
|
SSO_JWT_SECRET=<openssl rand -hex 32 로 생성>
|
|
SSO_JWT_REFRESH_SECRET=<openssl rand -hex 32 로 생성>
|
|
|
|
# NAS 기존 TKQC의 DB 패스워드와 동일하게 설정
|
|
POSTGRES_PASSWORD=<기존 tkqc-db mproject 패스워드>
|
|
|
|
# System 3 관리자 (기존 TKQC 관리자)
|
|
SYSTEM3_ADMIN_USERNAME=hyungi
|
|
SYSTEM3_ADMIN_PASSWORD=<기존 TKQC 관리자 비밀번호>
|
|
|
|
# Cloudflare Tunnel 토큰
|
|
CLOUDFLARE_TUNNEL_TOKEN=<Cloudflare Zero Trust 대시보드에서 확인>
|
|
```
|
|
|
|
기존 패스워드 확인 방법 (NAS SSH):
|
|
```bash
|
|
# TK-FB MariaDB 패스워드
|
|
cat "/volume1/Technicalkorea Document/tkfb-package/.env" | grep MYSQL
|
|
|
|
# TKQC PostgreSQL 패스워드
|
|
cat /volume1/docker/tkqc/tkqc-package/.env | grep POSTGRES
|
|
|
|
# Cloudflare Tunnel 토큰
|
|
echo 'fukdon-riwbaq-fiQfy2' | sudo -S /usr/local/bin/docker inspect tkfb_cloudflared | grep TUNNEL_TOKEN
|
|
```
|
|
|
|
---
|
|
|
|
## NAS 배포 절차
|
|
|
|
### Step 1: 기존 서비스 백업
|
|
|
|
```bash
|
|
# NAS SSH 접속
|
|
ssh hyungi@192.168.0.3
|
|
|
|
# 백업 디렉토리 생성
|
|
mkdir -p /volume1/docker/backups/$(date +%Y%m%d)
|
|
|
|
# MariaDB 백업
|
|
echo 'fukdon-riwbaq-fiQfy2' | sudo -S /usr/local/bin/docker exec tkfb_db \
|
|
mysqldump -u root -p<ROOT_PASSWORD> --all-databases > \
|
|
/volume1/docker/backups/$(date +%Y%m%d)/mariadb-all.sql
|
|
|
|
# PostgreSQL 백업
|
|
echo 'fukdon-riwbaq-fiQfy2' | sudo -S /usr/local/bin/docker exec tkqc-db \
|
|
pg_dumpall -U mproject > \
|
|
/volume1/docker/backups/$(date +%Y%m%d)/postgres-all.sql
|
|
|
|
# uploads 백업
|
|
cp -r "/volume1/Technicalkorea Document/tkfb-package/uploads" \
|
|
/volume1/docker/backups/$(date +%Y%m%d)/tkfb-uploads
|
|
cp -r /volume1/docker/tkqc/tkqc-package/uploads \
|
|
/volume1/docker/backups/$(date +%Y%m%d)/tkqc-uploads
|
|
```
|
|
|
|
### Step 2: 프로젝트 NAS 전송
|
|
|
|
```bash
|
|
# 로컬 Mac에서 실행
|
|
# node_modules 제외하여 전송
|
|
rsync -avz --exclude='node_modules' --exclude='.env' --exclude='__pycache__' \
|
|
-e ssh /Users/hyungiahn/Documents/code/tk-factory-services/ \
|
|
hyungi@192.168.0.3:/volume1/docker/tk-factory-services/
|
|
|
|
# .env 파일 별도 전송
|
|
scp -O /Users/hyungiahn/Documents/code/tk-factory-services/.env \
|
|
hyungi@192.168.0.3:/volume1/docker/tk-factory-services/.env
|
|
```
|
|
|
|
> **참고**: Synology에서 `scp`는 `-O` 옵션 필수 (레거시 프로토콜)
|
|
|
|
### Step 3: 기존 서비스 중지
|
|
|
|
```bash
|
|
# NAS SSH
|
|
# TK-FB 중지
|
|
cd "/volume1/Technicalkorea Document/tkfb-package"
|
|
echo 'fukdon-riwbaq-fiQfy2' | sudo -S /usr/local/bin/docker compose down
|
|
|
|
# TKQC 중지
|
|
cd /volume1/docker/tkqc/tkqc-package
|
|
echo 'fukdon-riwbaq-fiQfy2' | sudo -S /usr/local/bin/docker compose down
|
|
```
|
|
|
|
### Step 4: 통합 서비스 기동
|
|
|
|
```bash
|
|
cd /volume1/docker/tk-factory-services
|
|
|
|
# Docker 이미지 빌드 + 서비스 기동
|
|
echo 'fukdon-riwbaq-fiQfy2' | sudo -S /usr/local/bin/docker compose up --build -d
|
|
|
|
# 로그 확인
|
|
echo 'fukdon-riwbaq-fiQfy2' | sudo -S /usr/local/bin/docker compose logs -f --tail=50
|
|
```
|
|
|
|
### Step 5: DB 마이그레이션
|
|
|
|
```bash
|
|
# SSO 유저 테이블은 docker-compose.yml에 의해 자동 실행됨
|
|
# (scripts/migrate-users.sql → MariaDB init)
|
|
|
|
# PostgreSQL 마이그레이션도 자동 실행됨
|
|
# (system3-nonconformance/api/migrations/ → PostgreSQL init)
|
|
|
|
# 헬스체크 확인
|
|
echo 'fukdon-riwbaq-fiQfy2' | sudo -S /usr/local/bin/docker compose ps
|
|
```
|
|
|
|
### Step 6: Cloudflare Tunnel 설정
|
|
|
|
Cloudflare Zero Trust 대시보드 (`https://one.dash.cloudflare.com/`)에서:
|
|
|
|
1. **Networks → Tunnels** → 기존 터널 선택
|
|
2. **Public Hostname** 탭에서 3개 서브도메인 설정:
|
|
|
|
| Subdomain | Domain | Service |
|
|
|-----------|--------|---------|
|
|
| tkfb | technicalkorea.net | `http://tk-gateway:80` |
|
|
| tkreport | technicalkorea.net | `http://tk-system2-web:80` |
|
|
| tkqc | technicalkorea.net | `http://tk-system3-web:80` |
|
|
|
|
> 기존 `tkfb.technicalkorea.net`과 `tkqc.technicalkorea.net`은 대상 서비스만 변경
|
|
|
|
### Step 7: 테스트
|
|
|
|
```bash
|
|
# 1. 헬스체크
|
|
curl -s http://localhost:30005/api/health # System 1 API
|
|
curl -s http://localhost:30105/api/health # System 2 API
|
|
curl -s http://localhost:30200/api/health # System 3 API
|
|
curl -s http://localhost:30050/api/health # SSO Auth
|
|
|
|
# 2. 웹 접속 테스트 (브라우저)
|
|
# - https://tkfb.technicalkorea.net/ → 포털 표시
|
|
# - https://tkfb.technicalkorea.net/login → 로그인 페이지
|
|
# - 로그인 후 → 대시보드 이동
|
|
# - https://tkreport.technicalkorea.net/ → System 2 (재로그인 없이)
|
|
# - https://tkqc.technicalkorea.net/ → System 3 (재로그인 없이)
|
|
|
|
# 3. SSO 쿠키 확인 (브라우저 개발자 도구)
|
|
# - Application → Cookies에서 sso_token, sso_user 확인
|
|
# - domain이 .technicalkorea.net인지 확인
|
|
```
|
|
|
|
---
|
|
|
|
## 롤백 방법
|
|
|
|
문제 발생 시 기존 서비스로 복원:
|
|
|
|
```bash
|
|
# 통합 서비스 중지
|
|
cd /volume1/docker/tk-factory-services
|
|
echo 'fukdon-riwbaq-fiQfy2' | sudo -S /usr/local/bin/docker compose down
|
|
|
|
# TK-FB 복원
|
|
cd "/volume1/Technicalkorea Document/tkfb-package"
|
|
echo 'fukdon-riwbaq-fiQfy2' | sudo -S /usr/local/bin/docker compose up -d
|
|
|
|
# TKQC 복원
|
|
cd /volume1/docker/tkqc/tkqc-package
|
|
echo 'fukdon-riwbaq-fiQfy2' | sudo -S /usr/local/bin/docker compose up -d
|
|
```
|
|
|
|
---
|
|
|
|
## 트러블슈팅
|
|
|
|
| 증상 | 원인 | 해결 |
|
|
|------|------|------|
|
|
| 403 Forbidden (nginx) | Docker 내부 IP 차단 | nginx.conf에 `allow 172.16.0.0/12` 추가 |
|
|
| SSO 로그인 후 다른 시스템에서 미인증 | 쿠키 domain 설정 오류 | 브라우저 쿠키에서 domain이 `.technicalkorea.net`인지 확인 |
|
|
| DB 연결 실패 | 패스워드 불일치 | `.env`의 DB 패스워드가 기존과 동일한지 확인 |
|
|
| Cloudflare 502 | 컨테이너 미기동 | `docker compose ps`로 상태 확인, `docker compose logs <서비스>` |
|
|
| SCP 실패 | Synology subsystem | `scp -O` 옵션 사용 |
|
|
| sudo 파이프 실패 | Synology 제한 | `echo 'password' \| sudo -S` 패턴 사용 |
|