From 65281a734a8a42793220aec1ff72902701d74013 Mon Sep 17 00:00:00 2001 From: eafonyang Date: Tue, 11 Aug 2026 16:45:25 +0800 Subject: [PATCH] =?UTF-8?q?=E9=83=A8=E7=BD=B2=E6=AD=A3=E5=BC=8F=E7=8E=AF?= =?UTF-8?q?=E5=A2=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dashboard/docker-compose.yml | 2 ++ www/dist | 1 + www/docker-compose.yml | 28 +++++++++++++++++++++++++ www/nginx.conf | 40 ++++++++++++++++++++++++++++++++++++ www/nuxt.config.ts | 13 ++++++++---- www/scripts/deploy-www.sh | 38 ++++++++++++++++++++++++++++++++++ 6 files changed, 118 insertions(+), 4 deletions(-) create mode 120000 www/dist create mode 100644 www/docker-compose.yml create mode 100644 www/nginx.conf create mode 100755 www/scripts/deploy-www.sh diff --git a/dashboard/docker-compose.yml b/dashboard/docker-compose.yml index dba203e..8a98177 100644 --- a/dashboard/docker-compose.yml +++ b/dashboard/docker-compose.yml @@ -26,6 +26,8 @@ services: - "host.docker.internal:host-gateway" volumes: - /data/projects/source:/data/projects/source + # 素材库上传目录:容器内 /app/uploads ↔ 宿主机 /data/project/dashboard/backend/uploads + - /data/project/dashboard/frontend/dist/uploads:/app/uploads frontend: image: nginx:alpine diff --git a/www/dist b/www/dist new file mode 120000 index 0000000..bcd7dee --- /dev/null +++ b/www/dist @@ -0,0 +1 @@ +/Users/eafonyang/Developer/luxsin-admin/www/.output/public \ No newline at end of file diff --git a/www/docker-compose.yml b/www/docker-compose.yml new file mode 100644 index 0000000..107b807 --- /dev/null +++ b/www/docker-compose.yml @@ -0,0 +1,28 @@ +x-logging: &default-logging + driver: json-file + options: + max-size: "10m" + max-file: "5" + +services: + www: + image: nginx:alpine + container_name: www-frontend + ports: + # 宿主机 8081 → 容器 80 + - "8081:80" + volumes: + # Nuxt SPA 构建产物(nuxt build,ssr:false 时静态文件在 .output/public) + - /data/project/dashboard/www/.output/public:/usr/share/nginx/html:ro + - /data/project/dashboard/www/nginx.conf:/etc/nginx/conf.d/default.conf:ro + restart: unless-stopped + logging: *default-logging + networks: + # 复用 dashboard compose 创建的网络,容器内可用服务名 backend 访问 CMS API + - audio-network + +networks: + audio-network: + external: true + # dashboard compose(项目名 dashboard)创建的桥接网络 + name: dashboard_audio-network diff --git a/www/nginx.conf b/www/nginx.conf new file mode 100644 index 0000000..bc92851 --- /dev/null +++ b/www/nginx.conf @@ -0,0 +1,40 @@ +server { + listen 80; + server_name _; + + # Nuxt SPA 构建产物(nuxt build + ssr:false,静态文件位于 .output/public) + root /usr/share/nginx/html; + index index.html; + + client_max_body_size 50m; + gzip on; + gzip_types text/plain text/css application/json application/javascript image/svg+xml; + + # 带内容指纹的构建资源:长缓存(正则含 {},必须加引号避免被当作块定界符) + location ~* "\.[0-9a-f]{8}\.(js|css|png|jpg|jpeg|gif|webp|svg|woff2?)$" { + expires 365d; + add_header Cache-Control "public, immutable"; + try_files $uri =404; + } + + # SPA history 回退:i18n 英文前缀 /en 及各路由均由前端接管 + location / { + try_files $uri $uri/ /index.html; + } + + # CMS API 与素材静态文件:反代到 backend 容器(compose 网络内服务名解析) + location /api/ { + proxy_pass http://backend:8000; + proxy_http_version 1.1; + proxy_set_header Host $host; + 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; + } + + location /uploads/ { + proxy_pass http://backend:8000; + proxy_set_header Host $host; + expires 7d; + } +} diff --git a/www/nuxt.config.ts b/www/nuxt.config.ts index 2455621..0f713a6 100644 --- a/www/nuxt.config.ts +++ b/www/nuxt.config.ts @@ -6,10 +6,12 @@ export default defineNuxtConfig({ css: ['~/assets/css/main.css'], - // 运行时配置:NUXT_PUBLIC_API_BASE_URL / NUXT_PUBLIC_ASSET_BASE_URL 环境变量可覆盖 + // 生产构建(nuxt build/generate,NODE_ENV=production)走同源相对路径 /api,由 nginx 反代到 backend; + // 开发(pnpm dev)直连本地后端。显式传入的 NUXT_PUBLIC_* 环境变量仍可覆盖。 + // 注:Nuxt 默认只加载 .env,不会自动读 .env.production,故用 NODE_ENV 区分环境。 runtimeConfig: { public: { - apiBaseUrl: 'http://localhost:8083/api', + apiBaseUrl: process.env.NODE_ENV === 'production' ? '/api' : 'http://localhost:8083/api', // 素材静态服务地址(用于解析 /uploads/... 相对路径),为空时默认取 apiBaseUrl 的 origin assetBaseUrl: '' } @@ -24,8 +26,11 @@ export default defineNuxtConfig({ ], langDir: 'locales', defaultLocale: 'zh', - // SEO 标签(canonical / hreflang)所需的站点基础 URL,部署时通过环境变量配置 - baseUrl: process.env.NUXT_PUBLIC_SITE_URL || 'http://localhost:3100', + // SEO 标签(canonical / hreflang)所需的站点基础 URL:显式 NUXT_PUBLIC_SITE_URL 优先, + // 否则生产默认正式域名、开发默认本地 dev 地址 + baseUrl: + process.env.NUXT_PUBLIC_SITE_URL || + (process.env.NODE_ENV === 'production' ? 'https://www.luxsin.com.cn' : 'http://localhost:3100'), strategy: 'prefix_except_default', detectBrowserLanguage: { useCookie: true, diff --git a/www/scripts/deploy-www.sh b/www/scripts/deploy-www.sh new file mode 100755 index 0000000..82c68cb --- /dev/null +++ b/www/scripts/deploy-www.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# ============================================================ +# www 部署脚本:上传构建产物与部署配置到正式服务器 +# 上传内容:.output/public/、nginx.conf、docker-compose.yml +# 目标:luxsin-api2:/data/project/dashboard/www +# 用法:./scripts/deploy-www.sh +# ============================================================ +set -euo pipefail + +REMOTE_HOST="luxsin-api2" +REMOTE_DIR="/data/project/dashboard/www" + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +WWW_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)" + +# 本地需先完成静态构建(nuxt generate,ssr:false 产出 .output/public/index.html) +if [ ! -f "${WWW_DIR}/.output/public/index.html" ]; then + echo "❌ 本地缺少 ${WWW_DIR}/.output/public/index.html,请先执行:" + echo " cd ${WWW_DIR} && pnpm generate" + exit 1 +fi + +echo "==> 确保远程目录存在" +ssh "${REMOTE_HOST}" "mkdir -p ${REMOTE_DIR}/.output/public" + +echo "==> 同步 .output/public/(--delete:删除远端已失效的旧产物)" +rsync -avz --delete -e ssh \ + "${WWW_DIR}/.output/public/" "${REMOTE_HOST}:${REMOTE_DIR}/.output/public/" + +echo "==> 上传 nginx.conf / docker-compose.yml" +rsync -avz -e ssh \ + "${WWW_DIR}/nginx.conf" \ + "${WWW_DIR}/docker-compose.yml" \ + "${REMOTE_HOST}:${REMOTE_DIR}/" + +echo "✅ 上传完成:${REMOTE_HOST}:${REMOTE_DIR}" +echo "下一步(在服务器上执行):" +echo " cd ${REMOTE_DIR} && docker compose up -d"