BigBike
This commit is contained in:
1 parent
2364aa32b0
commit
5ba4afb2de
7 files changed
+756
No files matched your search
@@ -0,0 +1,178 @@
|
||||
# Server Information: sql@192.168.1.26
|
||||
|
||||
เอกสารสรุปรายละเอียดสภาพแวดล้อม (Environment), Runtimes (Node, Bun, PM2), ฐานข้อมูล (PostgreSQL, MariaDB), Nginx, และข้อกำหนดสำหรับการเขียน Git `post-receive` hook บนเซิร์ฟเวอร์ `192.168.1.26`
|
||||
|
||||
---
|
||||
|
||||
## 1. ข้อมูลระบบทั่วไป (System Overview)
|
||||
|
||||
| รายการ | รายละเอียด |
|
||||
| :--- | :--- |
|
||||
| **IP Address** | `192.168.1.26` |
|
||||
| **Hostname** | `sql` |
|
||||
| **SSH User** | `sql` (`uid=1000`, `gid=1000`) |
|
||||
| **Home Directory** | `/home/sql` |
|
||||
| **OS** | Ubuntu 22.04.5 LTS (Jammy Jellyfish) |
|
||||
| **Kernel** | Linux 5.15.0-191-generic x86_64 |
|
||||
| **CPU** | 12 vCPUs (QEMU Virtual CPU version 2.5+) |
|
||||
| **RAM** | Total: **15 GiB** (Used: ~1.7 GiB, Available: ~13 GiB, Swap: 4.0 GiB) |
|
||||
| **Disk** | `/` (LVM `ubuntu--vg-ubuntu--lv`): **391 GiB** (Used: 44 GiB / 12%, Avail: **331 GiB**) |
|
||||
| **User Groups** | `sql (1000)`, `adm (4)`, `cdrom (24)`, `sudo (27)`, `dip (30)`, `plugdev (46)`, `lxd (110)` |
|
||||
| **Sudo Access** | ต้องการ Password (Non-interactive sudo ไม่สามารถรันแบบไร้รหัสผ่านได้) |
|
||||
|
||||
---
|
||||
|
||||
## 2. สรุป Runtimes & เครื่องมือสำหรับ Post-Receive Hook
|
||||
|
||||
> **ข้อควรระวังสำคัญสำหรับ Post-Receive Hook:**
|
||||
> เมื่อ Git รัน hook ผ่าน SSH (`non-login non-interactive shell`), ค่า `$PATH` จะถูกจำกัดเป็นค่าเริ่มต้นของระบบ (มักมีแค่ `/usr/bin:/bin`) ทำให้หา `bun` ไม่เจอ
|
||||
> **ต้อง export PATH เสมอที่ต้นสคริปต์ hook:**
|
||||
> ```bash
|
||||
> export PATH="/home/sql/.bun/bin:/usr/local/bin:/usr/bin:/bin:$PATH"
|
||||
> ```
|
||||
|
||||
| เครื่องมือ | Version | Path แบบ Absolute | หมายเหตุ |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| **Bun** | `1.3.8` | `/home/sql/.bun/bin/bun` | รันเร็ว เหมาะสำหรับ `bun install`, `bun run build`, และ Elysia/Backend |
|
||||
| **Node.js** | `v25.2.0` | `/usr/bin/node` | ระบบไม่ได้ใช้ NVM (ลงผ่าน Package Manager ไว้ที่ `/usr/bin/node`) |
|
||||
| **NPM** | `11.6.2` | `/usr/bin/npm` | |
|
||||
| **PM2** | `6.0.14` | `/usr/bin/pm2` | มี Systemd Service `pm2-sql.service` เปิดใช้งานอัตโนมัติ (Boot startup) |
|
||||
| **Git** | `2.34.1` | `/usr/bin/git` | |
|
||||
| **Python** | `3.10.12` | `/usr/bin/python3` | มี venv อยู่ในบางโปรเจกต์ |
|
||||
|
||||
---
|
||||
|
||||
## 3. สถานะ PM2 & โปรเซสที่กำลังทำงานอยู่ (PM2 Processes)
|
||||
|
||||
PM2 Service: `pm2-sql` (Active / Enabled on boot)
|
||||
|
||||
| ID | Process Name | Mode | Interpreter | Script / Entry Point | Working Directory (CWD) | Port / Usage |
|
||||
| :---: | :--- | :---: | :---: | :--- | :--- | :---: |
|
||||
| **0** | `pm2-logrotate` | module | node | - | - | Auto-rotate logs |
|
||||
| **1** | `ddc hr backend` | fork | `/home/sql/.bun/bin/bun` | `apps/backend/dist/index.js` | `/home/sql/code/ddc_ops/apps/backend` | **5000** |
|
||||
| **2** | `aroka-backend` | fork | `none` (Bun directly) | `/home/sql/.bun/bin/bun run ...` | `/home/sql/code/aro/apps/backend` | **4000** |
|
||||
| **3** | `shop-ddcth` | fork | `node` (v25.2.0) | `apps/shop.ddcth.com/server.js` | `/home/sql/code/ddc_ops/apps/shop.ddcth.com` | **3001** (Next.js Standalone) |
|
||||
| **4** | `rebrand-dev` | fork | `none` (bash) | `bun run dev -- --port 4545` | `/home/sql/code/rebrand` | **4545** (Vite Dev Server) |
|
||||
| **5** | `check-order-production` | fork | `bash` | `run_backend.sh` (uvicorn FastAPI) | `/home/sql/code/nick/check-order-production` | **8000** |
|
||||
|
||||
---
|
||||
|
||||
## 4. ฐานข้อมูล (PostgreSQL & MariaDB)
|
||||
|
||||
### PostgreSQL (Local Instance)
|
||||
* **Version:** PostgreSQL 14.24 (Ubuntu 14.24-0ubuntu0.22.04.1)
|
||||
* **Cluster:** `14/main` (Status: `online`)
|
||||
* **Port:** `5432` (Listen on `127.0.0.1:5432`)
|
||||
* **Local Connection URL (ผ่านการทดสอบสำเร็จ):**
|
||||
```text
|
||||
postgresql://postgres:password@localhost:5432/postgres
|
||||
```
|
||||
* **ฐานข้อมูลที่มีอยู่ปัจจุบัน:**
|
||||
* `arokamwedweb` (Owner: `postgres`)
|
||||
* `postgres` (Owner: `postgres`)
|
||||
* **การสร้าง Database ใหม่สำหรับระบบ CMS:**
|
||||
```bash
|
||||
psql 'postgresql://postgres:password@localhost:5432/postgres' -c "CREATE DATABASE homaroma_db;"
|
||||
```
|
||||
Connection string สำหรับ `.env`:
|
||||
```text
|
||||
DATABASE_URL="postgresql://postgres:password@localhost:5432/homaroma_db?schema=public"
|
||||
```
|
||||
|
||||
### MariaDB / MySQL
|
||||
* **Version:** 10.6.22-MariaDB
|
||||
* **Port:** `3306` (Listen on `0.0.0.0:3306`)
|
||||
* **Status:** Active (running)
|
||||
|
||||
---
|
||||
|
||||
## 5. แผนผังพอร์ตที่ใช้งานอยู่บน Server (Port Allocation Map)
|
||||
|
||||
ห้ามตั้งพอร์ตซ้ำกับเซอร์วิสเหล่านี้ในการ Deploy:
|
||||
|
||||
| Port | Protocol / Service | Process / Application |
|
||||
| :---: | :--- | :--- |
|
||||
| **22** | SSH | OpenSSH Server |
|
||||
| **80** | HTTP | Nginx Reverse Proxy & Web Server |
|
||||
| **3001** | HTTP | `shop-ddcth` (Next.js SSR / Standalone) |
|
||||
| **3306** | MySQL | MariaDB 10.6 |
|
||||
| **4000** | HTTP | `aroka-backend` (Bun API) |
|
||||
| **4545** | HTTP | `rebrand-dev` (Vite dev) |
|
||||
| **5000** | HTTP | `ddc hr backend` (Bun Elysia API) |
|
||||
| **5432** | PostgreSQL | PostgreSQL 14 |
|
||||
| **6333 / 6334** | HTTP / gRPC | Qdrant Vector Database |
|
||||
| **8000** | HTTP | `check-order-production` (FastAPI / Uvicorn) |
|
||||
|
||||
> 💡 **พอร์ตแนะนำสำหรับระบบใหม่บน Server นี้:**
|
||||
> * Backend API (Elysia/Node): **`3005`** หรือ **`3050`**
|
||||
> * Website (Next.js SSR): **`3002`** หรือ **`3003`** (พอร์ต `3002` ว่างอยู่)
|
||||
|
||||
---
|
||||
|
||||
## 6. สิทธิ์และการจัดเก็บไฟล์ (Filesystem Structure & Permissions)
|
||||
|
||||
### 1) Git Bare Repositories
|
||||
* ตำแหน่งจัดเก็บ: `/home/sql/git/<project-name>.git`
|
||||
* Repositories บนเครื่อง:
|
||||
* `/home/sql/git/bigbike.git` (Symlink: `bigbike.ddcsprocket.com.git`) ⚡ **[สร้างใหม่สำหรับ bigbike.ddcsprocket.com]**
|
||||
* `/home/sql/git/aro.git`
|
||||
* `/home/sql/git/ddc_ops.git`
|
||||
* `/home/sql/git/rebrand.git`
|
||||
|
||||
|
||||
### 2) Checked-out Code & Backend Run Dir
|
||||
* ตำแหน่งจัดเก็บ: `/home/sql/code/<project-name>/`
|
||||
* ตัวอย่างที่มีอยู่เดิม:
|
||||
* `/home/sql/code/ddc_ops`
|
||||
* `/home/sql/code/aro`
|
||||
* `/home/sql/code/rebrand`
|
||||
|
||||
### 3) Web Root สำหรับ Static Files (Nginx)
|
||||
* Root: `/var/www/html/`
|
||||
* **สิทธิ์การเขียน:**
|
||||
* โฟลเดอร์ `/var/www/html` หลักเป็นของ `root:root` (User `sql` ไม่สามารถ `mkdir` ใต้ `/var/www/html` โดยตรงได้)
|
||||
* ต้องให้ root สร้างโฟลเดอร์ไว้ล่วงหน้าและตั้งสิทธิ์เป็น `sql:sql` เช่น:
|
||||
```bash
|
||||
sudo mkdir -p /var/www/html/homaroma
|
||||
sudo chown -R sql:sql /var/www/html/homaroma
|
||||
```
|
||||
* หรือเลือก Deploy static files ไว้ภายใน `/home/sql/projects/...` แล้วให้ Nginx ชี้เข้ามา (ต้องเปิด permission ให้อ่านได้)
|
||||
|
||||
---
|
||||
|
||||
## 7. Nginx Virtual Hosts ที่ตั้งค่าไว้ปัจจุบัน
|
||||
|
||||
Nginx รันอยู่ที่พอร์ต `80` โดยมี vhosts ใน `/etc/nginx/sites-enabled/`:
|
||||
* `admindemo.arokathaimed.com` ➔ `/var/www/html/aroka_admin`
|
||||
* `demo.arokathaimed.com` ➔ `/var/www/html/arokamedweb`
|
||||
* `ops.ddcth.com` & Default Server ➔ `/var/www/html/ddc_ops`
|
||||
* `luckydraw.ddcth.com` ➔ `/var/www/html/luckydraw`
|
||||
* `shop.ddcsprocket.co.th` ➔ `/var/www/html/shop.ddcth.com`
|
||||
|
||||
---
|
||||
|
||||
## 8. ข้อสรุปและ Checklist สำหรับสร้าง Post-Receive Hook
|
||||
|
||||
1. **ระบุ Binary Paths ชัดเจน:**
|
||||
```bash
|
||||
BUN="/home/sql/.bun/bin/bun"
|
||||
PM2="/usr/bin/pm2"
|
||||
NODE="/usr/bin/node"
|
||||
export PATH="/home/sql/.bun/bin:/usr/local/bin:/usr/bin:/bin:$PATH"
|
||||
```
|
||||
2. **สร้าง Git Bare Repo:**
|
||||
```bash
|
||||
mkdir -p /home/sql/git/cms.git
|
||||
cd /home/sql/git/cms.git
|
||||
git init --bare
|
||||
```
|
||||
3. **เตรียม Directory สำหรับ Code:**
|
||||
```bash
|
||||
mkdir -p /home/sql/code/cms
|
||||
```
|
||||
4. **เตรียม Directory สำหรับ Static Deploy (SPA/Admin):**
|
||||
```bash
|
||||
# ต้องสร้างด้วยสิทธิ์ที่ sql สามารถเขียนได้
|
||||
mkdir -p /var/www/html/cms_spa /var/www/html/cms_admin
|
||||
```
|
||||
5. **สร้างไฟล์ hook ที่ `/home/sql/git/<repo>.git/hooks/post-receive` และ `chmod +x`**
|
||||
@@ -0,0 +1,110 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ==============================================================================
|
||||
# Bigbike Project (bigbike.ddcsprocket.com)
|
||||
# Deployment Script (post-receive hook) on sql@192.168.1.26
|
||||
# Role: Application Runner (PM2 / Bun / Node) - No local Nginx
|
||||
# ==============================================================================
|
||||
|
||||
set -e
|
||||
export PATH="/home/sql/.bun/bin:/usr/local/bin:/usr/bin:/bin:$PATH"
|
||||
|
||||
# 1. PATH CONFIG
|
||||
GIT_DIR="/home/sql/git/bigbike.git"
|
||||
WORK_DIR="/home/sql/code/bigbike"
|
||||
BRANCH="master"
|
||||
TEMP_DIR="/tmp/bigbike_build_$(date +%s)"
|
||||
|
||||
# 2. RUNTIMES & EXECUTABLES
|
||||
BUN="/home/sql/.bun/bin/bun"
|
||||
NODE="/usr/bin/node"
|
||||
PM2="/usr/bin/pm2"
|
||||
|
||||
# 3. PM2 PROCESS NAMES
|
||||
PM2_NAME_BACKEND="bigbike-backend"
|
||||
PM2_NAME_WEBSITE="bigbike-website"
|
||||
|
||||
# 4. ASSIGNED PORTS (Direct forwarded from outer proxy / gateway)
|
||||
# (Port 3001 is shop-ddcth, 4000 is aroka, 5000 is ddc hr)
|
||||
BACKEND_PORT=3005
|
||||
SSR_PORT=3002
|
||||
|
||||
# 5. ENVIRONMENT VARIABLES
|
||||
export PORT="$SSR_PORT"
|
||||
export BACKEND_PORT="$BACKEND_PORT"
|
||||
export VITE_API_URL="https://api.bigbike.ddcsprocket.com/api"
|
||||
export NEXT_PUBLIC_API_URL="https://api.bigbike.ddcsprocket.com/api"
|
||||
|
||||
echo "========================================================"
|
||||
echo "🚀 [Bigbike] Starting Deployment on 192.168.1.26..."
|
||||
echo "========================================================"
|
||||
|
||||
# A. Checkout code to Work Directory
|
||||
mkdir -p "$WORK_DIR"
|
||||
echo ">>> Checking out branch $BRANCH to $WORK_DIR..."
|
||||
git --work-tree="$WORK_DIR" --git-dir="$GIT_DIR" checkout -f "$BRANCH"
|
||||
|
||||
cd "$WORK_DIR"
|
||||
|
||||
# B. Install dependencies
|
||||
if [ -f "package.json" ]; then
|
||||
echo ">>> Installing dependencies with Bun..."
|
||||
$BUN install
|
||||
fi
|
||||
|
||||
# C. Setup Backend (if apps/backend exists)
|
||||
if [ -d "apps/backend" ]; then
|
||||
echo ">>> Setting up Backend..."
|
||||
cd "$WORK_DIR/apps/backend"
|
||||
|
||||
if [ -f "prisma/schema.prisma" ]; then
|
||||
echo ">>> Generating Prisma Client..."
|
||||
$BUN x prisma generate
|
||||
|
||||
echo ">>> Auto-updating Database Schema..."
|
||||
if [ -d "prisma/migrations" ]; then
|
||||
echo ">>> Running Prisma migrate deploy..."
|
||||
$BUN x prisma migrate deploy || echo "⚠️ migrate deploy had notices, falling back to db push..."
|
||||
fi
|
||||
echo ">>> Syncing schema with db push..."
|
||||
$BUN x prisma db push --accept-data-loss
|
||||
fi
|
||||
|
||||
echo ">>> Restarting PM2 process: $PM2_NAME_BACKEND..."
|
||||
if $PM2 describe "$PM2_NAME_BACKEND" > /dev/null 2>&1; then
|
||||
$PM2 restart "$PM2_NAME_BACKEND" --update-env
|
||||
else
|
||||
echo ">>> Starting $PM2_NAME_BACKEND for the first time on port $BACKEND_PORT..."
|
||||
PORT=$BACKEND_PORT $PM2 start "$BUN" --name "$PM2_NAME_BACKEND" --cwd "$WORK_DIR/apps/backend" -- run src/index.ts
|
||||
fi
|
||||
cd "$WORK_DIR"
|
||||
fi
|
||||
|
||||
# D. Setup Website SSR (if apps/website exists)
|
||||
if [ -d "apps/website" ]; then
|
||||
echo ">>> Building Next.js Website..."
|
||||
cd "$WORK_DIR/apps/website"
|
||||
NODE_ENV=production $BUN run build
|
||||
|
||||
echo ">>> Restarting PM2 process: $PM2_NAME_WEBSITE..."
|
||||
if $PM2 describe "$PM2_NAME_WEBSITE" > /dev/null 2>&1; then
|
||||
PORT=$SSR_PORT $PM2 restart "$PM2_NAME_WEBSITE" --update-env
|
||||
else
|
||||
echo ">>> Starting $PM2_NAME_WEBSITE for the first time on port $SSR_PORT..."
|
||||
# Check standalone server or standard next start
|
||||
if [ -f ".next/standalone/server.js" ]; then
|
||||
PORT=$SSR_PORT $PM2 start "$NODE" --name "$PM2_NAME_WEBSITE" --cwd "$WORK_DIR/apps/website/.next/standalone" -- server.js
|
||||
else
|
||||
PORT=$SSR_PORT $PM2 start "$BUN" --name "$PM2_NAME_WEBSITE" --cwd "$WORK_DIR/apps/website" -- run start
|
||||
fi
|
||||
fi
|
||||
cd "$WORK_DIR"
|
||||
fi
|
||||
|
||||
# E. Save PM2 state
|
||||
$PM2 save
|
||||
|
||||
echo "========================================================"
|
||||
echo "✅ [Bigbike] Deployment Finished Successfully!"
|
||||
echo "========================================================"
|
||||
$PM2 status
|
||||
@@ -0,0 +1,157 @@
|
||||
# Bigbike Platform Deployment Guide & System Architecture
|
||||
### Target Domain: `bigbike.ddcsprocket.com`
|
||||
### Target Server: `sql@192.168.1.26`
|
||||
|
||||
---
|
||||
|
||||
## 1. บทบาทของเซิร์ฟเวอร์ (System Architecture & Role)
|
||||
|
||||
* **Server IP:** `192.168.1.26` (Hostname: `sql`, User: `sql`)
|
||||
* **บทบาท (Role):** **Application Runner เท่านั้น (Node.js / Bun / PM2)**
|
||||
* **ขอบเขตการทำงาน:**
|
||||
* รัน API Service (Elysia / Bun) และ Website SSR (Next.js Standalone / Node.js) ภายใต้การควบคุมของ PM2
|
||||
* **ไม่ต้องตั้งค่า Nginx บนเครื่องนี้** เนื่องจากระบบมี Gateway / Reverse Proxy ภายนอกทำการ Port-Forward หรือ Proxy ส่ง Traffic เข้ามายังพอร์ตของแต่ละ Service โดยตรง
|
||||
|
||||
```
|
||||
[ User Request ]
|
||||
│
|
||||
▼
|
||||
[ External Gateway / Firewall / Nginx Proxy ]
|
||||
│
|
||||
├── Forward Traffic (Domain: bigbike.ddcsprocket.com) ──► 192.168.1.26:3002 (Next.js SSR)
|
||||
└── Forward Traffic (Domain: api.bigbike.ddcsprocket.com) ─► 192.168.1.26:3005 (Elysia API)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. โครงสร้าง Git Repository & การเชื่อมต่อ (Git Info)
|
||||
|
||||
### ฝั่ง Server (`192.168.1.26`)
|
||||
| รายการ | ตำแหน่ง Path บน Server | รายละเอียด |
|
||||
| :--- | :--- | :--- |
|
||||
| **Bare Repository** | `/home/sql/git/bigbike.git` | จุดรับ Git Push จากเครื่อง Local |
|
||||
| **Symlink Alias** | `/home/sql/git/bigbike.ddcsprocket.com.git` | ชี้ไปยัง `bigbike.git` |
|
||||
| **Working Directory** | `/home/sql/code/bigbike` | โฟลเดอร์แตกไฟล์ Source Code และรันโปรเจกต์ |
|
||||
| **Hook Script** | `/home/sql/git/bigbike.git/hooks/post-receive` | สคริปต์สั่ง Build และ Restart PM2 อัตโนมัติ (`chmod +x`) |
|
||||
|
||||
### ฝั่ง Local (`d:\cms`)
|
||||
* **Git Remote Name:** `bigbike`
|
||||
* **Remote URL:** `sql@192.168.1.26:/home/sql/git/bigbike.git`
|
||||
* **คำสั่ง Deploy:**
|
||||
```powershell
|
||||
git push bigbike master
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Runtimes & สภาพแวดล้อมที่ใช้ในการประมวลผล
|
||||
|
||||
| เครื่องมือ | Version | Path บนเครื่อง 192.168.1.26 | หน้าที่ในไปป์ไลน์ |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| **Bun** | `1.3.8` | `/home/sql/.bun/bin/bun` | รัน `bun install`, `bun run build`, รัน Elysia Backend |
|
||||
| **Node.js** | `v25.2.0` | `/usr/bin/node` | รัน Next.js Standalone SSR Server |
|
||||
| **PM2** | `6.0.14` | `/usr/bin/pm2` | Process Manager ควบคุม Service ให้รันตลอดเวลา |
|
||||
| **PostgreSQL** | `14.24` | `localhost:5432` | ฐานข้อมูล Local |
|
||||
|
||||
> ⚠️ **ข้อควรระวังเรื่อง PATH ใน Post-Receive Hook:**
|
||||
> SSH non-interactive session จะไม่โหลด `~/.bashrc` อัตโนมัติ ในหัวสคริปต์ `post-receive` ต้อง export PATH เสมอ:
|
||||
> ```bash
|
||||
> export PATH="/home/sql/.bun/bin:/usr/local/bin:/usr/bin:/bin:$PATH"
|
||||
> ```
|
||||
|
||||
---
|
||||
|
||||
## 4. แผนผังพอร์ต & การจัดการ PM2 (Process Management)
|
||||
|
||||
### พอร์ตและ Process ของ Bigbike (เปิดใหม่)
|
||||
| Service | PM2 Process Name | Port | Runtime / Command | CWD |
|
||||
| :--- | :--- | :---: | :--- | :--- |
|
||||
| **Backend API** | `bigbike-backend` | **`3005`** | `bun run src/index.ts` | `/home/sql/code/bigbike/apps/backend` |
|
||||
| **Website (SSR)** | `bigbike-website` | **`3002`** | `node server.js` (.next/standalone) | `/home/sql/code/bigbike/apps/website` |
|
||||
|
||||
### ตารางตรวจสอบพอร์ตเดิมบน Server (เพื่อป้องกันพอร์ตชน)
|
||||
| Port | Service เดิมที่ใช้งานอยู่ | สถานะ |
|
||||
| :---: | :--- | :---: |
|
||||
| **3001** | `shop-ddcth` (Next.js) | ใช้งานอยู่ |
|
||||
| **3002** | *ว่าง* ➔ **กำหนดให้ `bigbike-website`** | ✅ ใช้งานได้ |
|
||||
| **3005** | *ว่าง* ➔ **กำหนดให้ `bigbike-backend`** | ✅ ใช้งานได้ |
|
||||
| **3306** | MariaDB Server | ใช้งานอยู่ |
|
||||
| **4000** | `aroka-backend` | ใช้งานอยู่ |
|
||||
| **4545** | `rebrand-dev` (Vite) | ใช้งานอยู่ |
|
||||
| **5000** | `ddc hr backend` (Bun) | ใช้งานอยู่ |
|
||||
| **5432** | PostgreSQL 14 Local | ใช้งานอยู่ |
|
||||
| **6333 / 6334** | Qdrant Vector DB | ใช้งานอยู่ |
|
||||
| **8000** | `check-order-production` (Python FastAPI) | ใช้งานอยู่ |
|
||||
|
||||
---
|
||||
|
||||
## 5. การตั้งค่าฐานข้อมูล & ไฟล์ .env (Database & Environment Config)
|
||||
|
||||
### 1) สถานะฐานข้อมูล PostgreSQL
|
||||
* **สถานะปัจจุบัน:** ✅ **สร้าง Database `bigbike_db` บน `192.168.1.26` เรียบร้อยแล้ว**
|
||||
* **Host:** `localhost:5432`
|
||||
* **User:** `postgres`
|
||||
* **Password:** `password`
|
||||
* **Connection String:**
|
||||
```text
|
||||
DATABASE_URL="postgresql://postgres:password@localhost:5432/bigbike_db?schema=public"
|
||||
```
|
||||
|
||||
### 2) ตำแหน่งไฟล์ .env ที่ติดตั้งไว้บน Server (`192.168.1.26`)
|
||||
* **Backend API:** `/home/sql/code/bigbike/apps/backend/.env`
|
||||
```env
|
||||
PORT=3005
|
||||
DATABASE_URL="postgresql://postgres:password@localhost:5432/bigbike_db?schema=public"
|
||||
NODE_ENV=production
|
||||
APP_URL="https://api.bigbike.ddcsprocket.com"
|
||||
BACKEND_PUBLIC_URL="https://api.bigbike.ddcsprocket.com"
|
||||
CORS_ORIGIN="https://admin.bigbike.ddcsprocket.com,https://spa.bigbike.ddcsprocket.com,https://bigbike.ddcsprocket.com,http://localhost:3000,http://localhost:3002"
|
||||
JWT_SECRET="bigbike-secret-key-prod-2026-ddc"
|
||||
OMISE_SECRET_KEY=""
|
||||
```
|
||||
* **Website (Next.js SSR):** `/home/sql/code/bigbike/apps/website/.env`
|
||||
```env
|
||||
PORT=3002
|
||||
NODE_ENV=production
|
||||
NEXT_PUBLIC_API_URL="https://api.bigbike.ddcsprocket.com/api"
|
||||
```
|
||||
*(ไฟล์ template ถูกสำรองไว้ใน [backend.env](file:///d:/cms/serverinfo/192.168.1.26/bigbike.ddcsprocket.com/backend.env) และ [website.env](file:///d:/cms/serverinfo/192.168.1.26/bigbike.ddcsprocket.com/website.env))*
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 6. วงจรการทำงานของ Post-Receive Hook (Deployment Pipeline)
|
||||
|
||||
เมื่อมีการ `git push bigbike master` สคริปต์ `/home/sql/git/bigbike.git/hooks/post-receive` จะทำงานตามลำดับดังนี้:
|
||||
|
||||
1. **Checkout Source Code:** แตกไฟล์ล่าสุดจาก Git ลงที่ `/home/sql/code/bigbike`
|
||||
2. **Install Dependencies:** สั่งรัน `$BUN install` ใน root monorepo
|
||||
3. **Backend Service & Auto Database Migration:**
|
||||
* รัน `$BUN x prisma generate` (อัปเดต Prisma Client Types)
|
||||
* รัน `$BUN x prisma migrate deploy` (นำ migration files ใหม่ไป Apply ลง DB อัตโนมัติ)
|
||||
* รัน `$BUN x prisma db push --accept-data-loss` (ซิงก์ schema เข้า DB ทันที ป้องกันกรณีแก้ schema.prisma โดยไม่ได้รัน migrate dev)
|
||||
* สั่ง `pm2 restart bigbike-backend --update-env` (หากยังไม่เคยรัน จะสั่ง `pm2 start` บนพอร์ต `3005`)
|
||||
4. **Website Service (Next.js SSR):**
|
||||
* บิลด์ Next.js ด้วย `NODE_ENV=production $BUN run build`
|
||||
* สั่ง `pm2 restart bigbike-website --update-env` (หากยังไม่เคยรัน จะสั่งรัน standalone `server.js` บนพอร์ต `3002`)
|
||||
5. **Persist State:** สั่ง `pm2 save` เพื่อบันทึกรายชื่อโปรเซส ให้ฟื้นตัวอัตโนมัติเมื่อเซิร์ฟเวอร์รีบูต
|
||||
|
||||
---
|
||||
|
||||
## 7. คำสั่งที่ใช้ในการตรวจสอบและแก้ไขปัญหา (Runbook & Troubleshooting)
|
||||
|
||||
### ตรวจสอบสถานะและ Logs บน Server:
|
||||
```bash
|
||||
# ดูสถานะ PM2 ทั้งหมด
|
||||
ssh sql@192.168.1.26 "pm2 status"
|
||||
|
||||
# ดู Logs สดของ Backend
|
||||
ssh sql@192.168.1.26 "pm2 logs bigbike-backend --lines 100"
|
||||
|
||||
# ดู Logs สดของ Website SSR
|
||||
ssh sql@192.168.1.26 "pm2 logs bigbike-website --lines 100"
|
||||
|
||||
# ทดสอบ Curl พอร์ตภายในเครื่อง
|
||||
ssh sql@192.168.1.26 "curl -I http://localhost:3005"
|
||||
ssh sql@192.168.1.26 "curl -I http://localhost:3002"
|
||||
```
|
||||
@@ -0,0 +1,23 @@
|
||||
# Git Configuration for bigbike.ddcsprocket.com
|
||||
|
||||
## Remote Configuration
|
||||
* **Server:** `192.168.1.26`
|
||||
* **SSH User:** `sql`
|
||||
* **Bare Repo (Server):** `/home/sql/git/bigbike.git`
|
||||
* **Symlink (Server):** `/home/sql/git/bigbike.ddcsprocket.com.git`
|
||||
* **Working Directory (Server):** `/home/sql/code/bigbike`
|
||||
* **Hook File (Server):** `/home/sql/git/bigbike.git/hooks/post-receive`
|
||||
|
||||
## Local Git Setup (Machine)
|
||||
* **Remote Name:** `bigbike`
|
||||
* **Remote Push URL:** `sql@192.168.1.26:/home/sql/git/bigbike.git`
|
||||
* **Remote Fetch URL:** `sql@192.168.1.26:/home/sql/git/bigbike.git`
|
||||
|
||||
## Deploy Commands
|
||||
```powershell
|
||||
# Deploy branch master
|
||||
git push bigbike master
|
||||
|
||||
# Dry run test
|
||||
git push --dry-run bigbike master
|
||||
```
|
||||
@@ -0,0 +1,110 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ==============================================================================
|
||||
# Bigbike Project (bigbike.ddcsprocket.com)
|
||||
# Deployment Script (post-receive hook) on sql@192.168.1.26
|
||||
# Role: Application Runner (PM2 / Bun / Node) - No local Nginx
|
||||
# ==============================================================================
|
||||
|
||||
set -e
|
||||
export PATH="/home/sql/.bun/bin:/usr/local/bin:/usr/bin:/bin:$PATH"
|
||||
|
||||
# 1. PATH CONFIG
|
||||
GIT_DIR="/home/sql/git/bigbike.git"
|
||||
WORK_DIR="/home/sql/code/bigbike"
|
||||
BRANCH="master"
|
||||
TEMP_DIR="/tmp/bigbike_build_$(date +%s)"
|
||||
|
||||
# 2. RUNTIMES & EXECUTABLES
|
||||
BUN="/home/sql/.bun/bin/bun"
|
||||
NODE="/usr/bin/node"
|
||||
PM2="/usr/bin/pm2"
|
||||
|
||||
# 3. PM2 PROCESS NAMES
|
||||
PM2_NAME_BACKEND="bigbike-backend"
|
||||
PM2_NAME_WEBSITE="bigbike-website"
|
||||
|
||||
# 4. ASSIGNED PORTS (Direct forwarded from outer proxy / gateway)
|
||||
# (Port 3001 is shop-ddcth, 4000 is aroka, 5000 is ddc hr)
|
||||
BACKEND_PORT=3005
|
||||
SSR_PORT=3002
|
||||
|
||||
# 5. ENVIRONMENT VARIABLES
|
||||
export PORT="$SSR_PORT"
|
||||
export BACKEND_PORT="$BACKEND_PORT"
|
||||
export VITE_API_URL="https://api.bigbike.ddcsprocket.com/api"
|
||||
export NEXT_PUBLIC_API_URL="https://api.bigbike.ddcsprocket.com/api"
|
||||
|
||||
echo "========================================================"
|
||||
echo "🚀 [Bigbike] Starting Deployment on 192.168.1.26..."
|
||||
echo "========================================================"
|
||||
|
||||
# A. Checkout code to Work Directory
|
||||
mkdir -p "$WORK_DIR"
|
||||
echo ">>> Checking out branch $BRANCH to $WORK_DIR..."
|
||||
git --work-tree="$WORK_DIR" --git-dir="$GIT_DIR" checkout -f "$BRANCH"
|
||||
|
||||
cd "$WORK_DIR"
|
||||
|
||||
# B. Install dependencies
|
||||
if [ -f "package.json" ]; then
|
||||
echo ">>> Installing dependencies with Bun..."
|
||||
$BUN install
|
||||
fi
|
||||
|
||||
# C. Setup Backend (if apps/backend exists)
|
||||
if [ -d "apps/backend" ]; then
|
||||
echo ">>> Setting up Backend..."
|
||||
cd "$WORK_DIR/apps/backend"
|
||||
|
||||
if [ -f "prisma/schema.prisma" ]; then
|
||||
echo ">>> Generating Prisma Client..."
|
||||
$BUN x prisma generate
|
||||
|
||||
echo ">>> Auto-updating Database Schema..."
|
||||
if [ -d "prisma/migrations" ]; then
|
||||
echo ">>> Running Prisma migrate deploy..."
|
||||
$BUN x prisma migrate deploy || echo "⚠️ migrate deploy had notices, falling back to db push..."
|
||||
fi
|
||||
echo ">>> Syncing schema with db push..."
|
||||
$BUN x prisma db push --accept-data-loss
|
||||
fi
|
||||
|
||||
echo ">>> Restarting PM2 process: $PM2_NAME_BACKEND..."
|
||||
if $PM2 describe "$PM2_NAME_BACKEND" > /dev/null 2>&1; then
|
||||
$PM2 restart "$PM2_NAME_BACKEND" --update-env
|
||||
else
|
||||
echo ">>> Starting $PM2_NAME_BACKEND for the first time on port $BACKEND_PORT..."
|
||||
PORT=$BACKEND_PORT $PM2 start "$BUN" --name "$PM2_NAME_BACKEND" --cwd "$WORK_DIR/apps/backend" -- run src/index.ts
|
||||
fi
|
||||
cd "$WORK_DIR"
|
||||
fi
|
||||
|
||||
# D. Setup Website SSR (if apps/website exists)
|
||||
if [ -d "apps/website" ]; then
|
||||
echo ">>> Building Next.js Website..."
|
||||
cd "$WORK_DIR/apps/website"
|
||||
NODE_ENV=production $BUN run build
|
||||
|
||||
echo ">>> Restarting PM2 process: $PM2_NAME_WEBSITE..."
|
||||
if $PM2 describe "$PM2_NAME_WEBSITE" > /dev/null 2>&1; then
|
||||
PORT=$SSR_PORT $PM2 restart "$PM2_NAME_WEBSITE" --update-env
|
||||
else
|
||||
echo ">>> Starting $PM2_NAME_WEBSITE for the first time on port $SSR_PORT..."
|
||||
# Check standalone server or standard next start
|
||||
if [ -f ".next/standalone/server.js" ]; then
|
||||
PORT=$SSR_PORT $PM2 start "$NODE" --name "$PM2_NAME_WEBSITE" --cwd "$WORK_DIR/apps/website/.next/standalone" -- server.js
|
||||
else
|
||||
PORT=$SSR_PORT $PM2 start "$BUN" --name "$PM2_NAME_WEBSITE" --cwd "$WORK_DIR/apps/website" -- run start
|
||||
fi
|
||||
fi
|
||||
cd "$WORK_DIR"
|
||||
fi
|
||||
|
||||
# E. Save PM2 state
|
||||
$PM2 save
|
||||
|
||||
echo "========================================================"
|
||||
echo "✅ [Bigbike] Deployment Finished Successfully!"
|
||||
echo "========================================================"
|
||||
$PM2 status
|
||||
@@ -0,0 +1,29 @@
|
||||
// PM2 Ecosystem Config for sql@192.168.1.26
|
||||
module.exports = {
|
||||
apps: [
|
||||
{
|
||||
name: 'cms-backend',
|
||||
script: './src/index.ts',
|
||||
cwd: '/home/sql/code/cms-api/apps/backend',
|
||||
interpreter: '/home/sql/.bun/bin/bun',
|
||||
watch: false,
|
||||
max_memory_restart: '1G',
|
||||
env_production: {
|
||||
NODE_ENV: 'production',
|
||||
PORT: 3005
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'cms-website',
|
||||
script: 'server.js',
|
||||
cwd: '/home/sql/code/cms-website',
|
||||
interpreter: '/usr/bin/node',
|
||||
watch: false,
|
||||
max_memory_restart: '1G',
|
||||
env_production: {
|
||||
NODE_ENV: 'production',
|
||||
PORT: 3002
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
@@ -0,0 +1,149 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ==============================================================================
|
||||
# HomAroma / CMS Project - Post-Receive Hook for sql@192.168.1.26
|
||||
# ==============================================================================
|
||||
|
||||
# 1. PATH & ENVIRONMENT
|
||||
export PATH="/home/sql/.bun/bin:/usr/local/bin:/usr/bin:/bin:$PATH"
|
||||
set -e
|
||||
|
||||
# 2. TARGET PATHS
|
||||
# Static Frontend Deployments (Nginx document root)
|
||||
TARGET_SPA="/var/www/html/cms/spa"
|
||||
TARGET_ADMIN="/var/www/html/cms/admin"
|
||||
|
||||
# Backend & Next.js Website Working Directories
|
||||
TARGET_BACKEND="/home/sql/code/cms-api"
|
||||
TARGET_WEBSITE="/home/sql/code/cms-website"
|
||||
|
||||
# 3. REPOSITORY CONFIG
|
||||
REPO="/home/sql/git/cms.git"
|
||||
BRANCH="master"
|
||||
TEMP_DIR="/tmp/cms_build_$(date +%s)"
|
||||
|
||||
# 4. BINARY PATHS
|
||||
BUN="/home/sql/.bun/bin/bun"
|
||||
NODE="/usr/bin/node"
|
||||
PM2="/usr/bin/pm2"
|
||||
|
||||
# 5. PM2 PROCESS NAMES
|
||||
PM2_NAME_BACKEND="cms-backend"
|
||||
PM2_NAME_WEBSITE="cms-website"
|
||||
|
||||
# 6. SERVICE PORTS (Ensure no collision with 3001, 4000, 4545, 5000, 5432, 6333, 8000)
|
||||
BACKEND_PORT=3005
|
||||
SSR_PORT=3002
|
||||
|
||||
# 7. BUILD ENVIRONMENT VARIABLES
|
||||
export VITE_API_URL="http://192.168.1.26:${BACKEND_PORT}/api"
|
||||
export NEXT_PUBLIC_API_URL="http://192.168.1.26:${BACKEND_PORT}/api"
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# START DEPLOYMENT
|
||||
# ------------------------------------------------------------------------------
|
||||
echo "------- 🚀 Starting Full Deployment: sql@192.168.1.26 -------"
|
||||
|
||||
# A. Prepare Temp Source from Checkout
|
||||
echo "Cloning branch $BRANCH to temporary directory: $TEMP_DIR"
|
||||
mkdir -p "$TEMP_DIR"
|
||||
git --work-tree="$TEMP_DIR" --git-dir="$REPO" checkout -f "$BRANCH"
|
||||
|
||||
cd "$TEMP_DIR"
|
||||
echo "Installing monorepo dependencies with Bun..."
|
||||
$BUN install
|
||||
|
||||
# B. Build & Deploy SPA
|
||||
if [ -d "apps/spa" ]; then
|
||||
echo ">>> Building SPA..."
|
||||
cd apps/spa
|
||||
$BUN run build
|
||||
echo "Deploying SPA to $TARGET_SPA..."
|
||||
mkdir -p "$TARGET_SPA"
|
||||
rm -rf "$TARGET_SPA"/*
|
||||
cp -rv dist/* "$TARGET_SPA"/
|
||||
cd ../..
|
||||
fi
|
||||
|
||||
# C. Build & Deploy Admin Panel
|
||||
if [ -d "apps/admin" ]; then
|
||||
echo ">>> Building Admin Panel..."
|
||||
cd apps/admin
|
||||
$BUN run build
|
||||
echo "Deploying Admin Panel to $TARGET_ADMIN..."
|
||||
mkdir -p "$TARGET_ADMIN"
|
||||
rm -rf "$TARGET_ADMIN"/*
|
||||
cp -rv dist/* "$TARGET_ADMIN"/
|
||||
cd ../..
|
||||
fi
|
||||
|
||||
# D. Deploy & Manage Backend
|
||||
if [ -d "apps/backend" ]; then
|
||||
echo ">>> Updating Backend at $TARGET_BACKEND..."
|
||||
mkdir -p "$TARGET_BACKEND/apps"
|
||||
mkdir -p "$TARGET_BACKEND/packages"
|
||||
|
||||
rsync -av --delete \
|
||||
--exclude='.env' \
|
||||
--exclude='public/' \
|
||||
--exclude='node_modules/' \
|
||||
apps/backend/ "$TARGET_BACKEND/apps/backend/"
|
||||
|
||||
rsync -av packages/ "$TARGET_BACKEND/packages/"
|
||||
cp package.json bun.lock ecosystem.config.js "$TARGET_BACKEND/" 2>/dev/null || cp package.json bun.lock "$TARGET_BACKEND/"
|
||||
|
||||
cd "$TARGET_BACKEND"
|
||||
$BUN install
|
||||
|
||||
mkdir -p "$TARGET_BACKEND/apps/backend/public"
|
||||
|
||||
cd "$TARGET_BACKEND/apps/backend"
|
||||
echo ">>> Generating Prisma Client & Pushing DB..."
|
||||
$BUN x prisma generate
|
||||
$BUN x prisma db push --accept-data-loss || echo "Prisma db push skipped or failed"
|
||||
|
||||
echo ">>> Managing PM2 for Backend..."
|
||||
if $PM2 describe "$PM2_NAME_BACKEND" > /dev/null 2>&1; then
|
||||
$PM2 restart "$PM2_NAME_BACKEND" --update-env
|
||||
else
|
||||
$PM2 start "$BUN" --name "$PM2_NAME_BACKEND" --cwd "$TARGET_BACKEND/apps/backend" -- run src/index.ts
|
||||
fi
|
||||
fi
|
||||
|
||||
# E. Deploy & Manage Website (Next.js SSR)
|
||||
if [ -d "$TEMP_DIR/apps/website" ]; then
|
||||
echo ">>> Building Website (Next.js SSR)..."
|
||||
cd "$TEMP_DIR/apps/website"
|
||||
$BUN run build
|
||||
|
||||
echo ">>> Updating Website at $TARGET_WEBSITE..."
|
||||
mkdir -p "$TARGET_WEBSITE"
|
||||
rsync -av --delete \
|
||||
--exclude='.env' \
|
||||
--exclude='node_modules/' \
|
||||
"$TEMP_DIR/apps/website/.next/standalone/" "$TARGET_WEBSITE/" 2>/dev/null || echo "Standalone directory sync"
|
||||
|
||||
if [ -d "$TEMP_DIR/apps/website/.next/static" ]; then
|
||||
mkdir -p "$TARGET_WEBSITE/.next/static"
|
||||
cp -rv "$TEMP_DIR/apps/website/.next/static/"* "$TARGET_WEBSITE/.next/static/"
|
||||
fi
|
||||
if [ -d "$TEMP_DIR/apps/website/public" ]; then
|
||||
cp -rv "$TEMP_DIR/apps/website/public" "$TARGET_WEBSITE/"
|
||||
fi
|
||||
|
||||
echo ">>> Managing PM2 for Website..."
|
||||
cd "$TARGET_WEBSITE"
|
||||
PORT=$SSR_PORT
|
||||
if $PM2 describe "$PM2_NAME_WEBSITE" > /dev/null 2>&1; then
|
||||
$PM2 restart "$PM2_NAME_WEBSITE" --update-env
|
||||
else
|
||||
PORT=$SSR_PORT $PM2 start "$NODE" --name "$PM2_NAME_WEBSITE" -- server.js
|
||||
fi
|
||||
fi
|
||||
|
||||
# F. Cleanup & Save PM2
|
||||
rm -rf "$TEMP_DIR"
|
||||
$PM2 save
|
||||
|
||||
echo "===== ✅ Deployment Completed Successfully! ====="
|
||||
$PM2 list
|
||||
Reference in new issue
Block a user