Become a sponsor

本章节介绍如何使用 Docker 快速部署后端服务,无需手动安装 Python、MySQL、Redis 等环境。
温馨提示
Docker 部署适合快速体验和生产环境。本地开发建议使用 后端启动 章节的方式。
确保已安装 Docker 和 Docker Compose:
# 验证 Docker 安装
docker --version
# Docker version 24.0.x
# 验证 Docker Compose 安装
docker compose version
# Docker Compose version v2.x.x# 复制环境变量模板
cp .env.example .env
# 编辑 .env,配置数据库密码、Redis 密码、JWT 密钥等重要提示
Docker 部署时,.env 中的 DB_HOST 和 REDIS_HOST 应指向 Docker 网络中的服务名称(如 mysql、redis),而非 127.0.0.1。
# 构建并启动所有服务
docker compose up -d --build
# 查看服务状态
docker compose ps
# 查看日志
docker compose logs -f app后端 API: http://127.0.0.1:8041/api/v1/health项目使用多阶段构建,减小镜像体积:
# ======================================================================
# Stage 1: 构建依赖
# 使用一个临时镜像来解析 Poetry 依赖,避免把 Poetry 本身
# 和构建缓存带入最终运行镜像,从而减小镜像体积。
# ======================================================================
FROM python:3.12-slim AS builder
# 设置构建阶段的工作目录
WORKDIR /build
# 只拷贝依赖描述文件(先拷这些可以利用 Docker 层缓存:
# 只要依赖没变,后续 poetry export 就不会重新执行)
COPY pyproject.toml poetry.lock* ./
# 安装 Poetry,并把 pyproject.toml / poetry.lock 中的依赖
# 导出为普通的 requirements.txt,方便运行阶段用 pip 安装。
# --without-hashes:不写入哈希校验,简化后续安装。
RUN pip install --no-cache-dir poetry \
&& poetry export -f requirements.txt -o requirements.txt --without-hashes
# ======================================================================
# Stage 2: 运行
# 基于干净的 python:3.12-slim 构建最终镜像,只保留运行所需内容。
# ======================================================================
FROM python:3.12-slim AS runtime
# 环境变量配置:
# PYTHONUNBUFFERED=1 → 不缓冲 stdout/stderr,日志实时输出
# PYTHONDONTWRITEBYTECODE=1 → 不生成 .pyc 文件,保持镜像干净
# TZ=Asia/Shanghai → 设置容器时区为上海
ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
TZ=Asia/Shanghai
# 设置应用运行的工作目录
WORKDIR /data/apps
# 从构建阶段拷贝导出的 requirements.txt
COPY --from=builder /build/requirements.txt ./
# 安装运行所需的 Python 依赖
RUN pip install --no-cache-dir -r requirements.txt
# 拷贝应用代码和资源文件到镜像中
COPY src ./src # 源码目录
COPY app.py ./ # 应用入口
COPY alembic ./alembic # 数据库迁移脚本
COPY alembic.ini ./ # 数据库迁移配置
COPY .env.example ./.env # 环境变量示例(默认作为 .env 使用)
COPY scripts ./scripts # 辅助脚本
COPY templates ./templates # 模板文件
COPY static ./static # 静态资源
# 创建运行时需要的上传目录和日志目录
RUN mkdir -p uploads logs
# 声明容器对外暴露的端口
EXPOSE 8041
# 容器启动命令:运行 Tornado 应用入口
CMD ["python", "app.py"]┌─────────────────────────────────────────────────────────────┐
│ Stage 1: builder │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ python:3.12-slim │ │
│ │ + Poetry │ │
│ │ + pyproject.toml / poetry.lock │ │
│ │ ─────────────────────────────────────────────────────── │ │
│ │ → poetry export → requirements.txt │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ 仅拷贝 requirements.txt │
│ Stage 2: runtime │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ python:3.12-slim │ │
│ │ + pip install -r requirements.txt │ │
│ │ + 应用源码 + 配置 + 脚本 │ │
│ │ ─────────────────────────────────────────────────────── │ │
│ │ → 最终镜像(不含 Poetry、不含构建缓存) │ │
│ └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘项目自带的 docker-compose.yml 仅包含应用服务,适用于数据库和 Redis 已有外部实例的场景:
# ======================================================================
# Docker Compose 编排文件(基础版)
# 仅包含应用服务,适用于数据库和 Redis 已有外部实例的场景
# 使用方式:docker compose up -d
# 依赖根目录下的 .env 提供环境变量
# ======================================================================
services:
# ====================================================================
# 应用服务:构建并运行本项目
# ====================================================================
tornado_antdvue:
image: tornado_antdvue:latest # 镜像名称
container_name: tornado_antdvue # 容器名称
build:
context: ./ # 构建上下文为项目根目录
dockerfile: Dockerfile # 使用项目根目录的 Dockerfile
restart: always # 总是自动重启(生产环境推荐)
ports:
- "8041:8041" # 宿主机端口:容器端口
environment:
- TORNADO_PORT=8041 # 应用监听端口
- TORNADO_ENV=production # 运行环境设为生产模式
env_file:
- .env # 从 .env 文件加载数据库密码等环境变量
volumes:
- ./uploads:/data/apps/uploads # 持久化上传文件到宿主机
- ./logs:/data/apps/logs # 持久化日志(与 Dockerfile WORKDIR 对应)
command: python app.py # 启动命令
logging:
driver: "json-file" # 日志驱动:JSON 文件
options:
max-size: "500m" # 单个日志文件最大 500MB
max-file: "10" # 最多保留 10 个日志文件快速体验或小型部署推荐使用包含 MySQL 和 Redis 的完整版:
# ======================================================================
# Docker Compose 编排文件(完整版)
# 包含三个服务:app(应用)、mysql(数据库)、redis(缓存)
# 使用方式:docker compose up -d
# 依赖根目录下的 .env 提供密码等环境变量
# ======================================================================
services:
# ====================================================================
# 应用服务:构建并运行本项目
# ====================================================================
app:
build: . # 使用当前目录的 Dockerfile 构建镜像
ports:
- "8041:8041" # 宿主机端口:容器端口(供外部访问)
env_file:
- .env # 从 .env 文件加载环境变量(数据库密码等)
environment:
- TORNADO_ENV=production # 运行环境设为生产模式
- DB_HOST=mysql # 数据库地址指向 Docker 网络中的 mysql 服务
- REDIS_HOST=redis # Redis 地址指向 Docker 网络中的 redis 服务
volumes:
- ./uploads:/data/apps/uploads # 持久化上传文件到宿主机
- ./logs:/data/apps/logs # 持久化日志(与 Dockerfile WORKDIR 对应)
depends_on:
- mysql # 声明依赖,但不保证 mysql 已就绪
- redis
restart: unless-stopped # 除非手动停止,否则总是自动重启
# ====================================================================
# MySQL 数据库
# ====================================================================
mysql:
image: mysql:8.0 # 官方 MySQL 8.0 镜像
environment:
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD} # root 密码,从 .env 读取
MYSQL_DATABASE: ${DB_DATABASE} # 初始化时自动创建的数据库名
ports:
- "3306:3306" # 暴露到宿主机(生产环境建议去掉)
volumes:
- mysql_data:/var/lib/mysql # 命名卷持久化数据库数据
restart: unless-stopped
# ====================================================================
# Redis 缓存
# ====================================================================
redis:
image: redis:7-alpine # 轻量级 Redis 7 镜像
command: redis-server --requirepass ${REDIS_PASSWORD} # 启动时设置访问密码
ports:
- "6379:6379" # 暴露到宿主机(生产环境建议去掉)
volumes:
- redis_data:/data # 持久化 Redis 数据
restart: unless-stopped
# ======================================================================
# 命名卷:由 Docker 管理,数据存放在宿主机 /var/lib/docker/volumes 下
# ======================================================================
volumes:
mysql_data: # MySQL 数据持久化卷
redis_data: # Redis 数据持久化卷使用完整版 docker-compose.yml 时,.env 文件中的数据库和 Redis 地址应指向 Docker 服务名称:
# ============================================================
# 数据库配置(指向 Docker 网络中的 mysql 服务)
# ============================================================
DB_DRIVER=mysql
DB_HOST=mysql # Docker 服务名称,不是 127.0.0.1
DB_PORT=3306
DB_DATABASE=djangoadmin.tornado.antdvue
DB_USERNAME=root
DB_PASSWORD=your_mysql_password # 与 MYSQL_ROOT_PASSWORD 一致
DB_PREFIX=tornado_
# ============================================================
# Redis 配置(指向 Docker 网络中的 redis 服务)
# ============================================================
REDIS_HOST=redis # Docker 服务名称,不是 127.0.0.1
REDIS_PORT=6379
REDIS_PASSWORD=your_redis_password
REDIS_AUTH=True
# ============================================================
# JWT 配置(必填)
# ============================================================
JWT_SECRET=your_jwt_secret_key_at_least_32_bytes
# ============================================================
# 应用配置
# ============================================================
TORNADO_ENV=production
TORNADO_DEBUG=False# 构建镜像
docker compose build
# 启动服务(后台运行)
docker compose up -d
# 停止服务
docker compose down
# 停止服务并删除数据卷(⚠️ 会丢失数据)
docker compose down -v
# 查看日志(实时跟踪)
docker compose logs -f app
# 查看所有服务日志
docker compose logs -f
# 进入容器
docker compose exec app bash
# 重启服务
docker compose restart app
# 查看容器状态
docker compose ps
# 查看容器资源占用
docker statsDocker Compose 使用命名卷和绑定挂载持久化数据:
| 存储方式 | 卷名/路径 | 说明 |
|---|---|---|
| 命名卷 | mysql_data | MySQL 数据文件(由 Docker 管理) |
| 命名卷 | redis_data | Redis 数据文件(由 Docker 管理) |
| 绑定挂载 | ./uploads | 上传文件(映射到宿主机) |
| 绑定挂载 | ./logs | 日志文件(映射到宿主机) |
数据备份
生产环境定期备份数据库:
# 备份 MySQL
docker compose exec mysql mysqldump -uroot -p${DB_PASSWORD} ${DB_DATABASE} > backup_$(date +%Y%m%d).sql
# 恢复 MySQL
docker compose exec -T mysql mysql -uroot -p${DB_PASSWORD} ${DB_DATABASE} < backup.sql# .env
TORNADO_DEBUG=False
TORNADO_ENV=production# 生成 JWT 密钥
python -c "import secrets; print(secrets.token_urlsafe(48))"server {
# 监听 80 端口(HTTP)
listen 80;
# 域名配置(替换为实际域名)
server_name your-domain.com;
# 反向代理配置:将所有请求转发到 Tornado 应用
location / {
# 转发目标:Tornado 应用监听的地址和端口
proxy_pass http://127.0.0.1:8041;
# 传递原始请求头,让后端获取真实的客户端信息
proxy_set_header Host $host; # 原始域名
proxy_set_header X-Real-IP $remote_addr; # 客户端真实 IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 代理链 IP 列表
proxy_set_header X-Forwarded-Proto $scheme; # 原始协议(http/https)
# 超时配置(根据业务需求调整)
proxy_connect_timeout 60s; # 连接后端超时时间
proxy_send_timeout 60s; # 发送请求超时时间
proxy_read_timeout 60s; # 读取响应超时时间
# 缓冲配置
proxy_buffering on; # 开启响应缓冲,减轻后端压力
proxy_buffer_size 4k; # 响应头缓冲区大小
proxy_buffers 8 4k; # 响应体缓冲区数量和大小
}
# 静态文件直接由 Nginx 提供(可选,提升性能)
location /static/ {
alias /data/apps/static/; # 映射到容器内的静态文件目录
expires 7d; # 浏览器缓存 7 天
access_log off; # 关闭静态文件访问日志
}
# 上传文件直接由 Nginx 提供(可选)
location /uploads/ {
alias /data/apps/uploads/; # 映射到容器内的上传文件目录
expires 1d; # 浏览器缓存 1 天
access_log off;
}
# 安全配置:拒绝访问隐藏文件
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
}HTTPS 配置
生产环境建议启用 HTTPS。可使用 Let's Encrypt 免费证书:
# 安装 certbot
apt install certbot python3-certbot-nginx
# 申请证书并自动配置 Nginx
certbot --nginx -d your-domain.com生产环境建议不暴露 MySQL 和 Redis 端口到宿主机:
# docker-compose.yml
mysql:
# ports: # 注释掉或删除
# - "3306:3306" # 生产环境不暴露
...
redis:
# ports: # 注释掉或删除
# - "6379:6379" # 生产环境不暴露
...# docker-compose.yml
services:
app:
logging:
driver: "json-file"
options:
max-size: "500m" # 单个日志文件最大 500MB
max-file: "10" # 最多保留 10 个日志文件# 查看容器日志
docker compose logs app
# 常见原因:
# 1. .env 配置错误(数据库密码、Redis 密码)
# 2. 端口被占用(修改 docker-compose.yml 中的端口映射)
# 3. 磁盘空间不足
# 4. JWT_SECRET 未配置或过短1. 确认 MySQL 容器已启动:docker compose ps
2. 确认 .env 中 DB_HOST=mysql(Docker 服务名称,不是 127.0.0.1)
3. 确认 DB_PASSWORD 与 MYSQL_ROOT_PASSWORD 一致
4. 确认 MySQL 已就绪:docker compose logs mysql1. 确认 Redis 容器已启动:docker compose ps
2. 确认 .env 中 REDIS_HOST=redis(Docker 服务名称,不是 127.0.0.1)
3. 确认 REDIS_PASSWORD 与 docker-compose.yml 中的密码一致Dockerfile 已设置 TZ=Asia/Shanghai,如果仍有时区问题:
# 进入容器检查时区
docker compose exec app date
# 手动设置时区(docker-compose.yml)
environment:
- TZ=Asia/ShanghaiDocker 部署通过 Docker Compose 一键启动应用、MySQL、Redis 三个服务。多阶段构建减小镜像体积,命名卷保证数据持久化。生产环境建议关闭调试模式、使用强密钥、配置 Nginx 反向代理、限制端口暴露、配置日志轮转。