260210:1700 Start Delpoy
This commit is contained in:
193
specs/08-infrastructure/09_app_deployment.md
Normal file
193
specs/08-infrastructure/09_app_deployment.md
Normal file
@@ -0,0 +1,193 @@
|
||||
# การ Deploy Application (Backend + Frontend) บน QNAP
|
||||
|
||||
> 📍 **Version:** v1.7.0
|
||||
> 🖥️ **Server:** QNAP TS-473A (Container Station)
|
||||
> 🔗 **Docker Compose Path:** `/share/np-dms/app/docker-compose.yml`
|
||||
|
||||
---
|
||||
|
||||
## 📋 Prerequisites
|
||||
|
||||
ก่อน deploy ต้องมี services เหล่านี้รันอยู่แล้ว:
|
||||
|
||||
| Service | Container Name | Docker Compose | Status |
|
||||
| :------------- | :------------- | :--------------------------------- | :----- |
|
||||
| MariaDB | `mariadb` | `lcbp3-db` (MariaDB_setting.md) | ✅ |
|
||||
| Redis | `cache` | `services` (04_Service_setting.md) | ✅ |
|
||||
| Elasticsearch | `search` | `services` (04_Service_setting.md) | ✅ |
|
||||
| NPM | `npm` | `lcbp3-npm` (NPM_setting.md) | ✅ |
|
||||
| Docker Network | `lcbp3` | `docker network create lcbp3` | ✅ |
|
||||
|
||||
---
|
||||
|
||||
## 1. Build Docker Images
|
||||
|
||||
### Option A: Build บน Dev Machine แล้ว Transfer
|
||||
|
||||
```bash
|
||||
# อยู่ที่ workspace root (nap-dms.lcbp3/)
|
||||
|
||||
# Build Backend
|
||||
docker build -f backend/Dockerfile -t lcbp3-backend:latest .
|
||||
|
||||
# Build Frontend (NEXT_PUBLIC_API_URL bake เข้าไปตอน build)
|
||||
docker build -f frontend/Dockerfile \
|
||||
--build-arg NEXT_PUBLIC_API_URL=https://backend.np-dms.work/api \
|
||||
-t lcbp3-frontend:latest .
|
||||
|
||||
# Export เป็น .tar เพื่อ Transfer
|
||||
docker save lcbp3-backend:latest | gzip > lcbp3-backend.tar.gz
|
||||
docker save lcbp3-frontend:latest | gzip > lcbp3-frontend.tar.gz
|
||||
|
||||
# Transfer ไปยัง QNAP (ผ่าน SCP หรือ Shared Folder)
|
||||
scp lcbp3-*.tar.gz admin@192.168.10.8:/share/np-dms/app/
|
||||
```
|
||||
|
||||
### Option B: Build บน QNAP โดยตรง (SSH)
|
||||
|
||||
```bash
|
||||
# SSH เข้า QNAP
|
||||
ssh admin@192.168.10.8
|
||||
|
||||
# Clone หรือ Pull code จาก Gitea
|
||||
cd /share/np-dms/app/source
|
||||
git pull origin main
|
||||
|
||||
# Build images
|
||||
docker build -f backend/Dockerfile -t lcbp3-backend:latest .
|
||||
docker build -f frontend/Dockerfile \
|
||||
--build-arg NEXT_PUBLIC_API_URL=https://backend.np-dms.work/api \
|
||||
-t lcbp3-frontend:latest .
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Load Images บน QNAP (เฉพาะ Option A)
|
||||
|
||||
```bash
|
||||
# SSH เข้า QNAP
|
||||
ssh admin@192.168.10.8
|
||||
|
||||
# Load images
|
||||
docker load < /share/np-dms/app/lcbp3-backend.tar.gz
|
||||
docker load < /share/np-dms/app/lcbp3-frontend.tar.gz
|
||||
|
||||
# ตรวจสอบ
|
||||
docker images | grep lcbp3
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. สร้าง Directories และกำหนดสิทธิ์
|
||||
|
||||
```bash
|
||||
# สร้าง directories สำหรับ volumes
|
||||
mkdir -p /share/dms-data/uploads/temp
|
||||
mkdir -p /share/dms-data/uploads/permanent
|
||||
mkdir -p /share/dms-data/logs/backend
|
||||
mkdir -p /share/np-dms/app
|
||||
|
||||
# กำหนดสิทธิ์ให้ non-root user ใน container (UID 1001)
|
||||
chown -R 1001:1001 /share/dms-data/uploads
|
||||
chown -R 1001:1001 /share/dms-data/logs/backend
|
||||
chmod -R 750 /share/dms-data/uploads
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Deploy ผ่าน Container Station
|
||||
|
||||
### 4.1 Copy docker-compose.yml
|
||||
|
||||
คัดลอกไฟล์ `specs/08-infrastructure/docker-compose-app.yml` ไปยัง QNAP:
|
||||
|
||||
```bash
|
||||
# วางไฟล์ที่ path
|
||||
/share/np-dms/app/docker-compose.yml
|
||||
```
|
||||
|
||||
### 4.2 สร้าง Application ใน Container Station
|
||||
|
||||
1. เปิด **Container Station** บน QNAP Web UI
|
||||
2. ไปที่ **Applications** → **Create**
|
||||
3. เลือก **Create Application**
|
||||
4. ตั้งชื่อ Application: `lcbp3-app`
|
||||
5. วาง (Paste) เนื้อหาจาก `docker-compose-app.yml`
|
||||
6. แก้ไข Environment Variables ตามต้องการ (โดยเฉพาะ Secrets)
|
||||
7. กด **Create** เพื่อ deploy
|
||||
|
||||
> ⚠️ **สำคัญ:** ตรวจสอบ environment variables ก่อน deploy:
|
||||
> - `DB_PASSWORD` — Password ของ MariaDB
|
||||
> - `REDIS_PASSWORD` — Password ของ Redis
|
||||
> - `JWT_SECRET` — Secret key สำหรับ JWT Tokens
|
||||
> - `AUTH_SECRET` — Secret key สำหรับ NextAuth
|
||||
|
||||
### 4.3 ตรวจสอบ Container Status
|
||||
|
||||
ใน Container Station → Applications → `lcbp3-app`:
|
||||
- ✅ `backend` — Status: **Running** (healthy)
|
||||
- ✅ `frontend` — Status: **Running** (healthy)
|
||||
|
||||
---
|
||||
|
||||
## 5. Verify Deployment
|
||||
|
||||
### ตรวจสอบ Health
|
||||
|
||||
```bash
|
||||
# Backend health (จากภายใน Docker network)
|
||||
docker exec frontend wget -qO- http://backend:3000/health
|
||||
|
||||
# Frontend (ผ่าน NPM)
|
||||
curl -I https://lcbp3.np-dms.work
|
||||
|
||||
# Backend API (ผ่าน NPM)
|
||||
curl -I https://backend.np-dms.work/api
|
||||
```
|
||||
|
||||
### ตรวจสอบ Logs
|
||||
|
||||
```bash
|
||||
# ดู logs ใน Container Station UI
|
||||
# หรือผ่าน CLI:
|
||||
docker logs -f backend
|
||||
docker logs -f frontend
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Update / Re-deploy
|
||||
|
||||
เมื่อต้องการ deploy version ใหม่:
|
||||
|
||||
```bash
|
||||
# 1. Build images ใหม่ (บน Dev Machine)
|
||||
docker build -f backend/Dockerfile -t lcbp3-backend:latest .
|
||||
docker build -f frontend/Dockerfile -t lcbp3-frontend:latest .
|
||||
|
||||
# 2. Export & Transfer
|
||||
docker save lcbp3-backend:latest | gzip > lcbp3-backend.tar.gz
|
||||
docker save lcbp3-frontend:latest | gzip > lcbp3-frontend.tar.gz
|
||||
scp lcbp3-*.tar.gz admin@192.168.10.8:/share/np-dms/app/
|
||||
|
||||
# 3. Load บน QNAP
|
||||
ssh admin@192.168.10.8
|
||||
docker load < /share/np-dms/app/lcbp3-backend.tar.gz
|
||||
docker load < /share/np-dms/app/lcbp3-frontend.tar.gz
|
||||
|
||||
# 4. Restart ใน Container Station
|
||||
# Applications → lcbp3-app → Restart
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📦 Resource Summary
|
||||
|
||||
| Service | Image | CPU Limit | Memory Limit | Port |
|
||||
| :----------- | :---------------------- | :-------- | :----------- | :--- |
|
||||
| **backend** | `lcbp3-backend:latest` | 2.0 | 1.5 GB | 3000 |
|
||||
| **frontend** | `lcbp3-frontend:latest` | 2.0 | 2 GB | 3000 |
|
||||
|
||||
> 📖 NPM Proxy Hosts ตั้งค่าเรียบร้อยแล้ว:
|
||||
> - `lcbp3.np-dms.work` → `frontend:3000`
|
||||
> - `backend.np-dms.work` → `backend:3000`
|
||||
@@ -181,13 +181,14 @@ graph TB
|
||||
|
||||
### Core Services (QNAP)
|
||||
|
||||
| ไฟล์ | Application | Services | Path บน QNAP |
|
||||
| :--------------------------------------- | :---------- | :---------------------------------------- | :------------------------ |
|
||||
| [MariaDB_setting.md](MariaDB_setting.md) | `lcbp3-db` | `mariadb`, `pma` | `/share/np-dms/mariadb/` |
|
||||
| [NPM_setting.md](NPM_setting.md) | `lcbp3-npm` | `npm`, `landing` | `/share/np-dms/npm/` |
|
||||
| [Service_setting.md](Service_setting.md) | `services` | `cache` (Redis), `search` (Elasticsearch) | `/share/np-dms/services/` |
|
||||
| [Gitea_setting.md](Gitea_setting.md) | `git` | `gitea` | `/share/np-dms/gitea/` |
|
||||
| [n8n_setting.md](n8n_setting.md) | `n8n` | `n8n` | `/share/np-dms/n8n/` |
|
||||
| ไฟล์ | Application | Services | Path บน QNAP |
|
||||
| :----------------------------------------------- | :---------- | :---------------------------------------- | :------------------------ |
|
||||
| [MariaDB_setting.md](MariaDB_setting.md) | `lcbp3-db` | `mariadb`, `pma` | `/share/np-dms/mariadb/` |
|
||||
| [NPM_setting.md](NPM_setting.md) | `lcbp3-npm` | `npm`, `landing` | `/share/np-dms/npm/` |
|
||||
| [Service_setting.md](Service_setting.md) | `services` | `cache` (Redis), `search` (Elasticsearch) | `/share/np-dms/services/` |
|
||||
| [Gitea_setting.md](Gitea_setting.md) | `git` | `gitea` | `/share/np-dms/gitea/` |
|
||||
| [n8n_setting.md](n8n_setting.md) | `n8n` | `n8n` | `/share/np-dms/n8n/` |
|
||||
| [docker-compose-app.yml](docker-compose-app.yml) | `lcbp3-app` | `backend` (NestJS), `frontend` (Next.js) | `/share/np-dms/app/` |
|
||||
|
||||
### Infrastructure Services (ASUSTOR)
|
||||
|
||||
@@ -333,10 +334,11 @@ docker exec mariadb mysqldump -u root -p lcbp3 > backup.sql
|
||||
|
||||
## 📚 เอกสารเสริม
|
||||
|
||||
| ไฟล์ | คำอธิบาย |
|
||||
| :------------------------------- | :------------------------------------------------ |
|
||||
| [Git_command.md](Git_command.md) | คำสั่ง Git + Gitea Cheat Sheet |
|
||||
| [lcbp3-db.md](lcbp3-db.md) | Docker Compose สำหรับ MariaDB (alternative version) |
|
||||
| ไฟล์ | คำอธิบาย |
|
||||
| :------------------------------------------- | :-------------------------------------------------------- |
|
||||
| [Git_command.md](Git_command.md) | คำสั่ง Git + Gitea Cheat Sheet |
|
||||
| [lcbp3-db.md](lcbp3-db.md) | Docker Compose สำหรับ MariaDB (alternative version) |
|
||||
| [09_app_deployment.md](09_app_deployment.md) | ขั้นตอน Deploy Backend + Frontend บน QNAP Container Station |
|
||||
|
||||
---
|
||||
|
||||
|
||||
121
specs/08-infrastructure/docker-compose-app.yml
Normal file
121
specs/08-infrastructure/docker-compose-app.yml
Normal file
@@ -0,0 +1,121 @@
|
||||
# File: /share/np-dms/app/docker-compose.yml
|
||||
# DMS Container v1.7.0: Application Stack (Backend + Frontend)
|
||||
# Application name: lcbp3-app
|
||||
# ============================================================
|
||||
# ⚠️ ใช้งานร่วมกับ services อื่นที่รันอยู่แล้วบน QNAP:
|
||||
# - mariadb (lcbp3-db)
|
||||
# - cache (services)
|
||||
# - search (services)
|
||||
# - npm (lcbp3-npm)
|
||||
# ============================================================
|
||||
|
||||
x-restart: &restart_policy
|
||||
restart: unless-stopped
|
||||
|
||||
x-logging: &default_logging
|
||||
logging:
|
||||
driver: 'json-file'
|
||||
options:
|
||||
max-size: '10m'
|
||||
max-file: '5'
|
||||
|
||||
networks:
|
||||
lcbp3:
|
||||
external: true
|
||||
|
||||
services:
|
||||
# ----------------------------------------------------------------
|
||||
# 1. Backend API (NestJS)
|
||||
# Service Name: backend (ตามที่ NPM อ้างอิง → backend:3000)
|
||||
# ----------------------------------------------------------------
|
||||
backend:
|
||||
<<: [*restart_policy, *default_logging]
|
||||
image: lcbp3-backend:latest
|
||||
container_name: backend
|
||||
stdin_open: true
|
||||
tty: true
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '2.0'
|
||||
memory: 1536M
|
||||
reservations:
|
||||
cpus: '0.5'
|
||||
memory: 512M
|
||||
environment:
|
||||
TZ: 'Asia/Bangkok'
|
||||
NODE_ENV: 'production'
|
||||
# --- Database ---
|
||||
DB_HOST: 'mariadb'
|
||||
DB_PORT: '3306'
|
||||
DB_NAME: 'lcbp3'
|
||||
DB_USER: 'center'
|
||||
DB_PASSWORD: 'Center#2025'
|
||||
# --- Redis ---
|
||||
REDIS_HOST: 'cache'
|
||||
REDIS_PORT: '6379'
|
||||
REDIS_PASSWORD: 'Center2025'
|
||||
# --- Elasticsearch ---
|
||||
ELASTICSEARCH_HOST: 'search'
|
||||
ELASTICSEARCH_PORT: '9200'
|
||||
# --- JWT ---
|
||||
JWT_SECRET: 'eebc122aa65adde8c76c6a0847d9649b2b67a06db1504693e6c912e51499b76e'
|
||||
JWT_EXPIRES_IN: '8h'
|
||||
# --- Numbering ---
|
||||
NUMBERING_LOCK_TIMEOUT: '5000'
|
||||
NUMBERING_RESERVATION_TTL: '300'
|
||||
# --- File Upload ---
|
||||
UPLOAD_TEMP_DIR: '/app/uploads/temp'
|
||||
UPLOAD_PERMANENT_DIR: '/app/uploads/permanent'
|
||||
MAX_FILE_SIZE: '52428800'
|
||||
networks:
|
||||
- lcbp3
|
||||
volumes:
|
||||
# Two-Phase Storage: จัดเก็บไฟล์นอก container
|
||||
- '/share/dms-data/uploads/temp:/app/uploads/temp'
|
||||
- '/share/dms-data/uploads/permanent:/app/uploads/permanent'
|
||||
- '/share/dms-data/logs/backend:/app/logs'
|
||||
healthcheck:
|
||||
test: ['CMD', 'curl', '-f', 'http://localhost:3000/health']
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 30s
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
# 2. Frontend Web App (Next.js)
|
||||
# Service Name: frontend (ตามที่ NPM อ้างอิง → frontend:3000)
|
||||
# ----------------------------------------------------------------
|
||||
frontend:
|
||||
<<: [*restart_policy, *default_logging]
|
||||
image: lcbp3-frontend:latest
|
||||
container_name: frontend
|
||||
stdin_open: true
|
||||
tty: true
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '2.0'
|
||||
memory: 2G
|
||||
reservations:
|
||||
cpus: '0.25'
|
||||
memory: 512M
|
||||
environment:
|
||||
TZ: 'Asia/Bangkok'
|
||||
NODE_ENV: 'production'
|
||||
HOSTNAME: '0.0.0.0'
|
||||
PORT: '3000'
|
||||
# --- NextAuth ---
|
||||
AUTH_SECRET: 'eebc122aa65adde8c76c6a0847d9649b2b67a06db1504693e6c912e51499b76e'
|
||||
AUTH_URL: 'https://lcbp3.np-dms.work'
|
||||
networks:
|
||||
- lcbp3
|
||||
healthcheck:
|
||||
test: ['CMD-SHELL', 'wget --no-verbose --tries=1 --spider http://localhost:3000/ || exit 1']
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 20s
|
||||
depends_on:
|
||||
backend:
|
||||
condition: service_healthy
|
||||
Reference in New Issue
Block a user