chore: restore initial vtuber source snapshot

This commit is contained in:
ogt
2026-07-03 00:36:01 +08:00
commit 17f0c8c8ff
85 changed files with 7677 additions and 0 deletions

View File

@@ -0,0 +1,79 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ENV_FILE="${SCRIPT_DIR}/.env.prod"
if [ ! -f "${ENV_FILE}" ]; then
echo "❌ 找不到 deploy/.env.prod請先建立後再執行。"
exit 1
fi
source "${ENV_FILE}"
DEPLOY_HOST="${DEPLOY_HOST:-}"
DEPLOY_USER="${DEPLOY_USER:-}"
DEPLOY_PORT="${DEPLOY_PORT:-22}"
APP_DOMAIN="${APP_DOMAIN:-vtuber.wooo.work}"
NGINX_SERVER_CONFIG="${NGINX_SERVER_CONFIG:-}"
SNIPPET_SRC="${SCRIPT_DIR}/vtuber-nginx-110-live-fallback.conf"
SNIPPET_REMOTE="/etc/nginx/snippets/vtuber-nginx-110-live-fallback.conf"
if [ -z "${DEPLOY_HOST}" ] || [ -z "${DEPLOY_USER}" ]; then
echo "❌ deploy/.env.prod 缺少 DEPLOY_HOST / DEPLOY_USER"
exit 1
fi
REMOTE="${DEPLOY_USER}@${DEPLOY_HOST}"
SSH_OPTS=(-p "${DEPLOY_PORT}")
SCP_OPTS=(-P "${DEPLOY_PORT}")
NGINX_SNIPPET_TAG="vtuber-nginx-110-live-fallback.conf"
TMP_SNIPPET="/tmp/vtuber-nginx-110-live-fallback.conf"
if [ -z "${NGINX_SERVER_CONFIG}" ]; then
echo "未指定 NGINX_SERVER_CONFIG開始自動偵測..."
NGINX_SERVER_CONFIG="$(
ssh "${SSH_OPTS[@]}" "${REMOTE}" "
if [ -f '/etc/nginx/conf.d/vtuber.wooo.conf' ]; then
echo '/etc/nginx/conf.d/vtuber.wooo.conf'
elif [ -f \"/etc/nginx/sites-available/${APP_DOMAIN}\" ]; then
echo '/etc/nginx/sites-available/${APP_DOMAIN}'
elif [ -f '/etc/nginx/sites-enabled/vtuber.wooo.work' ]; then
echo '/etc/nginx/sites-enabled/vtuber.wooo.work'
else
grep -R -l \"server_name[[:space:]]\\+.*${APP_DOMAIN}\" /etc/nginx/sites-enabled /etc/nginx/sites-available /etc/nginx/conf.d 2>/dev/null | head -n 1
fi
"
)"
fi
if [ -z "${NGINX_SERVER_CONFIG}" ]; then
echo "❌ 無法自動找出 vtuber 的 nginx 設定檔,請手動指定 NGINX_SERVER_CONFIG 環境變數"
exit 1
fi
echo "目標主機:${REMOTE}"
echo "目標網域:${APP_DOMAIN}"
echo "目標 Nginx 設定:${NGINX_SERVER_CONFIG}"
ssh "${SSH_OPTS[@]}" "${REMOTE}" "test -f '${SNIPPET_REMOTE}' && sudo chmod 644 '${SNIPPET_REMOTE}' || true"
ssh "${SSH_OPTS[@]}" "${REMOTE}" "test -f '${NGINX_SERVER_CONFIG}' || { echo 'Nginx 設定檔不存在:${NGINX_SERVER_CONFIG}' >&2; exit 1; }"
scp "${SCP_OPTS[@]}" "${SNIPPET_SRC}" "${REMOTE}:${TMP_SNIPPET}"
ssh "${SSH_OPTS[@]}" "${REMOTE}" "sudo cp '${TMP_SNIPPET}' '${SNIPPET_REMOTE}' && sudo chmod 644 '${SNIPPET_REMOTE}'"
ssh "${SSH_OPTS[@]}" "${REMOTE}" "
set -euo pipefail
sudo cp '${NGINX_SERVER_CONFIG}' '${NGINX_SERVER_CONFIG}.bak.\$(date +%F_%H%M%S)'
if ! sudo grep -q '${NGINX_SNIPPET_TAG}' '${NGINX_SERVER_CONFIG}'; then
sudo sed -i '/^[[:space:]]*server_name[[:space:]]\\+[^;]*;/ a\\
include /etc/nginx/snippets/vtuber-nginx-110-live-fallback.conf;\\
' '${NGINX_SERVER_CONFIG}'
fi
sudo nginx -t
if command -v systemctl >/dev/null 2>&1; then
sudo systemctl reload nginx
else
sudo service nginx reload
fi
"
echo "✅ 110 Nginx 404 fallback 已提交。"

