260210:1700 Start Delpoy
Some checks failed
Spec Validation / validate-markdown (push) Has been cancelled
Spec Validation / validate-diagrams (push) Has been cancelled
Spec Validation / check-todos (push) Has been cancelled

This commit is contained in:
admin
2026-02-10 17:00:32 +07:00
parent d5e37d986f
commit d9df4e66b4
8 changed files with 642 additions and 11 deletions

View 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`

View File

@@ -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 |
---

View 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