Compare commits

..

2 Commits

Author SHA1 Message Date
qorgh529
72689d8647 docs: 2026-05 허브 홈페이지 구축 및 URL 구조 개편 내용 추가
Some checks failed
Build and Push Images / build-backend (push) Has been cancelled
2026-06-10 18:15:14 +09:00
qorgh529
c092efe160 docs: GitHub 포트폴리오용 README 작성 2026-04-28 19:55:32 +09:00

157
README.md
View File

@@ -12,17 +12,21 @@
``` ```
사용자 (외부 인터넷) 사용자 (외부 인터넷)
├── https://cyanburu.com → Web Portal ├── https://cyanburu.com → Hub 홈페이지 (포트폴리오/서비스 허브)
├── https://gitea.cyanburu.com → Gitea ├── https://cyanburu.com/portal → Web Portal
── https://argo.cyanburu.com → ArgoCD ── https://cyanburu.com/kingscup → King's Cup 게임 (개발 예정)
├── https://gitea.cyanburu.com → Gitea
└── https://argo.cyanburu.com → ArgoCD
MSI 라우터 (포트포워딩 80/443) MSI 라우터 (포트포워딩 80/443)
Nginx Ingress Controller ← TLS 종료, 도메인별 라우팅 Nginx Ingress Controller ← TLS 종료, 도메인/경로별 라우팅
cert-manager ← Let's Encrypt 인증서 자동 발급/갱신 cert-manager ← Let's Encrypt 인증서 자동 발급/갱신
Kubernetes 네임스페이스별 서비스 Kubernetes 네임스페이스별 서비스
├── hub
│ └── Nginx (정적 HTML) ← cyanburu.com/ 허브 홈페이지
├── web-portal ├── web-portal
│ ├── Nginx Frontend (ClusterIP: 80) │ ├── Nginx Frontend (ClusterIP: 80)
│ ├── FastAPI Backend (ClusterIP: 8000) │ ├── FastAPI Backend (ClusterIP: 8000)
@@ -46,6 +50,7 @@ Gitea → ArgoCD 자동 감지 & 배포
| Frontend | Nginx + HTML/CSS/JS (SPA) | | Frontend | Nginx + HTML/CSS/JS (SPA) |
| Backend | Python FastAPI | | Backend | Python FastAPI |
| Database | PostgreSQL | | Database | PostgreSQL |
| Cache | Redis (King's Cup 세션) |
| Container | Docker Desktop | | Container | Docker Desktop |
| Orchestration | Kubernetes (Docker Desktop 내장) | | Orchestration | Kubernetes (Docker Desktop 내장) |
| GitOps | Gitea + ArgoCD | | GitOps | Gitea + ArgoCD |
@@ -70,22 +75,27 @@ nginx-portal/
│ └── Dockerfile │ └── Dockerfile
├── frontend/ ├── frontend/
│ ├── index.html # 싱글 페이지 앱 (SPA) │ ├── index.html # 싱글 페이지 앱 (SPA)
│ ├── nginx.conf # Nginx 설정 + /api/* 프록시 │ ├── nginx.conf # Nginx 설정 + /api/* 프록시 (/portal subpath 대응)
│ └── Dockerfile
├── hub/ # 허브 홈페이지 (cyanburu.com/)
│ ├── index.html # 포트폴리오/서비스 허브 정적 페이지
│ └── Dockerfile │ └── Dockerfile
├── k8s/ ├── k8s/
│ ├── 00-hub.yaml # hub 네임스페이스 + Deployment + Service
│ ├── 01-namespace.yaml # web-portal 네임스페이스 │ ├── 01-namespace.yaml # web-portal 네임스페이스
│ ├── 02-postgres.yaml # PostgreSQL + PVC + Service │ ├── 02-postgres.yaml # PostgreSQL + PVC + Service
│ ├── 03-secrets.yaml # DB/JWT 시크릿 │ ├── 03-secrets.yaml # DB/JWT 시크릿
│ ├── 04-backend.yaml # FastAPI Deployment + Service │ ├── 04-backend.yaml # FastAPI Deployment + Service
── 05-frontend.yaml # Nginx Deployment + NodePort(30090) ── 05-frontend.yaml # Nginx Deployment + NodePort(30090)
│ ├── 07-clusterissuer.yaml # Let's Encrypt ClusterIssuer
│ ├── 08-ingress.yaml # Web Portal Ingress (cyanburu.com/portal)
│ ├── 09-ingress-gitea.yaml # Gitea Ingress (gitea.cyanburu.com)
│ ├── 10-ingress-argocd.yaml # ArgoCD Ingress (argo.cyanburu.com)
│ ├── 11-notify-secrets.yaml # Discord Webhook / Gmail Secret
│ ├── 12-???.yaml # 기존 파일
│ └── 13-ingress-hub.yaml # Hub Ingress (cyanburu.com/)
├── 06-argocd-app.yaml # ArgoCD Application 정의 (k8s 폴더 밖에 위치) ├── 06-argocd-app.yaml # ArgoCD Application 정의 (k8s 폴더 밖에 위치)
└── README.md └── README.md
k8s/ 폴더 내 추가 파일:
├── 07-clusterissuer.yaml # Let's Encrypt ClusterIssuer
├── 08-ingress.yaml # Web Portal Ingress (cyanburu.com)
├── 09-ingress-gitea.yaml # Gitea Ingress (gitea.cyanburu.com)
└── 10-ingress-argocd.yaml # ArgoCD Ingress (argo.cyanburu.com)
``` ```
> ⚠️ `06-argocd-app.yaml` 은 반드시 `k8s/` 폴더 **밖**에 위치해야 합니다. > ⚠️ `06-argocd-app.yaml` 은 반드시 `k8s/` 폴더 **밖**에 위치해야 합니다.
@@ -126,6 +136,7 @@ k8s/ 폴더 내 추가 파일:
- **계정 잠금 해제**: 잠긴 계정을 버튼 하나로 해제 - **계정 잠금 해제**: 잠긴 계정을 버튼 하나로 해제
- **사용자 상태 확인**: 정상 / 🔒잠김 / 초기PW / 변경요청 태그로 한눈에 확인 - **사용자 상태 확인**: 정상 / 🔒잠김 / 초기PW / 변경요청 태그로 한눈에 확인
- **공지사항 작성**: 공지 탭에서 전체 사용자에게 공지 등록 / 삭제 - **공지사항 작성**: 공지 탭에서 전체 사용자에게 공지 등록 / 삭제
- **🏠 홈 카드 관리**: `cyanburu.com` 메인 허브 홈페이지에 표시될 카드 추가 / 수정 / 삭제 / 순서 변경
### 게시판 (공지 / 관리자 요청) ### 게시판 (공지 / 관리자 요청)
@@ -273,10 +284,32 @@ kubectl get certificate -n argocd
| 서비스 | URL | | 서비스 | URL |
|--------|-----| |--------|-----|
| Web Portal | `https://cyanburu.com` | | Hub 홈페이지 | `https://cyanburu.com` |
| Web Portal | `https://cyanburu.com/portal` |
| Gitea | `https://gitea.cyanburu.com` | | Gitea | `https://gitea.cyanburu.com` |
| ArgoCD | `https://argo.cyanburu.com` | | ArgoCD | `https://argo.cyanburu.com` |
### 14단계. Hub 홈페이지 배포 (최초 1회)
```bash
# hub 네임스페이스 생성
kubectl create namespace hub
# Registry Secret 생성
kubectl create secret docker-registry gitea-registry-secret \
--namespace=hub \
--docker-server=192.168.10.101:30000 \
--docker-username=<계정> \
--docker-password=<패스워드>
# 이미지 빌드 & Push
docker build -t 192.168.10.101:30000/<계정>/hub:latest ./hub/
docker push 192.168.10.101:30000/<계정>/hub:latest
# 배포
kubectl apply -f k8s/00-hub.yaml
kubectl apply -f k8s/13-ingress-hub.yaml
```
--- ---
## 🔄 이후 배포 방법 (코드 수정 시) ## 🔄 이후 배포 방법 (코드 수정 시)
@@ -822,3 +855,101 @@ backend/
frontend/ frontend/
└── index.html ← 🔔 알림 설정 탭 추가 (좌측 폼 + 우측 리스트 UI) └── index.html ← 🔔 알림 설정 탭 추가 (좌측 폼 + 우측 리스트 UI)
``` ```
---
### 2026-05-19 (허브 홈페이지 구축 + URL 구조 개편)
#### URL 구조 변경
| 변경 전 | 변경 후 | 내용 |
|---------|---------|------|
| `cyanburu.com/` | `cyanburu.com/portal` | 기존 웹 포털 경로 변경 |
| — | `cyanburu.com/` | 신규 허브 홈페이지 (루트) |
| — | `cyanburu.com/kingscup` | 킹컵 게임 (개발 예정) |
#### 기능 추가
**허브 홈페이지 (`cyanburu.com/`)**
- 포트폴리오 겸 서비스 허브 페이지 신규 구축
- 에디토리얼 매거진 + 사이버펑크 믹스 디자인
- `Cormorant Garamond` 세리프 폰트 + 크림 배경 (에디토리얼)
- 배경 격자 그리드, 민트 네온 호버 효과 (사이버펑크)
- 터미널 스타일 클러스터 상태 표시 + 실시간 업타임 카운터
- 커스텀 커서 (민트 점 + 링)
- DB 기반 동적 카드 로딩 — `/portal/api/homepage/cards` API 호출
- API 실패 시 정적 카드로 자동 폴백
- `hub` 네임스페이스에 독립 배포 (nginx 정적 서빙)
**홈 카드 관리 (관리자)**
- `cyanburu.com/portal` 관리자 탭에 `🏠 홈 카드 관리` 추가
- 카드 추가 / 수정 / 삭제 / 순서 변경 / 공개 여부 설정
- 변경 사항이 허브 홈페이지에 즉시 반영 (재배포 불필요)
- `homepage_cards` 테이블 (PostgreSQL) 신규 추가
**web-portal 경로 변경 (`/` → `/portal`)**
- Nginx Ingress `rewrite-target` 으로 `/portal` prefix strip 처리
- `frontend/nginx.conf` subpath 대응 수정
- `frontend/index.html` API 경로 `/api``/portal/api` 수정
- `backend/main.py` `root_path="/portal"` 추가
#### 신규 k8s 파일
| 파일 | 내용 |
|------|------|
| `k8s/00-hub.yaml` | hub 네임스페이스 + Deployment + Service |
| `k8s/13-ingress-hub.yaml` | Hub Ingress (`cyanburu.com/`) |
#### DB 테이블 추가
```sql
CREATE TABLE IF NOT EXISTS homepage_cards (
id SERIAL PRIMARY KEY,
title VARCHAR(100) NOT NULL,
subtitle VARCHAR(200),
description TEXT,
url VARCHAR(500) NOT NULL,
tag VARCHAR(20) DEFAULT 'LIVE',
sort_order INTEGER DEFAULT 0,
visible BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT NOW()
);
```
> 신규 배포 시 `main.py` startup 이벤트에서 자동 생성. 실패 시 psql에서 직접 실행.
#### 프로젝트 구조 변경
```
hub/ ← 신규 추가
├── index.html ← 허브 홈페이지 (동적 카드 로딩)
└── Dockerfile ← nginx:alpine 기반 정적 서빙
backend/
└── main.py ← homepage_cards CRUD API 추가, root_path="/portal" 설정
frontend/
├── index.html ← API 경로 /portal/api 로 수정, 🏠 홈 카드 관리 탭 추가
└── nginx.conf ← /portal subpath 대응 수정
k8s/
├── 00-hub.yaml ← 신규 추가
├── 08-ingress.yaml ← /portal 경로로 변경
└── 13-ingress-hub.yaml ← 신규 추가 (cyanburu.com/ → hub)
```
#### 트러블슈팅 (5월)
**hub namespace not found**
- Registry Secret 생성 전 네임스페이스가 없어서 발생
- 해결: `kubectl create namespace hub` 먼저 실행 후 Secret 생성
**Ingress host+path 충돌 (BadRequest)**
- 기존 web-portal-ingress가 `cyanburu.com /` 를 점유하고 있어서 hub-ingress 생성 불가
- 해결: `08-ingress.yaml``/portal` 경로로 먼저 apply 후 `13-ingress-hub.yaml` apply
**홈 카드 관리 탭 내용 미표시**
- `page-admin-hub-cards` div가 `</main>` 밖에 위치해서 JS가 null 반환
- 해결: sed 명령으로 div를 `</main>` 안으로 이동
**hub 홈페이지 카드 미반영**
- `hub/index.html`에 동적 로딩 코드가 없는 구버전 파일이 배포됨
- 해결: 동적 카드 로딩 버전으로 `hub/index.html` 교체 후 재빌드