部署调整

This commit is contained in:
2026-09-01 23:11:14 +08:00
parent 1bcbb23281
commit 26c982ec74
10 changed files with 101 additions and 18 deletions
+20
View File
@@ -0,0 +1,20 @@
error: externally-managed-environment
× This environment is externally managed
╰─> To install Python packages system-wide, try apt install
python3-xyz, where xyz is the package you are trying to
install.
If you wish to install a non-Debian-packaged Python package,
create a virtual environment using python3 -m venv path/to/venv.
Then use path/to/venv/bin/python and path/to/venv/bin/pip. Make
sure you have python3-full installed.
If you wish to install a non-Debian packaged Python application,
it may be easiest to use pipx install xyz, which will manage a
virtual environment for you. Make sure you have pipx installed.
See /usr/share/doc/python3.12/README.venv for more information.
note: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages.
hint: See PEP 668 for the detailed specification.
+3 -1
View File
@@ -6,7 +6,9 @@ WORKDIR /app
# 依赖单独成层,利用缓存 # 依赖单独成层,利用缓存
COPY requirements.txt ./requirements.txt COPY requirements.txt ./requirements.txt
RUN pip install --no-cache-dir -r requirements.txt RUN pip install --no-cache-dir --timeout 120 --retries 5 \
-i https://pypi.tuna.tsinghua.edu.cn/simple \
-r requirements.txt
# 后端源码 # 后端源码
COPY app ./app COPY app ./app
+4
View File
@@ -29,5 +29,9 @@ class Settings:
REDIS_DB: int = int(os.getenv("REDIS_DB", "0")) REDIS_DB: int = int(os.getenv("REDIS_DB", "0"))
REDIS_PASSWORD: str = os.getenv("REDIS_PASSWORD", "digiwin") REDIS_PASSWORD: str = os.getenv("REDIS_PASSWORD", "digiwin")
# 反向代理路径前缀(让 Swagger / OpenAPI 在带前缀的代理后正确生成 URL)
# 生产经外层 nginx 暴露在 https://<host>/mcp-auth-api/ 下时设为 /mcp-auth-api;直连 8003 时留空
ROOT_PATH: str = os.getenv("ROOT_PATH", "")
settings = Settings() settings = Settings()
+3
View File
@@ -32,6 +32,9 @@ app = FastAPI(
title="MCP Auth Admin", title="MCP Auth Admin",
description="MCP 服务 Bearer Token 动态鉴权管理后台", description="MCP 服务 Bearer Token 动态鉴权管理后台",
version="1.0.0", version="1.0.0",
# 反向代理路径前缀:带前缀的外层 nginx(如 /mcp-auth-api)后,
# OpenAPI servers 与 Swagger 加载的 openapi.json 会带上该前缀,文档才能正确渲染
root_path=settings.ROOT_PATH,
lifespan=lifespan, lifespan=lifespan,
) )
+2
View File
@@ -25,4 +25,6 @@ services:
- REDIS_PORT=${REDIS_PORT:-6379} - REDIS_PORT=${REDIS_PORT:-6379}
- REDIS_DB=${REDIS_DB:-0} - REDIS_DB=${REDIS_DB:-0}
- REDIS_PASSWORD=${REDIS_PASSWORD:-digiwin} - REDIS_PASSWORD=${REDIS_PASSWORD:-digiwin}
# 外层反向代理路径前缀(/mcp-auth-api/docs 文档正常渲染所需)
- ROOT_PATH=${ROOT_PATH:-/mcp-auth-api}
restart: unless-stopped restart: unless-stopped
+55 -9
View File
@@ -10,6 +10,54 @@ server {
gzip_types text/plain text/css application/json application/javascript text/xml application/xml text/javascript image/svg+xml; gzip_types text/plain text/css application/json application/javascript text/xml application/xml text/javascript image/svg+xml;
gzip_min_length 256; gzip_min_length 256;
# ── /mcp-admin 子路径(外部 nginx 不剥离前缀,需在此处理)──
# 后端 API 反向代理(/mcp-admin/api/ → 后端 /api/)
location /mcp-admin/api/ {
proxy_pass ${BACKEND_URL}/api/;
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;
add_header Cache-Control "no-cache, no-store, must-revalidate" always;
add_header Pragma "no-cache" always;
}
# 健康检查
location /mcp-admin/health {
proxy_pass ${BACKEND_URL}/api/health;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# 鼎捷云 IAM 登录服务反向代理(/mcp-admin/iam-api/ → iam.digiwincloud.com.cn/)
location /mcp-admin/iam-api/ {
proxy_pass https://iam.digiwincloud.com.cn/;
proxy_set_header Host iam.digiwincloud.com.cn;
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_ssl_server_name on;
add_header Cache-Control "no-cache, no-store, must-revalidate" always;
add_header Pragma "no-cache" always;
}
# 静态资源长缓存(Vite 构建产物带 hash,/mcp-admin/assets/ → /assets/)
location /mcp-admin/assets/ {
alias /usr/share/nginx/html/assets/;
expires 1y;
add_header Cache-Control "public, immutable";
}
# SPA 路由 fallback:/mcp-admin 下的非文件请求回退到 index.html
location /mcp-admin/ {
try_files $uri $uri/ /index.html;
}
# ── 根路径(直接访问容器时使用)──
# 后端 API 反向代理 # 后端 API 反向代理
location /api/ { location /api/ {
proxy_pass ${BACKEND_URL}/api/; proxy_pass ${BACKEND_URL}/api/;
@@ -18,7 +66,6 @@ server {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $scheme;
# 禁止浏览器缓存 API 响应
add_header Cache-Control "no-cache, no-store, must-revalidate" always; add_header Cache-Control "no-cache, no-store, must-revalidate" always;
add_header Pragma "no-cache" always; add_header Pragma "no-cache" always;
} }
@@ -30,7 +77,7 @@ server {
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
} }
# 鼎捷云 IAM 登录服务反向代理(与 vite.config.ts 中 /iam-api 代理一致) # 鼎捷云 IAM 登录服务反向代理
location /iam-api/ { location /iam-api/ {
proxy_pass https://iam.digiwincloud.com.cn/; proxy_pass https://iam.digiwincloud.com.cn/;
proxy_set_header Host iam.digiwincloud.com.cn; proxy_set_header Host iam.digiwincloud.com.cn;
@@ -39,17 +86,11 @@ server {
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $scheme;
proxy_ssl_server_name on; proxy_ssl_server_name on;
# 禁止浏览器缓存 API 响应
add_header Cache-Control "no-cache, no-store, must-revalidate" always; add_header Cache-Control "no-cache, no-store, must-revalidate" always;
add_header Pragma "no-cache" always; add_header Pragma "no-cache" always;
} }
# SPA 路由 fallback:所有非文件请求回退到 index.html # 静态资源长缓存
location / {
try_files $uri $uri/ /index.html;
}
# 静态资源长缓存(Vite 构建产物带 hash)
location /assets/ { location /assets/ {
expires 1y; expires 1y;
add_header Cache-Control "public, immutable"; add_header Cache-Control "public, immutable";
@@ -60,4 +101,9 @@ server {
expires 30d; expires 30d;
add_header Cache-Control "public"; add_header Cache-Control "public";
} }
# SPA 路由 fallback
location / {
try_files $uri $uri/ /index.html;
}
} }
+3 -3
View File
@@ -2,7 +2,7 @@ import axios from 'axios';
import { APP_TOKEN } from '../services/iamAuth'; import { APP_TOKEN } from '../services/iamAuth';
const api = axios.create({ const api = axios.create({
baseURL: '/api', baseURL: `${import.meta.env.BASE_URL}api`,
timeout: 15000, timeout: 15000,
}); });
@@ -22,10 +22,10 @@ api.interceptors.response.use(
(err) => { (err) => {
if (err.response?.status === 401) { if (err.response?.status === 401) {
const path = window.location.pathname; const path = window.location.pathname;
if (path !== '/login' && !path.startsWith('/sso-login')) { if (path !== `${import.meta.env.BASE_URL}login` && !path.startsWith(`${import.meta.env.BASE_URL}sso-login`)) {
sessionStorage.removeItem('userToken'); sessionStorage.removeItem('userToken');
sessionStorage.removeItem('userInfo'); sessionStorage.removeItem('userInfo');
window.location.href = '/login'; window.location.href = `${import.meta.env.BASE_URL}login`;
} }
} }
return Promise.reject(err); return Promise.reject(err);
+1 -1
View File
@@ -9,7 +9,7 @@ import 'antd/dist/reset.css';
ReactDOM.createRoot(document.getElementById('root')!).render( ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode> <React.StrictMode>
<ConfigProvider locale={zhCN}> <ConfigProvider locale={zhCN}>
<BrowserRouter> <BrowserRouter basename={import.meta.env.BASE_URL.replace(/\/$/, "")}>
<App /> <App />
</BrowserRouter> </BrowserRouter>
</ConfigProvider> </ConfigProvider>
+1 -1
View File
@@ -13,7 +13,7 @@ import { JSEncrypt } from 'jsencrypt';
*/ */
// 代理路径(vite.config.ts 中 /iam-api → https://iam.digiwincloud.com.cn) // 代理路径(vite.config.ts 中 /iam-api → https://iam.digiwincloud.com.cn)
const IAM_API_BASE = '/iam-api/api/iam/v2'; const IAM_API_BASE = `${import.meta.env.BASE_URL}iam-api/api/iam/v2`;
const IAM_IDENTITY_BASE = `${IAM_API_BASE}/identity`; const IAM_IDENTITY_BASE = `${IAM_API_BASE}/identity`;
// 应用 apptoken(digi-middleware-auth-app) // 应用 apptoken(digi-middleware-auth-app)
+9 -3
View File
@@ -3,15 +3,21 @@ import react from '@vitejs/plugin-react'
export default defineConfig({ export default defineConfig({
plugins: [react()], plugins: [react()],
base: '/mcp-admin/',
server: { server: {
port: 5173, port: 5173,
proxy: { proxy: {
'/api': 'https://ai-workshop.digiwincloud.com.cn/mcp-auth-api', // 生产部署在 /mcp-admin 子路径下,dev 代理路径也需带前缀
'/mcp-admin/api': {
target: 'https://ai-workshop.digiwincloud.com.cn/mcp-auth-api',
changeOrigin: true,
rewrite: (p) => p.replace(/^\/mcp-admin/, ''),
},
// 鼎捷云 IAM 登录服务代理(避免 CORS / 网络问题) // 鼎捷云 IAM 登录服务代理(避免 CORS / 网络问题)
'/iam-api': { '/mcp-admin/iam-api': {
target: 'https://iam.digiwincloud.com.cn', target: 'https://iam.digiwincloud.com.cn',
changeOrigin: true, changeOrigin: true,
rewrite: (p) => p.replace(/^\/iam-api/, ''), rewrite: (p) => p.replace(/^\/mcp-admin\/iam-api/, ''),
}, },
}, },
}, },