From a061f1ab8bc9343a0fbb2c68b5e65ae7f07114c9 Mon Sep 17 00:00:00 2001 From: fj <13632232383@163.com> Date: Mon, 21 Sep 2026 20:43:32 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0docker=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .dockerignore | 20 ++++++++++++++++++++ Dockerfile | 18 ++++++++++++++++++ database.py | 7 +++++-- docker-compose.yml | 43 +++++++++++++++++++++++++++++++++++++++++++ main.py | 18 ++++++++++++++---- 5 files changed, 100 insertions(+), 6 deletions(-) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..eb9b7a3 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,20 @@ +__pycache__ +*.pyc +*.pyo +*.pyd + +node_modules/ +.codebuddy/ +generated-images/ +artifacts/ + +.venv/ +venv/ +env/ + +.git/ +.gitignore + +.DS_Store +*.log +tests/ \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..5751fc4 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,18 @@ +# 基础镜像 +FROM python:3.12-slim + +# 设置工作目录 +WORKDIR /app + +# 先复制 requirements.txt 并安装依赖,利用 Docker 镜像缓存(使用清华镜像源加速) +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple + +# 复制整个项目代码到容器 +COPY . . + +# 暴露端口 +EXPOSE 8005 + +# 启动命令:运行 main.py 中的 FastAPI 应用 +CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8005"] \ No newline at end of file diff --git a/database.py b/database.py index ce33323..82f49a0 100644 --- a/database.py +++ b/database.py @@ -1,14 +1,17 @@ # database.py # 本文件负责配置数据库连接、创建引擎、会话工厂,并提供依赖注入函数 +import os from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from sqlalchemy.orm.decl_api import declarative_base # 1. 配置 MySQL 数据库连接 URL # 格式:mysql+pymysql://用户名:密码@主机:端口/数据库名?编码 -# 请将下面的 'root', '123456', 'localhost', '3306', 'test_db' 替换为你自己的实际信息 -SQLALCHEMY_DATABASE_URL = "mysql+pymysql://root:123456@localhost:3306/student_management_system" +# 优先读取环境变量 DATABASE_URL,便于 Docker / 生产环境覆盖; +# 本地直接 python main.py 跑时,使用下面的本地默认值。 +DEFAULT_DATABASE_URL = "mysql+pymysql://root:123456@localhost:3306/student_management_system" +SQLALCHEMY_DATABASE_URL = os.getenv("DATABASE_URL", DEFAULT_DATABASE_URL) # 2. 创建数据库引擎 engine = create_engine( diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..a6fc5cd --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,43 @@ +# docker-compose.yml +# 一条命令启动整个系统:docker compose up -d --build +# 停止:docker compose down +# 删除数据:docker compose down -v + +services: + mysql: + image: mysql:8.0 + container_name: sms-mysql + restart: unless-stopped + environment: + MYSQL_ROOT_PASSWORD: 123456 + MYSQL_DATABASE: student_management_system + TZ: Asia/Shanghai + command: + - --character-set-server=utf8mb4 + - --collation-server=utf8mb4_unicode_ci + - --default-authentication-plugin=mysql_native_password + # 注意:不把 3306 映射到宿主机,避免和本机已装的 MySQL 冲突 + # (应用容器通过 Docker 内部网络 "mysql" 主机名访问,不需要映射) + volumes: + - mysql_data:/var/lib/mysql + healthcheck: + test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-uroot", "-p123456"] + interval: 5s + timeout: 5s + retries: 20 + + app: + build: . + container_name: sms-app + restart: unless-stopped + depends_on: + mysql: + condition: service_healthy + environment: + # 在容器里 mysql 这个 hostname 解析到 mysql 服务 + DATABASE_URL: mysql+pymysql://root:123456@mysql:3306/student_management_system?charset=utf8mb4 + ports: + - "8005:8005" + +volumes: + mysql_data: \ No newline at end of file diff --git a/main.py b/main.py index 5030764..db25177 100644 --- a/main.py +++ b/main.py @@ -1,5 +1,6 @@ # main0814.py # 项目入口文件:创建 FastAPI 应用、注册路由、创建数据库表 +from contextlib import asynccontextmanager from fastapi import FastAPI from pathlib import Path from fastapi.responses import FileResponse, JSONResponse @@ -11,11 +12,20 @@ from starlette.middleware.cors import CORSMiddleware from api import student_api, advisor_api, employment_api, score_api, class_api, teacher_api from init_db import init_all, drop_tables + +# 1. 应用生命周期:启动时自动建表(幂等,已有表不会重建) +@asynccontextmanager +async def lifespan(app: FastAPI): + init_all(False, False) # 不重置、不灌种子,仅保证表存在 + yield + + # 2. 创建 FastAPI 实例 app = FastAPI( title="FastAPI + SQLAlchemy 分层架构(MySQL)", description="用户管理示例,演示分层架构和 MySQL 集成", - version="1.0.0" + version="1.0.0", + lifespan=lifespan, ) # 3. 添加跨域中间件(允许前端跨域请求) @@ -94,7 +104,7 @@ if __name__ == "__main__": import uvicorn uvicorn.run( "main:app", # 指定应用位置(模块名:应用变量名) - host="0.0.0.0", # 监听所有网络接口 - port=8004, # 端口 - reload=True # 开发模式,代码变动自动重启 + host="127.0.0.1", # 只监听本机,终端里的链接可直接点击打开 + port=8005, # 端口(与 Dockerfile / docker-compose 一致) + reload=True # 开发模式,代码变动自动重启 ) \ No newline at end of file