refactor: 优化 Docker 部署配置

- 后端使用 uv 管理依赖,镜像内包含所有依赖
- 前端使用生产构建 + serve 提供静态文件
- 添加 WeasyPrint 完整系统依赖
- 修复 PDF 报告 Logo 显示问题
- 添加 .dockerignore 优化构建
- 更新部署文档和 GitHub Actions 工作流
- 前端端口从 5173 改为 3000
This commit is contained in:
lintsinghua 2025-12-05 20:51:22 +08:00
parent db3d8fd9f8
commit 33c4df9645
14 changed files with 220 additions and 249 deletions

View File

@ -115,10 +115,11 @@ jobs:
# 打包 Docker 配置文件 # 打包 Docker 配置文件
tar -czf release/xcodereviewer-docker-${{ steps.version.outputs.VERSION }}.tar.gz \ tar -czf release/xcodereviewer-docker-${{ steps.version.outputs.VERSION }}.tar.gz \
docker-compose.yml \ docker-compose.yml \
Dockerfile \
nginx.conf \
backend/Dockerfile \ backend/Dockerfile \
backend/.dockerignore \
frontend/Dockerfile \ frontend/Dockerfile \
frontend/.dockerignore \
frontend/docker-entrypoint.sh \
backend/env.example \ backend/env.example \
frontend/.env.example frontend/.env.example
@ -206,12 +207,12 @@ jobs:
- name: 设置 Docker Buildx - name: 设置 Docker Buildx
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v3
# 16. 构建并推送前端 Docker 镜像(生产环境 Nginx # 16. 构建并推送前端 Docker 镜像
- name: 构建并推送前端 Docker 镜像 - name: 构建并推送前端 Docker 镜像
uses: docker/build-push-action@v5 uses: docker/build-push-action@v5
with: with:
context: . context: ./frontend
file: ./Dockerfile file: ./frontend/Dockerfile
push: true push: true
platforms: linux/amd64,linux/arm64 platforms: linux/amd64,linux/arm64
tags: | tags: |

View File

@ -1,35 +0,0 @@
# 多阶段构建 - 构建阶段
FROM node:20-alpine AS builder
# 设置工作目录
WORKDIR /app
# 安装 pnpm
RUN npm install -g pnpm
# 复制前端项目文件
COPY frontend/package.json frontend/pnpm-lock.yaml ./
# 安装依赖
RUN pnpm install --frozen-lockfile
# 复制前端源代码
COPY frontend/ .
# 构建应用
RUN pnpm build
# 生产阶段 - 使用 nginx 提供静态文件服务
FROM nginx:alpine
# 复制自定义 nginx 配置
COPY nginx.conf /etc/nginx/conf.d/default.conf
# 从构建阶段复制构建产物
COPY --from=builder /app/dist /usr/share/nginx/html
# 暴露端口
EXPOSE 80
# 启动 nginx
CMD ["nginx", "-g", "daemon off;"]

View File

@ -95,7 +95,7 @@ cp backend/env.example backend/.env
docker-compose up -d docker-compose up -d
``` ```
🎉 **搞定!** 打开 http://localhost:5173 开始体验吧! 🎉 **搞定!** 打开 http://localhost:3000 开始体验吧!
### 演示账户 ### 演示账户

12
backend/.dockerignore Normal file
View File

@ -0,0 +1,12 @@
.venv
__pycache__
*.pyc
.git
.gitignore
*.md
.env
.vscode
.DS_Store
uploads/
.mypy_cache
.ruff_cache

View File

