Django + MySQL + Redis + Docker + Nginx 生产部署笔记
适用范围
本部署方案适用于:
Django 后端(Gunicorn)
Vue 前端(打包静态资源)
MySQL 8.0(生产环境)
Redis 7(缓存 / Token / 限流)
Nginx(反向代理 + HTTPS)
Docker Compose(统一管理)
Linux 服务器(CentOS / Ubuntu / Debian)
一、项目目录结构
project-root/ │ ├── back_stage_management_django/ # Django 后端 │ ├── entrypoint.sh # 后端启动脚本(一次性初始化) │ ├── run_sql.py # 初始化 SQL 导入脚本 │ ├── .env.prod # 后端环境变量 │ └── ... │ ├── back-stage-management-front/ # Vue 前端 │ └── dist/ # 前端打包产物 │ └── docker_deploy/ # 部署目录(生产环境) ├── deploy.sh # Linux 一键部署脚本 ├── deploy.bat # Windows 一键部署脚本 ├── docker-compose.yml # 核心编排文件 │ ├── backend/ │ └── Dockerfile # Django 后端镜像构建文件 │ ├── frontend/ │ └── Dockerfile # Vue 前端镜像构建文件 │ └── nginx/ ├── nginx.conf # Nginx 配置(反向代理 + HTTPS) └── ssl/ # SSL 证书目录 ├── yourdomain+2.pem └── yourdomain+2-key.pem二、后端部署(Django + Gunicorn)
1. 后端 Dockerfile
位于:
docker_deploy/backend/Dockerfile内容:
FROM python:3.12-slim WORKDIR /app # 安装基础依赖 + MySQL 客户端 RUN apt-get update && apt-get install -y \ build-essential \ && rm -rf /var/lib/apt/lists/* # 安装 Python 依赖 COPY requirements.txt . RUN pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt RUN pip install gunicorn # 复制 Django 项目 COPY . . # 赋予脚本执行权限 RUN chmod +x ./entrypoint.sh ENTRYPOINT ["./entrypoint.sh"]内容解析:
1. FROM python:3.12-slim
FROM python:3.12-slim✔ 作用
选择一个轻量级的 Python 3.12 运行环境作为基础镜像。
✔ 为什么用 slim?
镜像体积小
更适合生产环境
更安全(攻击面更小)
Python 3.12 + PyMySQL 是当前 Django 5 的最佳组合。
2. WORKDIR /app
WORKDIR /app✔ 作用
设置容器内的工作目录为/app。
之后所有命令都在这个目录执行。
3. 安装基础依赖
RUN apt-get update && apt-get install -y \ build-essential \ && rm -rf /var/lib/apt/lists/*✔ 作用
安装编译工具(gcc、make 等)。
❗ 为什么需要 build-essential?
因为某些 Python 包可能需要编译(例如 cryptography、lxml 等)。
❗ 为什么没有安装 MySQL 客户端?
因为使用的是PyMySQL(纯 Python),不需要:
libmysqlclient-dev
default-mysql-client
pkg-config
镜像更干净、更轻量。
4. 安装 Python 依赖
COPY requirements.txt . RUN pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt RUN pip install gunicorn✔ 作用
复制 requirements.txt
安装依赖
单独安装 gunicorn(你之前要求过)
✔ 使用清华源加速
非常适合国内环境。
5. 复制 Django 项目
COPY . .✔ 作用
把整个 Django 项目复制到容器的/app目录。
6. 给 entrypoint.sh 添加执行权限
RUN chmod +x ./entrypoint.sh✔ 作用
确保 entrypoint.sh 可以被执行。
7. 设置容器启动命令
ENTRYPOINT ["./entrypoint.sh"]✔ 作用
容器启动时执行 entrypoint.sh。
✔ 为什么不用 CMD?
因为:
ENTRYPOINT 更适合“固定启动逻辑”
CMD 更适合“可覆盖的命令”
你这里需要固定执行 entrypoint.sh,所以 ENTRYPOINT 是正确选择。
核心功能:
使用 python:3.12-slim
安装依赖
复制项目
使用 entrypoint.sh 启动
2. entrypoint.sh(一次性初始化)
位于:
back_stage_management_django/entrypoint.sh内容:
#!/bin/bash set -e INIT_FLAG="/app/.initialized" echo "Backend container starting..." if [ ! -f "$INIT_FLAG" ]; then echo "Running initial setup..." echo "Waiting for MySQL..." python - <<EOF import pymysql, os, time, sys host = os.getenv("MYSQL_HOST") port = int(os.getenv("MYSQL_PORT")) user = os.getenv("MYSQL_USER") password = os.getenv("MYSQL_PASSWORD") max_wait = 300 interval = 2 elapsed = 0 while elapsed < max_wait: try: conn = pymysql.connect( host=host, port=port, user=user, password=password, connect_timeout=2 ) conn.close() print("MySQL ready") sys.exit(0) except Exception: time.sleep(interval) elapsed += interval print("MySQL not ready in time") sys.exit(1) EOF echo "Applying migrations..." python manage.py migrate echo "Importing SQL data..." python run_sql.py || true echo "Collecting static files..." python manage.py collectstatic --noinput touch "$INIT_FLAG" else echo "Initialization already done. Skipping migrate & SQL import." fi echo "Starting Gunicorn..." exec gunicorn back_stage_management_django.wsgi:application \ -b 0.0.0.0:8000 \ -w 4 \ --timeout 120功能:
等待 MySQL 就绪(Python 方式)
第一次启动执行:
migrate
run_sql.py(初始化数据)
collectstatic
之后启动只运行 Gunicorn
这是整个部署的核心,避免重复初始化。
3. 后端环境变量(.env.prod)
位于:
back_stage_management_django/.env.prod内容:
# =========================== # 基础配置(生产环境) # =========================== # 关闭 Django 调试模式(生产环境必须 False) DEBUG=False # 只允许前端域名访问后端(生产环境必须严格限制) # 示例:ALLOWED_HOSTS=yourdomain.com,www.yourdomain.com ALLOWED_HOSTS=localhost,127.0.0.1,192.168.10.143 # 只允