rename: hunhin → huahin (domain correction to huahin.propkk.com)
This commit is contained in:
1 parent
1dbc378bdb
commit
df5a22c512
7 files changed
+480
No files matched your search
@@ -0,0 +1,184 @@
|
||||
# HuaHin Deployment Runbook
|
||||
|
||||
เอกสารนี้เป็น runbook เฉพาะลูกค้า `huahin` โดยอิงจาก `DEPLOYMENT_GUIDE.md` และไฟล์ตัวอย่างใน `serverinfo/ddc-*`
|
||||
|
||||
## Target
|
||||
|
||||
- Project name: `huahin`
|
||||
- Website: `https://huahin.propkk.com`
|
||||
- SPA: `https://spa.huahin.propkk.com`
|
||||
- Admin: `https://admin.huahin.propkk.com`
|
||||
- API: `https://api.huahin.propkk.com`
|
||||
- Database: `huahindb`
|
||||
- Website SSR port: `3007`
|
||||
- Backend API port: `3056`
|
||||
- Bare repo: `/home/ti/git/huahin-website.git`
|
||||
- Backend path: `/home/ti/projects/huahin-api`
|
||||
- Website path: `/home/ti/projects/huahin-website`
|
||||
- SPA static path: `/home/ti/projects/MyNginxMain/nginx/html/huahin/spa`
|
||||
- Admin static path: `/home/ti/projects/MyNginxMain/nginx/html/huahin/admin`
|
||||
|
||||
## Files Prepared In This Repo
|
||||
|
||||
- `serverinfo/huahin-post-receive`
|
||||
- `serverinfo/huahin-backend.env.example`
|
||||
- `serverinfo/huahin-nginx/huahin.propkk.com.conf`
|
||||
- `serverinfo/huahin-nginx/spa.huahin.propkk.com.conf`
|
||||
- `serverinfo/huahin-nginx/admin.huahin.propkk.com.conf`
|
||||
- `serverinfo/huahin-nginx/api.huahin.propkk.com.conf`
|
||||
|
||||
## Preflight On Server
|
||||
|
||||
Run on `kitizone.com` before changing live services:
|
||||
|
||||
```bash
|
||||
ss -ltnp | grep -E ':3007|:3056' || true
|
||||
pm2 list
|
||||
```
|
||||
|
||||
If ports `3007` or `3056` are already used, stop and choose new ports before applying these files.
|
||||
|
||||
## 1. Create Bare Git Repository
|
||||
|
||||
```bash
|
||||
mkdir -p /home/ti/git/huahin-website.git
|
||||
cd /home/ti/git/huahin-website.git
|
||||
git init --bare
|
||||
```
|
||||
|
||||
## 2. Create Project Directories
|
||||
|
||||
```bash
|
||||
mkdir -p /home/ti/projects/huahin-api
|
||||
mkdir -p /home/ti/projects/huahin-website
|
||||
mkdir -p /home/ti/projects/MyNginxMain/nginx/html/huahin/spa
|
||||
mkdir -p /home/ti/projects/MyNginxMain/nginx/html/huahin/admin
|
||||
```
|
||||
|
||||
## 3. Create Database
|
||||
|
||||
```bash
|
||||
docker exec -it arokro_postgres bash
|
||||
psql -U postgres -c "CREATE DATABASE huahindb;"
|
||||
exit
|
||||
```
|
||||
|
||||
## 4. Open Firewall Ports
|
||||
|
||||
```bash
|
||||
sudo ufw allow 3007/tcp
|
||||
sudo ufw allow 3056/tcp
|
||||
sudo ufw reload
|
||||
```
|
||||
|
||||
## 5. Request SSL Certificates
|
||||
|
||||
```bash
|
||||
cd /home/ti/projects/MyNginxMain
|
||||
docker compose stop nginx
|
||||
|
||||
docker compose run --rm certbot certonly --standalone \
|
||||
-d huahin.propkk.com \
|
||||
-d spa.huahin.propkk.com \
|
||||
-d admin.huahin.propkk.com \
|
||||
-d api.huahin.propkk.com
|
||||
```
|
||||
|
||||
## 6. Install Nginx Configs
|
||||
|
||||
Copy files from `serverinfo/huahin-nginx/` to:
|
||||
|
||||
```text
|
||||
/home/ti/projects/MyNginxMain/nginx/conf.d/
|
||||
```
|
||||
|
||||
Then validate and restart nginx:
|
||||
|
||||
```bash
|
||||
cd /home/ti/projects/MyNginxMain
|
||||
docker compose run --rm nginx nginx -t
|
||||
docker compose up -d nginx
|
||||
```
|
||||
|
||||
## 7. Install Backend Environment File
|
||||
|
||||
Create this server file:
|
||||
|
||||
```text
|
||||
/home/ti/projects/huahin-api/.env
|
||||
```
|
||||
|
||||
Use `serverinfo/huahin-backend.env.example` as the base and replace placeholders before production use:
|
||||
|
||||
- `postgres:password` must match the real Postgres password.
|
||||
- `JWT_SECRET` must be a new project-specific secret.
|
||||
- `OMISE_SECRET_KEY` must be set if payments are enabled.
|
||||
|
||||
The deploy hook copies this file into `/home/ti/projects/huahin-api/apps/backend/.env` before Prisma commands.
|
||||
|
||||
## 8. Install Git Hook
|
||||
|
||||
Copy:
|
||||
|
||||
```text
|
||||
serverinfo/huahin-post-receive
|
||||
```
|
||||
|
||||
To:
|
||||
|
||||
```text
|
||||
/home/ti/git/huahin-website.git/hooks/post-receive
|
||||
```
|
||||
|
||||
Then run:
|
||||
|
||||
```bash
|
||||
chmod +x /home/ti/git/huahin-website.git/hooks/post-receive
|
||||
```
|
||||
|
||||
## 9. Deploy From Developer Machine
|
||||
|
||||
```bash
|
||||
git remote add huahin-website ti@kitizone.com:/home/ti/git/huahin-website.git
|
||||
git push huahin-website master
|
||||
```
|
||||
|
||||
## 10. Seed Database
|
||||
|
||||
Run after the first successful deployment:
|
||||
|
||||
```bash
|
||||
ssh ti@kitizone.com
|
||||
cd /home/ti/projects/huahin-api/apps/backend
|
||||
export PATH=$PATH:/home/ti/.bun/bin:/home/ti/.nvm/versions/node/v22.17.1/bin
|
||||
bun run prisma/seed.cjs
|
||||
```
|
||||
|
||||
Default seeded admin account is currently `admin / homaroma123`. Change it before handing production access to the customer.
|
||||
|
||||
## Verification
|
||||
|
||||
```bash
|
||||
pm2 list
|
||||
curl -I https://huahin.propkk.com
|
||||
curl -I https://spa.huahin.propkk.com
|
||||
curl -I https://admin.huahin.propkk.com
|
||||
curl -I https://api.huahin.propkk.com
|
||||
```
|
||||
|
||||
Expected PM2 processes:
|
||||
|
||||
- `huahin-backend`
|
||||
- `huahin-website`
|
||||
|
||||
Check browser console for:
|
||||
|
||||
- CORS errors on admin and SPA
|
||||
- missing static assets
|
||||
- API 504 from website SSR build or runtime fetches
|
||||
|
||||
## Known Risks
|
||||
|
||||
- `serverinfo/huahin-post-receive` rewrites `ecosystem.config.js` at deploy time from the base `homaroma` config. This follows the existing `pkh`/`ddc` pattern.
|
||||
- The codebase still contains some hardcoded HomAroma URLs and storage keys in app code. This runbook only prepares infrastructure deployment, not full white-label branding cleanup.
|
||||
- Payments and LINE LIFF need customer-specific production keys before launch.
|
||||
@@ -0,0 +1,8 @@
|
||||
PORT=3056
|
||||
DATABASE_URL="postgresql://postgres:password@localhost:5132/huahindb?schema=public"
|
||||
NODE_ENV=production
|
||||
APP_URL="https://api.huahin.propkk.com"
|
||||
BACKEND_PUBLIC_URL="https://api.huahin.propkk.com"
|
||||
CORS_ORIGIN="https://admin.huahin.propkk.com,https://spa.huahin.propkk.com,https://huahin.propkk.com"
|
||||
JWT_SECRET="replace-with-huahin-production-secret"
|
||||
OMISE_SECRET_KEY=""
|
||||
@@ -0,0 +1,31 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name admin.huahin.propkk.com;
|
||||
|
||||
location /.well-known/acme-challenge/ {
|
||||
root /var/www/certbot;
|
||||
}
|
||||
location / {
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name admin.huahin.propkk.com;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/admin.huahin.propkk.com/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/admin.huahin.propkk.com/privkey.pem;
|
||||
|
||||
root /usr/share/nginx/html/huahin/admin;
|
||||
index index.html index.htm;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||
expires max;
|
||||
log_not_found off;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name api.huahin.propkk.com;
|
||||
|
||||
location /.well-known/acme-challenge/ {
|
||||
root /var/www/certbot;
|
||||
}
|
||||
location / {
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name api.huahin.propkk.com;
|
||||
|
||||
client_max_body_size 20m;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/api.huahin.propkk.com/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/api.huahin.propkk.com/privkey.pem;
|
||||
|
||||
location / {
|
||||
proxy_pass http://192.168.1.167:3056;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection 'upgrade';
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name huahin.propkk.com;
|
||||
|
||||
location /.well-known/acme-challenge/ {
|
||||
root /var/www/certbot;
|
||||
}
|
||||
location / {
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name huahin.propkk.com;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/huahin.propkk.com/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/huahin.propkk.com/privkey.pem;
|
||||
|
||||
location / {
|
||||
proxy_pass http://192.168.1.167:3007;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection 'upgrade';
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_cache_bypass $http_upgrade;
|
||||
}
|
||||
|
||||
location /_next/static/ {
|
||||
proxy_pass http://192.168.1.167:3007;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
add_header Cache-Control "public, max-age=31536000, immutable";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name spa.huahin.propkk.com;
|
||||
|
||||
location /.well-known/acme-challenge/ {
|
||||
root /var/www/certbot;
|
||||
}
|
||||
location / {
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name spa.huahin.propkk.com;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/spa.huahin.propkk.com/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/spa.huahin.propkk.com/privkey.pem;
|
||||
|
||||
root /usr/share/nginx/html/huahin/spa;
|
||||
index index.html index.htm;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||
expires max;
|
||||
log_not_found off;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ==============================================================================
|
||||
# HuaHin Project - Integrated Deployment Script (post-receive hook)
|
||||
# ==============================================================================
|
||||
|
||||
# 1. TARGET PATHS (Nginx & PM2)
|
||||
TARGET_SPA="/home/ti/projects/MyNginxMain/nginx/html/huahin/spa"
|
||||
TARGET_ADMIN="/home/ti/projects/MyNginxMain/nginx/html/huahin/admin"
|
||||
TARGET_BACKEND="/home/ti/projects/huahin-api"
|
||||
TARGET_WEBSITE="/home/ti/projects/huahin-website"
|
||||
|
||||
# 2. REPOSITORY CONFIG
|
||||
REPO="/home/ti/git/huahin-website.git"
|
||||
BRANCH="master"
|
||||
TEMP_DIR="/tmp/huahin_build_$(date +%s)"
|
||||
|
||||
# 3. BINARY PATHS & PM2
|
||||
BUN="/home/ti/.bun/bin/bun"
|
||||
PM2="/home/ti/.nvm/versions/node/v22.17.1/bin/pm2"
|
||||
PM2_NAME_BACKEND="huahin-backend"
|
||||
PM2_NAME_WEBSITE="huahin-website"
|
||||
export PATH="$PATH:/home/ti/.bun/bin:/home/ti/.nvm/versions/node/v22.17.1/bin"
|
||||
|
||||
# 4. BUILD ENVIRONMENT
|
||||
export VITE_API_URL="https://api.huahin.propkk.com/api"
|
||||
export NEXT_PUBLIC_API_URL="https://api.huahin.propkk.com/api"
|
||||
|
||||
# Customer-specific values. Fill these in on the server if enabled.
|
||||
export VITE_LIFF_ID="${VITE_LIFF_ID:-}"
|
||||
export VITE_OMISE_PUBLIC_KEY="${VITE_OMISE_PUBLIC_KEY:-}"
|
||||
|
||||
# Service ports. Nginx proxies to these ports.
|
||||
BACKEND_PORT=3056
|
||||
SSR_PORT=3007
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# START DEPLOYMENT
|
||||
# ------------------------------------------------------------------------------
|
||||
set -e
|
||||
echo "------- Starting Full Deployment: HuaHin Platform -------"
|
||||
|
||||
# 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..."
|
||||
$BUN install
|
||||
|
||||
# B. Build & Deploy SPA
|
||||
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 ../..
|
||||
|
||||
# C. Build & Deploy ADMIN PANEL
|
||||
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 ../..
|
||||
|
||||
# D. Deploy & Manage BACKEND (API)
|
||||
echo ">>> Updating Backend at $TARGET_BACKEND..."
|
||||
mkdir -p $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/
|
||||
sed -i 's/homaroma/huahin/g' $TARGET_BACKEND/ecosystem.config.js
|
||||
sed -i 's/PORT: 3002/PORT: 3007/g' $TARGET_BACKEND/ecosystem.config.js
|
||||
|
||||
cd $TARGET_BACKEND
|
||||
echo "Installing backend dependencies..."
|
||||
$BUN install
|
||||
|
||||
mkdir -p $TARGET_BACKEND/apps/backend/public
|
||||
|
||||
cd $TARGET_BACKEND/apps/backend
|
||||
|
||||
echo ">>> Generating Prisma Client..."
|
||||
$BUN x prisma generate
|
||||
|
||||
if [ ! -f "$TARGET_BACKEND/.env" ]; then
|
||||
echo "Error: .env file is missing at $TARGET_BACKEND/.env. Deployment aborted."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cp "$TARGET_BACKEND/.env" "$TARGET_BACKEND/apps/backend/.env"
|
||||
echo ">>> Running Prisma Migrate Deploy..."
|
||||
$BUN x prisma migrate deploy
|
||||
|
||||
# E. PM2 Management - BACKEND
|
||||
echo ">>> Managing PM2 Process: $PM2_NAME_BACKEND..."
|
||||
$PM2 startOrReload $TARGET_BACKEND/ecosystem.config.js --only $PM2_NAME_BACKEND --env production --update-env
|
||||
echo "PM2 process '$PM2_NAME_BACKEND' is running. Waiting 10s for it to fully start..."
|
||||
sleep 10
|
||||
|
||||
# F. Build & Deploy WEBSITE (Next.js SSR)
|
||||
echo ">>> Building Next.js SSR App inside monorepo temp dir..."
|
||||
cd $TEMP_DIR/apps/website
|
||||
$BUN run build
|
||||
|
||||
# G. Prepare Next.js SSR
|
||||
echo ">>> Preparing Next.js SSR App..."
|
||||
rsync -av --delete \
|
||||
$TEMP_DIR/apps/website/.next/standalone/ $TARGET_WEBSITE/
|
||||
rsync -av \
|
||||
$TEMP_DIR/apps/website/public/ $TARGET_WEBSITE/apps/website/public/
|
||||
rsync -av \
|
||||
$TEMP_DIR/apps/website/.next/static/ $TARGET_WEBSITE/apps/website/.next/static/
|
||||
|
||||
cp $TEMP_DIR/ecosystem.config.js $TARGET_WEBSITE/
|
||||
sed -i 's/homaroma/huahin/g' $TARGET_WEBSITE/ecosystem.config.js
|
||||
sed -i 's/PORT: 3002/PORT: 3007/g' $TARGET_WEBSITE/ecosystem.config.js
|
||||
|
||||
# H. Fix Permissions
|
||||
echo ">>> Fixing Permissions..."
|
||||
chown -R ti:ti $TARGET_BACKEND $TARGET_WEBSITE
|
||||
|
||||
# I. PM2 Management - SSR Next.js
|
||||
cd $TARGET_WEBSITE
|
||||
echo ">>> Creating symlink for .next..."
|
||||
ln -sf apps/website/.next .next
|
||||
echo ">>> Managing PM2 Process: $PM2_NAME_WEBSITE..."
|
||||
$PM2 startOrReload $TARGET_WEBSITE/ecosystem.config.js --only $PM2_NAME_WEBSITE --env production --update-env
|
||||
echo "PM2 process '$PM2_NAME_WEBSITE' is running."
|
||||
|
||||
# J. Cleanup
|
||||
echo "Cleaning up build artifacts..."
|
||||
rm -rf $TEMP_DIR
|
||||
|
||||
echo "------- ALL DEPLOYMENTS COMPLETED SUCCESSFULLY -------"
|
||||
echo ""
|
||||
echo "Service Summary:"
|
||||
echo " Website (SSR) -> https://huahin.propkk.com (PM2: $PM2_NAME_WEBSITE, Port: $SSR_PORT)"
|
||||
echo " SPA -> https://spa.huahin.propkk.com"
|
||||
echo " Admin Panel -> https://admin.huahin.propkk.com"
|
||||
echo " API Backend -> https://api.huahin.propkk.com (PM2: $PM2_NAME_BACKEND, Port: $BACKEND_PORT)"
|
||||
Reference in new issue
Block a user