65
deploy/deploy-prod.sh Executable file
View File

@@ -0,0 +1,65 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
source "${SCRIPT_DIR}/.env.prod"
if [ -z "${DEPLOY_HOST:-}" ] || [ -z "${DEPLOY_USER:-}" ] || [ -z "${DEPLOY_DIR:-}" ]; then
echo "請先建立 deploy/.env.prod 並設定 DEPLOY_HOST / DEPLOY_USER / DEPLOY_DIR" >&2
exit 1
fi
SSH_OPTS=(-p "${DEPLOY_PORT:-22}")
REMOTE="${DEPLOY_USER}@${DEPLOY_HOST}"
echo "Preparing deployment content to ${REMOTE}:${DEPLOY_DIR}"
synced=0
if ssh "${SSH_OPTS[@]}" "$REMOTE" "[ -d \"${DEPLOY_DIR}/.git\" ]"; then
ssh "${SSH_OPTS[@]}" "$REMOTE" "
set -euo pipefail
cd \"${DEPLOY_DIR}\"
if git show-ref --verify --quiet \"refs/heads/${DEPLOY_BRANCH}\"; then
git fetch --all || true
git checkout \"${DEPLOY_BRANCH}\" || true
git pull origin \"${DEPLOY_BRANCH}\" || true
exit 0
else
echo \"[warn] 遠端 git 無法找到 ${DEPLOY_BRANCH},改用 rsync 同步部署檔案。\"\n
exit 1
fi
" && synced=1 || synced=0
# 分支存在但拉取失敗時fallback 改為 rsync
if [ ${synced} -ne 1 ]; then
ssh "${SSH_OPTS[@]}" "$REMOTE" "[ -d \"${DEPLOY_DIR}\" ] || mkdir -p \"${DEPLOY_DIR}\""
fi
else
synced=0
fi
if [ ${synced} -ne 1 ]; then
echo "遠端未完成 git 同步,改用 rsync 直接推送部署內容..."
rsync -av --delete \
--exclude 'node_modules' \
--exclude '.next' \
--exclude '.turbo' \
--exclude 'dist' \
--exclude 'coverage' \
--exclude '.env' \
--exclude '*.log' \
-e "ssh ${SSH_OPTS[*]}" \
"${ROOT_DIR}/" "$REMOTE:${DEPLOY_DIR}/"
fi
ssh "${SSH_OPTS[@]}" "$REMOTE" "
set -euo pipefail
cd \"${DEPLOY_DIR}\"
cp deploy/.env.prod .env
docker compose -f deploy/docker-compose.prod.yml --env-file deploy/.env.prod down || true
docker compose -f deploy/docker-compose.prod.yml --env-file deploy/.env.prod up -d --build
"
echo "VTuber production deploy sent to ${DEPLOY_USER}@${DEPLOY_HOST}"

View File

@@ -0,0 +1,69 @@
version: "3.9"
services:
db:
image: postgres:16
container_name: vtuber-db
environment:
- POSTGRES_DB=vtuber
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=vtuber_local_pwd
volumes:
- vtuber-pg-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres -d vtuber"]
interval: 5s
timeout: 5s
retries: 10
restart: always
api:
build:
context: ..
dockerfile: apps/api/Dockerfile
container_name: vtuber-api
depends_on:
db:
condition: service_healthy
environment:
- NODE_ENV=production
- PORT=${API_PORT:-4000}
- DATABASE_URL=${DATABASE_URL}
ports:
- "${API_PORT:-4000}:4000"
restart: always
web:
build:
context: ..
dockerfile: apps/web/Dockerfile
container_name: vtuber-web
depends_on:
- api
environment:
- NODE_ENV=production
- NEXT_PUBLIC_API_BASE_URL=http://api:4000/api
- NEXT_PUBLIC_APP_DOMAIN=${APP_DOMAIN}
- PORT=3000
ports:
- "${WEB_PORT:-3200}:3000"
restart: always
admin:
build:
context: ..
dockerfile: apps/admin/Dockerfile
container_name: vtuber-admin
depends_on:
- api
environment:
- NODE_ENV=production
- NEXT_PUBLIC_API_BASE_URL=http://api:4000/api
- NEXT_PUBLIC_APP_DOMAIN=${APP_DOMAIN}
- PORT=3001
ports:
- "${ADMIN_PORT:-3201}:3001"
restart: always
volumes:
vtuber-pg-data:

View File

@@ -0,0 +1,11 @@
# 追加到正式主機前台 Nginx server 區塊內
# vtuber-nginx-110-live-fallback
# 功能:發生 404 時自動導回首頁,避免走錯 host/path 看到空白頁
# 引用方式:在 server { ... } 中加
# include /etc/nginx/snippets/vtuber-nginx-110-live-fallback.conf;
error_page 404 = @vtuber_live_demo_fallback;
location @vtuber_live_demo_fallback {
return 302 /live/demo;
}