@ -4,37 +4,45 @@ WORKDIR /app
ENV PYTHONDONTWRITEBYTECODE=1 ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1 ENV PYTHONUNBUFFERED=1
ENV PIP_NO_CACHE_DIR=1 # 清除代理设置,避免容器内网络问题
ENV PIP_DISABLE_PIP_VERSION_CHECK=1 ENV http_proxy=
ENV https_proxy=
ENV HTTP_PROXY=
ENV HTTPS_PROXY=
# 安装系统依赖(包含 WeasyPrint 所需的库和中文字体支持) # 安装系统依赖(包含 WeasyPrint 所需的库和中文字体支持)
RUN for i in 1 2 3; do \ RUN rm -f /etc/apt/apt.conf.d/proxy.conf 2>/dev/null || true && \
unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY all_proxy ALL_PROXY && \
apt-get update && \ apt-get update && \
apt-get install -y --no-install-recommends \ apt-get install -y --no-install-recommends \
gcc \ gcc \
libpq-dev \ libpq-dev \
# WeasyPrint 依赖 curl \
# WeasyPrint 完整依赖
libpango-1.0-0 \ libpango-1.0-0 \
libpangoft2-1.0-0 \ libpangoft2-1.0-0 \
libpangocairo-1.0-0 \
libcairo2 \ libcairo2 \
libgdk-pixbuf2.0-0 \ libgdk-pixbuf-2.0-0 \
libffi-dev \ libffi-dev \
libglib2.0-0 \
shared-mime-info \ shared-mime-info \
# 字体支持(中文) # 字体支持(中文)
fonts-noto-cjk \ fonts-noto-cjk \
fonts-noto-cjk-extra \ fonts-noto-cjk-extra \
fontconfig \ fontconfig \
&& fc-cache -fv \ && fc-cache -fv \
&& rm -rf /var/lib/apt/lists/* \ && rm -rf /var/lib/apt/lists/*
&& break || sleep 5; \
done # 安装 uv
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
# 复制依赖文件 # 复制依赖文件
COPY pyproject.toml . COPY pyproject.toml uv.lock ./
COPY requirements.txt .
# 安装 Python 依赖 # 使用 uv 安装依赖(确保无代理)
RUN pip install --no-cache-dir -r requirements.txt RUN unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY all_proxy ALL_PROXY && \
uv sync --frozen --no-dev
# 复制应用代码 # 复制应用代码
COPY . . COPY . .

View File

@ -375,13 +375,18 @@ class ReportGenerator:
"""读取并编码 Logo 图片""" """读取并编码 Logo 图片"""
try: try:
current_dir = os.path.dirname(os.path.abspath(__file__)) current_dir = os.path.dirname(os.path.abspath(__file__))
# 回退三级到项目根目录: services -> app -> backend -> root # 尝试多个可能的路径
project_root = os.path.abspath(os.path.join(current_dir, '../../../')) possible_paths = [
logo_path = os.path.join(project_root, 'frontend/public/images/logo_nobg.png') # Docker 容器内路径
os.path.join(current_dir, '../../static/images/logo_nobg.png'),
# 本地开发路径
os.path.abspath(os.path.join(current_dir, '../../../frontend/public/images/logo_nobg.png')),
]
if os.path.exists(logo_path): for logo_path in possible_paths:
with open(logo_path, "rb") as image_file: if os.path.exists(logo_path):
return base64.b64encode(image_file.read()).decode('utf-8') with open(logo_path, "rb") as image_file:
return base64.b64encode(image_file.read()).decode('utf-8')
except Exception as e: except Exception as e:
print(f"Error loading logo: {e}") print(f"Error loading logo: {e}")
return "" return ""

Binary file not shown.

After

Width:  |  Height:  |  Size: 774 KiB

View File

@ -21,8 +21,7 @@ services:
build: build:
context: ./backend context: ./backend
volumes: volumes:
- ./backend:/app - backend_uploads:/app/uploads
- ./backend/uploads:/app/uploads
ports: ports:
- "8000:8000" - "8000:8000"
env_file: env_file:
@ -32,23 +31,19 @@ services:
depends_on: depends_on:
db: db:
condition: service_healthy condition: service_healthy
command: sh -c "alembic upgrade head && uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload" command: sh -c ".venv/bin/alembic upgrade head && .venv/bin/uvicorn app.main:app --host 0.0.0.0 --port 8000"
networks: networks:
- xcodereviewer-network - xcodereviewer-network
frontend: frontend:
build: build:
context: ./frontend context: ./frontend
volumes:
- ./frontend:/app
- /app/node_modules
ports: ports:
- "5173:5173" - "3000:3000"
environment: environment:
- VITE_API_BASE_URL=http://backend:8000/api/v1 - VITE_API_BASE_URL=http://localhost:8000/api/v1
depends_on: depends_on:
- backend - backend
command: npm run dev -- --host
networks: networks:
- xcodereviewer-network - xcodereviewer-network
@ -58,3 +53,4 @@ networks:
volumes: volumes:
postgres_data: postgres_data:
backend_uploads:

View File

@ -26,10 +26,10 @@ cp backend/env.example backend/.env
# 编辑 backend/.env配置 LLM API Key # 编辑 backend/.env配置 LLM API Key
# 3. 启动所有服务 # 3. 启动所有服务
docker-compose up -d docker compose up -d
# 4. 访问应用 # 4. 访问应用
# 前端: http://localhost:5173 # 前端: http://localhost:3000
# 后端 API: http://localhost:8000/docs # 后端 API: http://localhost:8000/docs
``` ```
@ -89,26 +89,26 @@ LLM_MODEL=gpt-4o-mini
```bash ```bash
# 3. 启动所有服务 # 3. 启动所有服务
docker-compose up -d docker compose up -d
# 4. 查看服务状态 # 4. 查看服务状态
docker-compose ps docker compose ps
# 5. 查看日志 # 5. 查看日志
docker-compose logs -f docker compose logs -f
``` ```
### 服务说明 ### 服务说明
| 服务 | 端口 | 说明 | | 服务 | 端口 | 说明 |
|------|------|------| |------|------|------|
| `frontend` | 5173 | React 前端应用(开发模式,支持热重载 | | `frontend` | 3000 | React 前端应用(生产构建,使用 serve 提供静态文件 |
| `backend` | 8000 | FastAPI 后端 API | | `backend` | 8000 | FastAPI 后端 API(使用 uv 管理依赖) |
| `db` | 5432 | PostgreSQL 15 数据库 | | `db` | 5432 | PostgreSQL 15 数据库 |
### 访问地址 ### 访问地址
- 前端应用: http://localhost:5173 - 前端应用: http://localhost:3000
- 后端 API: http://localhost:8000 - 后端 API: http://localhost:8000
- API 文档 (Swagger): http://localhost:8000/docs - API 文档 (Swagger): http://localhost:8000/docs
- API 文档 (ReDoc): http://localhost:8000/redoc - API 文档 (ReDoc): http://localhost:8000/redoc
@ -117,95 +117,70 @@ docker-compose logs -f
```bash ```bash
# 停止所有服务 # 停止所有服务
docker-compose down docker compose down
# 停止并删除数据卷(清除数据库) # 停止并删除数据卷(清除数据库)
docker-compose down -v docker compose down -v
# 重新构建镜像 # 重新构建镜像
docker-compose build --no-cache docker compose build --no-cache
# 查看特定服务日志 # 查看特定服务日志
docker-compose logs -f backend docker compose logs -f backend
# 进入容器调试 # 进入容器调试
docker-compose exec backend bash docker compose exec backend sh
docker-compose exec db psql -U postgres -d xcodereviewer docker compose exec db psql -U postgres -d xcodereviewer
``` ```
--- ---
## 生产环境部署 ## 生产环境部署
生产环境建议使用 Nginx 提供前端静态文件服务,并配置 HTTPS。 Docker Compose 默认配置已适用于生产环境:
### 方式一:使用预构建 Docker 镜像 - 前端:构建生产版本,使用 serve 提供静态文件服务
- 后端:使用 uv 管理依赖,镜像内包含所有依赖
- 数据库:使用 Docker Volume 持久化数据
```bash ### 生产环境安全建议
# 拉取最新镜像
docker pull ghcr.io/lintsinghua/xcodereviewer-frontend:latest
docker pull ghcr.io/lintsinghua/xcodereviewer-backend:latest
# 启动后端和数据库 1. **修改默认密钥**:务必修改 `SECRET_KEY` 为随机字符串
docker-compose up -d db backend 2. **配置 HTTPS**:使用 Nginx 反向代理并配置 SSL 证书
3. **限制 CORS**:在生产环境配置具体的前端域名
4. **数据库安全**:修改默认数据库密码,限制访问 IP
5. **API 限流**:配置 Nginx 或应用层限流
6. **日志监控**:配置日志收集和监控告警
7. **删除演示账户**:生产环境请删除或禁用 demo 账户
# 启动前端Nginx 生产镜像) ### Nginx 反向代理配置(可选)
docker run -d \
--name xcodereviewer-frontend \
-p 80:80 \
--network xcodereviewer-network \
ghcr.io/lintsinghua/xcodereviewer-frontend:latest
```
### 方式二:本地构建生产镜像 如需使用 Nginx 提供 HTTPS 和统一入口:
```bash
# 构建前端生产镜像(使用 Nginx
docker build -t xcodereviewer-frontend .
# 运行前端容器
docker run -d \
-p 80:80 \
--name xcodereviewer-frontend \
xcodereviewer-frontend
# 后端和数据库仍使用 docker-compose
docker-compose up -d db backend
```
### 方式三:手动部署
#### 前端部署
```bash
cd frontend
# 安装依赖
pnpm install
# 构建生产版本
pnpm build
# 将 dist 目录部署到 Nginx/Apache 等 Web 服务器
```
Nginx 配置示例:
```nginx ```nginx
server { server {
listen 80; listen 80;
server_name your-domain.com; server_name your-domain.com;
root /var/www/xcodereviewer/dist; return 301 https://$server_name$request_uri;
index index.html; }
# 前端路由支持 server {
listen 443 ssl http2;
server_name your-domain.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
# 前端
location / { location / {
try_files $uri $uri/ /index.html; proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
} }
# API 代理 # API 代理
location /api { location /api/ {
proxy_pass http://localhost:8000; proxy_pass http://localhost:8000/api/;
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
@ -214,38 +189,6 @@ server {
} }
``` ```
#### 后端部署
```bash
cd backend
# 创建虚拟环境
python -m venv .venv
source .venv/bin/activate
# 安装依赖
pip install -r requirements.txt
# 配置环境变量
cp env.example .env
# 编辑 .env 文件
# 初始化数据库
alembic upgrade head
# 使用 Gunicorn 启动(生产环境)
gunicorn app.main:app -w 4 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8000
```
### 生产环境安全建议
1. **修改默认密钥**:务必修改 `SECRET_KEY` 为随机字符串
2. **配置 HTTPS**:使用 Let's Encrypt 或其他 SSL 证书
3. **限制 CORS**:在生产环境配置具体的前端域名
4. **数据库安全**:修改默认数据库密码,限制访问 IP
5. **API 限流**:配置 Nginx 或应用层限流
6. **日志监控**:配置日志收集和监控告警
--- ---
## 本地开发部署 ## 本地开发部署
@ -259,13 +202,13 @@ gunicorn app.main:app -w 4 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8000
| Node.js | 18+ | 前端运行环境 | | Node.js | 18+ | 前端运行环境 |
| Python | 3.13+ | 后端运行环境 | | Python | 3.13+ | 后端运行环境 |
| PostgreSQL | 15+ | 数据库 | | PostgreSQL | 15+ | 数据库 |
| pnpm | 8+ | 推荐的包管理器 | | pnpm | 8+ | 推荐的前端包管理器 |
| uv | 最新版 | 推荐的 Python 包管理器 | | uv | 最新版 | 推荐的 Python 包管理器 |
### 数据库准备 ### 数据库准备
```bash ```bash
# 方式一:使用 Docker 启动 PostgreSQL # 方式一:使用 Docker 启动 PostgreSQL(推荐)
docker run -d \ docker run -d \
--name xcodereviewer-db \ --name xcodereviewer-db \
-e POSTGRES_USER=postgres \ -e POSTGRES_USER=postgres \
@ -275,7 +218,6 @@ docker run -d \
postgres:15-alpine postgres:15-alpine
# 方式二:使用本地 PostgreSQL # 方式二:使用本地 PostgreSQL
# 创建数据库
createdb xcodereviewer createdb xcodereviewer
``` ```
@ -285,25 +227,21 @@ createdb xcodereviewer
# 1. 进入后端目录 # 1. 进入后端目录
cd backend cd backend
# 2. 创建虚拟环境(推荐使用 uv # 2. 安装 uv如未安装
uv venv curl -LsSf https://astral.sh/uv/install.sh | sh
source .venv/bin/activate # Linux/macOS
# 或 .venv\Scripts\activate # Windows
# 3. 安装依赖 # 3. 同步依赖
uv pip install -e . uv sync
# 或使用 pip
pip install -r requirements.txt
# 4. 配置环境变量 # 4. 配置环境变量
cp env.example .env cp env.example .env
# 编辑 .env 文件,配置数据库和 LLM 参数 # 编辑 .env 文件,配置数据库和 LLM 参数
# 5. 初始化数据库 # 5. 初始化数据库
alembic upgrade head uv run alembic upgrade head
# 6. 启动后端服务(开发模式,支持热重载) # 6. 启动后端服务(开发模式,支持热重载)
uvicorn app.main:app --reload --port 8000 uv run uvicorn app.main:app --reload --port 8000
``` ```
### 前端启动 ### 前端启动
@ -314,9 +252,8 @@ cd frontend
# 2. 安装依赖 # 2. 安装依赖
pnpm install pnpm install
# 或 npm install / yarn install
# 3. 配置环境变量(可选,也可使用运行时配置 # 3. 配置环境变量(可选)
cp .env.example .env cp .env.example .env
# 4. 启动开发服务器 # 4. 启动开发服务器
@ -339,10 +276,10 @@ pnpm format
# 后端类型检查 # 后端类型检查
cd backend cd backend
mypy app uv run mypy app
# 后端代码格式化 # 后端代码格式化
ruff format app uv run ruff format app
``` ```
--- ---
@ -364,10 +301,10 @@ XCodeReviewer 采用前后端分离架构,所有数据存储在后端 PostgreS
```bash ```bash
# 导出 PostgreSQL 数据 # 导出 PostgreSQL 数据
docker-compose exec db pg_dump -U postgres xcodereviewer > backup.sql docker compose exec db pg_dump -U postgres xcodereviewer > backup.sql
# 恢复数据 # 恢复数据
docker-compose exec -T db psql -U postgres xcodereviewer < backup.sql docker compose exec -T db psql -U postgres xcodereviewer < backup.sql
``` ```
--- ---
@ -380,7 +317,7 @@ docker-compose exec -T db psql -U postgres xcodereviewer < backup.sql
```bash ```bash
# 检查端口占用 # 检查端口占用
lsof -i :5173 lsof -i :3000
lsof -i :8000 lsof -i :8000
lsof -i :5432 lsof -i :5432
@ -391,29 +328,37 @@ lsof -i :5432
```bash ```bash
# 检查数据库容器状态 # 检查数据库容器状态
docker-compose ps db docker compose ps db
# 查看数据库日志 # 查看数据库日志
docker-compose logs db docker compose logs db
# 确保数据库健康检查通过后再启动后端 # 确保数据库健康检查通过后再启动后端
docker-compose up -d db docker compose up -d db
docker-compose exec db pg_isready -U postgres docker compose exec db pg_isready -U postgres
docker-compose up -d backend docker compose up -d backend
``` ```
**Q: 构建时网络问题(代理相关)**
如果构建时遇到网络问题,检查 Docker Desktop 的代理设置:
1. 打开 Docker Desktop → Settings → Resources → Proxies
2. 关闭代理或配置正确的代理地址
3. 重启 Docker Desktop
4. 重新构建:`docker compose build --no-cache`
### 后端相关 ### 后端相关
**Q: PDF 导出功能报错WeasyPrint 依赖问题)** **Q: PDF 导出功能报错WeasyPrint 依赖问题)**
WeasyPrint 需要系统级依赖Docker 镜像已包含。本地开发时: Docker 镜像已包含 WeasyPrint 所需的系统依赖。本地开发时需要安装
```bash ```bash
# macOS # macOS
brew install pango cairo gdk-pixbuf libffi brew install pango cairo gdk-pixbuf libffi
# Ubuntu/Debian # Ubuntu/Debian
sudo apt-get install libpango-1.0-0 libpangoft2-1.0-0 libcairo2 libgdk-pixbuf2.0-0 sudo apt-get install libpango-1.0-0 libpangoft2-1.0-0 libcairo2 libgdk-pixbuf-2.0-0 libglib2.0-0
# Windows - 参见 FAQ.md 中的详细说明 # Windows - 参见 FAQ.md 中的详细说明
``` ```
@ -435,14 +380,14 @@ LLM_GAP_MS=3000
**Q: 前端无法连接后端 API** **Q: 前端无法连接后端 API**
检查 `frontend/.env` 中的 API 地址配置: Docker Compose 部署时,前端通过 `http://localhost:8000/api/v1` 访问后端。确保:
1. 后端容器正常运行:`docker compose ps backend`
2. 后端端口 8000 可访问:`curl http://localhost:8000/docs`
本地开发时,检查 `frontend/.env` 中的 API 地址配置:
```env ```env
# 本地开发
VITE_API_BASE_URL=http://localhost:8000/api/v1 VITE_API_BASE_URL=http://localhost:8000/api/v1
# Docker Compose 部署
VITE_API_BASE_URL=/api
``` ```
--- ---

8
frontend/.dockerignore Normal file
View File

@ -0,0 +1,8 @@
node_modules
dist
.git
.gitignore
*.md
.env*
.vscode
.DS_Store

View File

@ -1,23 +1,56 @@
FROM node:20-alpine FROM node:20-alpine AS builder
WORKDIR /app WORKDIR /app
# 安装 pnpm # 清除代理设置
RUN npm install -g pnpm ENV http_proxy=
ENV https_proxy=
ENV HTTP_PROXY=
ENV HTTPS_PROXY=
# 安装 pnpm确保无代理
RUN unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY all_proxy ALL_PROXY && \
npm install -g pnpm
# 复制依赖文件 # 复制依赖文件
COPY package.json pnpm-lock.yaml ./ COPY package.json pnpm-lock.yaml ./
# 安装依赖 # 安装依赖(确保无代理)
RUN pnpm install RUN unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY all_proxy ALL_PROXY && \
pnpm install --frozen-lockfile
# 复制源代码 # 复制源代码
COPY . . COPY . .
# 暴露端口 # 构建时使用占位符,运行时替换
EXPOSE 5173 ENV VITE_API_BASE_URL=__API_BASE_URL__
# 开发模式启动命令 # 构建生产版本
CMD ["pnpm", "dev", "--host"] RUN pnpm build
# 生产镜像
FROM node:20-alpine
WORKDIR /app
# 清除代理设置
ENV http_proxy=
ENV https_proxy=
ENV HTTP_PROXY=
ENV HTTPS_PROXY=
# 安装 serve确保无代理
RUN unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY all_proxy ALL_PROXY && \
npm install -g serve
# 复制构建产物
COPY --from=builder /app/dist ./dist
# 复制启动脚本
COPY docker-entrypoint.sh /docker-entrypoint.sh
RUN chmod +x /docker-entrypoint.sh
EXPOSE 3000
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["serve", "-s", "dist", "-l", "3000"]

View File

@ -0,0 +1,10 @@
#!/bin/sh
# 替换 API 地址占位符
API_URL="${VITE_API_BASE_URL:-http://localhost:8000/api/v1}"
# 在所有 JS 文件中替换占位符
find /app/dist -name '*.js' -exec sed -i "s|__API_BASE_URL__|${API_URL}|g" {} \;
# 执行原始命令
exec "$@"

26
frontend/nginx.conf Normal file
View File

@ -0,0 +1,26 @@
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html;
# 处理 SPA 路由
location / {
try_files $uri $uri/ /index.html;
}
# 代理 API 请求到后端
location /api/ {
proxy_pass http://backend:8000/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;
}
# 缓存静态资源
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}

View File

@ -1,38 +0,0 @@
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html;
# Gzip 压缩配置
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss application/json application/javascript;
# 安全头部
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
# 处理 React Router 的客户端路由
location / {
try_files $uri $uri/ /index.html;
}
# 静态资源缓存
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# API 代理(如果需要)
# location /api {
# proxy_pass http://backend:8000;
# proxy_http_version 1.1;
# proxy_set_header Upgrade $http_upgrade;
# proxy_set_header Connection 'upgrade';
# proxy_set_header Host $host;
# proxy_cache_bypass $http_upgrade;
# }
}