# Hướng Dẫn Deployment

>Hướng dẫn deployment cho GoodGo Microservices Platform trên các môi trường Local, Staging, và Production sử dụng Kubernetes và Neon PostgreSQL

## Mục lục

1. [Kiến trúc Deployment](#kiến-trúc-deployment)
2. [Yêu cầu Tiên quyết](#yêu-cầu-tiên-quyết)
3. [Thiết lập Database (Neon)](#thiết-lập-database-neon)
4. [Local Deployment](#local-deployment)
5. [Quy trình CI/CD](#quy-trình-cicd)
6. [Staging Deployment](#staging-deployment)
7. [Production Deployment](#production-deployment)
8. [Scaling & Resilience](#scaling--resilience)
9. [Quy trình Rollback](#quy-trình-rollback)

---

## Kiến trúc Deployment

```mermaid
graph TD
 subgraph "CI/CD Pipeline - GitHub Actions"
 Code[Code Push] --> Test[Run Tests]
 Test --> Build[Build Docker Image]
 Build --> Registry[Push to Registry]
 Registry --> Deploy[Deploy to K8s]
 end

 subgraph "Infrastructure - Kubernetes"
 Ingress[Traefik Ingress] --> Service[K8s Service]
 Service --> Pods[Application Pods]
 Pods --> Secrets[K8s Secrets]
 end

 subgraph "External Services"
 Pods --> Neon[(Neon PostgreSQL)]
 Pods --> Redis[(Redis Cloud)]
 end

 Deploy --> Ingress

 style Code fill:#1e3a5f,color:#e0e7ff
 style Test fill:#065f46,color:#d1fae5
 style Build fill:#1e40af,color:#dbeafe
 style Registry fill:#581c87,color:#f3e8ff
 style Deploy fill:#9a3412,color:#fed7aa
 style Ingress fill:#312e81,color:#e0e7ff
 style Service fill:#1e40af,color:#dbeafe
 style Pods fill:#14532d,color:#d1fae5
 style Secrets fill:#78350f,color:#fef3c7
 style Neon fill:#4c1d95,color:#f3e8ff
 style Redis fill:#854d0e,color:#fef3c7
```

---

## Yêu cầu Tiên quyết

Trước khi deploy, đảm bảo bạn có:

* **Công cụ**: Cài đặt `kubectl`, `helm`, `docker`.
* **Quyền truy cập**:
 * Kubernetes Cluster (EKS/GKE/DigitalOcean).
 * Container Registry (GHCR/DockerHub).
 * Tài khoản Neon Console.
* **Cấu hình**:
 * File `KUBECONFIG` đã được setup.
 * GitHub Secrets đã cấu hình cho CI/CD.

---

## Thiết lập Database (Neon)

Chúng tôi sử dụng **Neon Serverless PostgreSQL** cho tất cả môi trường để tận dụng tính năng branching và auto-scaling.

1. **Tạo Project**: Đăng nhập [neon.tech](https://neon.tech) và tạo project `goodgo-platform`.
2. **Tạo Branches**:
 * `main` -> Cho Development/Local.
 * `staging` -> Cho môi trường Staging.
 * `production` -> Cho môi trường Production (Protected).
3. **Lấy Connection Strings**:
 * Lưu lại connection string cho từng branch (Khuyến nghị dùng Pooler mode).

---

## Local Deployment

Cho phát triển cục bộ, chúng ta sử dụng Docker Compose.

```bash
# 1. Setup Biến môi trường
cp deployments/local/env.local.example deployments/local/.env.local
# Sửa .env.local với connection string của Neon branch `main`

# 2. Khởi động Infrastructure (Redis, Traefik, v.v.)
cd deployments/local
docker-compose up -d

# 3. Khởi động Services (Hot-reload)
pnpm dev
```

---

## Quy trình CI/CD

Chúng tôi sử dụng GitHub Actions để tự động hóa deployment.

| Workflow | Trigger | Mô tả |
| :--- | :--- | :--- |
| `ci-check.yml` | Pull Request | Chạy unit tests, linting, và kiểm tra build. |
| `deploy-staging.yml` | Push vào `develop` | Build image -> Deploy vào Namespace Staging. |
| `deploy-prod.yml` | Release / Tag | Build image -> Deploy vào Namespace Production. |

### Cấu hình Secrets (GitHub)

Cài đặt các secrets này trong phần settings của repository:

* `NEON_DATABASE_URL_STAGING`: Connection string cho branch staging.
* `NEON_DATABASE_URL_PRODUCTION`: Connection string cho branch production.
* `KUBECONFIG_STAGING`: Base64 encoded kubeconfig cho staging.
* `KUBECONFIG_PRODUCTION`: Base64 encoded kubeconfig cho production.
* `DOCKER_REGISTRY_TOKEN`: Dùng để push images.

---

## Staging Deployment

Staging phản chiếu production nhưng sử dụng tài nguyên tiết kiệm hơn.

### Deployment Thủ công

```bash
# 1. Tạo Secrets
kubectl create secret generic iam-service-secrets \
 --from-literal=database-url='<STAGING_NEON_URL>' \
 --from-literal=jwt-secret='<RANDOM_SECRET>' \
 -n staging

# 2. Apply Manifests
kubectl apply -f deployments/staging/kubernetes/ -n staging

# 3. Verify
kubectl get pods -n staging
```

### Qua CI/CD

Push code vào branch `develop`. Action sẽ:
1. Chạy tests.
2. Chạy `prisma migrate deploy` vào Database Staging.
3. Cập nhật Kubernetes deployment image.

---

## Production Deployment

Production sử dụng cấu hình high-availability (HA).

### 1. Chuẩn bị Database

* Đảm bảo branch Production trên Neon được set **protected**.
* Cấu hình **Point-in-Time Recovery (PITR)** window (ví dụ: 7 ngày).

### 2. Các bước Deployment Thủ công

```bash
# 1. Tạo Namespace
kubectl create namespace production

# 2. Tạo Secrets (Khuyến nghị Sealed Secrets) hoặc Standard Secrets
kubectl create secret generic iam-service-secrets \
 --from-literal=database-url='<PROD_NEON_URL>' \
 --from-literal=jwt-secret='<SECURE_RANDOM_SECRET>' \
 --from-literal=jwt-refresh-secret='<SECURE_RANDOM_SECRET>' \
 -n production

# 3. Deploy
kubectl apply -f deployments/production/kubernetes/ -n production
```

### 3. Xác minh

```bash
# Kiểm tra trạng thái Rollout
kubectl rollout status deployment/iam-service -n production

# Xem Logs
kubectl logs -l app=iam-service -n production
```

---

## Scaling & Resilience

### Horizontal Pod Autoscaler (HPA)

Chúng tôi sử dụng HPA để tự động scale số lượng pods dựa trên CPU/Memory.

```yaml
# Ví dụ cấu hình HPA
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
 name: iam-service-hpa
spec:
 minReplicas: 2
 maxReplicas: 10
 metrics:
 - type: Resource
 resource:
 name: cpu
 target:
 type: Utilization
 averageUtilization: 70
```

### Zero-Downtime Deployment

Kubernetes xử lý việc này thông qua Rolling Updates.
* **MaxSurge**: 25% (Thêm pods mới trước khi xóa pods cũ).
* **MaxUnavailable**: 0 (Đảm bảo không có downtime trong quá trình update).

---

## Quy trình Rollback

Nếu deployment thất bại hoặc gây ra lỗi nghiêm trọng:

### Kubernetes Rollback

```bash
# Undo deployment gần nhất
kubectl rollout undo deployment/iam-service -n production

# Undo về một revision cụ thể
kubectl rollout undo deployment/iam-service -n production --to-revision=2
```

### Database Rollback

Vì Neon hỗ trợ branching và PITR:
1. Vào Neon Console.
2. Restore branch `production` về timestamp trước khi migration bị lỗi.
3. **Cảnh báo**: Việc này có thể gây mất dữ liệu giao dịch mới. Hãy cẩn trọng.
