diff --git a/backend/Dockerfile b/backend/Dockerfile new file mode 100644 index 0000000..5cb7d1e --- /dev/null +++ b/backend/Dockerfile @@ -0,0 +1,23 @@ +# 使用Python官方镜像 +FROM python:3.9-slim + +# 设置工作目录 +WORKDIR /app + +# 复制依赖文件 +COPY requirements.txt . + +# 安装依赖 +RUN pip install --no-cache-dir -r requirements.txt + +# 复制项目文件 +COPY . . + +# 暴露端口 +EXPOSE 8000 + +# 设置环境变量 +ENV PYTHONUNBUFFERED=1 + +# 启动应用 +CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"] \ No newline at end of file diff --git a/backend/schemas/user.py b/backend/schemas/user.py index 46dc5f3..f837b7a 100644 --- a/backend/schemas/user.py +++ b/backend/schemas/user.py @@ -1,6 +1,6 @@ from datetime import datetime from enum import Enum -from pydantic import BaseModel, Field, root_validator +from pydantic import BaseModel, Field, model_validator from typing import Optional # 用户角色枚举 @@ -27,7 +27,7 @@ class UserUpdate(BaseModel): description: Optional[str] = Field(None, max_length=255, description="用户描述") # 可选:确保至少更新一个字段 - @root_validator + @model_validator(mode='before') def validate_at_least_one_field(cls, values): if not any(values.values()): raise ValueError("至少需要更新一个字段") diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..c9df627 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,53 @@ +version: '3.8' + +services: + frontend: + build: ./frontend + ports: + - "3000:80" + depends_on: + - backend + networks: + - app-network + + backend: + build: ./backend + environment: + - DB_HOST=mysql + - DB_PORT=3306 + - DB_USER=root + - DB_PASSWORD=password + - DB_NAME=db + - JWT_SECRET_KEY=your-secret-key + depends_on: + - mysql + networks: + - app-network + + nginx: + image: nginx:stable-alpine + ports: + - "80:80" + volumes: + - ./nginx.conf:/etc/nginx/nginx.conf + depends_on: + - frontend + - backend + networks: + - app-network + + mysql: + image: mysql:8.0 + environment: + MYSQL_ROOT_PASSWORD: password + MYSQL_DATABASE: db + volumes: + - mysql-data:/var/lib/mysql + networks: + - app-network + +volumes: + mysql-data: + +networks: + app-network: \ No newline at end of file diff --git a/frontend/Dockerfile b/frontend/Dockerfile new file mode 100644 index 0000000..db251a7 --- /dev/null +++ b/frontend/Dockerfile @@ -0,0 +1,29 @@ +# 使用Node.js作为基础镜像 +FROM node:18-alpine as build-stage + +# 设置工作目录 +WORKDIR /app + +# 复制package.json和package-lock.json +COPY package*.json ./ + +# 安装依赖 +RUN npm install + +# 复制项目文件 +COPY . . + +# 构建项目 +RUN npm run build + +# 使用Nginx作为生产环境 +FROM nginx:stable-alpine as production-stage + +# 复制构建好的文件到Nginx目录 +COPY --from=build-stage /app/dist /usr/share/nginx/html + +# 暴露80端口 +EXPOSE 80 + +# 启动Nginx +CMD ["nginx", "-g", "daemon off;"] diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..03b9131 --- /dev/null +++ b/nginx.conf @@ -0,0 +1,25 @@ +worker_processes 1; + +events { + worker_connections 1024; +} + +http { + server { + listen 80; + + location /api/ { + proxy_pass http://backend:8000/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + + location / { + proxy_pass http://frontend:80/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + } +} \ No newline at end of file