使用Docker部署Django项目完整指南(Waitress+Nginx+MySQL)

在经历了三天的Docker部署探索后,我成功将一个Django项目容器化部署。本文将完整记录整个部署过程,包括Docker核心概念、详细部署步骤、配置文件详解以及本地文件夹映射方案。

1. Docker核心概念理解

1.1 镜像(Image) vs 容器(Container)

镜像就像软件的"安装包":

  • 只读模板,包含运行应用所需的一切

  • 可以导出、导入、推送到仓库

  • 一个镜像可以创建多个容器实例

容器就像"运行中的软件":

  • 镜像的运行实例,有可写层

  • 相互隔离的进程空间

  • 临时性,删除后数据丢失(需卷持久化)

1.2 关键组件关系

text

镜像(MySQL) → 容器(MySQL实例)
镜像(Nginx) → 容器(Nginx实例)  
镜像(自定义Django) → 容器(Django应用实例)

2. 项目架构设计

2.1 服务架构

text

用户请求 → Nginx(80端口) → Waitress(8000端口) → Django应用 → MySQL数据库

2.2 目录结构

text

project/
├── Dockerfile              # Django应用镜像定义
├── docker-compose.yml      # 多服务编排
├── nginx.conf             # Nginx配置
├── requirements.txt        # Python依赖
└── myproject/             # Django项目代码
    ├── settings.py
    ├── urls.py
    └── wsgi.py

3. 核心配置文件详解

3.1 Dockerfile - Django应用镜像

dockerfile

FROM python:3.9-slim

# 安装系统依赖
RUN apt-get update && apt-get install -y \
    gcc g++ default-libmysqlclient-dev pkg-config \
    && rm -rf /var/lib/apt/lists/*

ENV PYTHONUNBUFFERED 1

# 设置工作目录
RUN mkdir /app
WORKDIR /app

# 安装Python依赖
COPY requirements.txt .
RUN pip install --upgrade pip && \
    pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple/

# 安装Waitress
RUN pip install waitress

# 复制项目代码
COPY . /app/

# 收集静态文件
RUN python manage.py collectstatic --noinput

EXPOSE 8000

# 启动命令
CMD ["waitress-serve", "--port=8000", "myproject.wsgi:application"]

3.2 docker-compose.yml - 服务编排

yaml

version: '3.8'

services:
  db:
    image: mysql:8.0
    command: 
      - --default-authentication-plugin=mysql_native_password
      - --character-set-server=utf8mb4
      - --collation-server=utf8mb4_unicode_ci
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: rootpassword
      MYSQL_DATABASE: myproject_db
      MYSQL_USER: myproject_user
      MYSQL_PASSWORD: userpassword
    volumes:
      - mysql_data:/var/lib/mysql
    networks:
      - app-network

  web:
    build: .
    volumes:
      - static_volume:/app/staticfiles
      - media_volume:/app/media
      - .:/app
    expose:
      - "8000"
    depends_on:
      - db
    restart: unless-stopped
    networks:
      - app-network

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - static_volume:/app/staticfiles:ro
      - media_volume:/app/media:ro
      - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
    depends_on:
      - web
    restart: unless-stopped
    networks:
      - app-network

volumes:
  mysql_data:
  static_volume:
  media_volume:

networks:
  app-network:
    driver: bridge

3.3 nginx.conf - Nginx配置

nginx

server {
    listen 80;
    server_name localhost;

    # 静态文件处理
    location /static/ {
        alias /app/staticfiles/;
        expires 30d;
        add_header Cache-Control "public, immutable";
        try_files $uri =404;
    }

    # 媒体文件处理
    location /media/ {
        alias /app/media/;
        expires 30d;
        add_header Cache-Control "public";
        try_files $uri =404;
    }

    # Django应用代理
    location / {
        proxy_pass http://web: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;
        proxy_set_header X-Forwarded-Proto $scheme;
        
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }

    # Gzip压缩
    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
}

3.4 Django settings.py关键配置

python

import pymysql
pymysql.install_as_MySQLdb()

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'myproject_db',
        'USER': 'myproject_user',
        'PASSWORD': 'userpassword',
        'HOST': 'db',  # 使用服务名,不是localhost
        'PORT': '3306',
        'OPTIONS': {
            'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
            'charset': 'utf8mb4',
        }
    }
}

# 静态文件配置
STATIC_URL = '/static/'
STATIC_ROOT = '/app/staticfiles'

# 生产环境设置
DEBUG = False
ALLOWED_HOSTS = ['localhost', '127.0.0.1']

4. 本地文件夹映射实战

4.1 文件读写目录映射

对于需要读写本地文件的Django项目,通过卷挂载实现:

yaml

# 在docker-compose.yml的web服务中添加
volumes:
  - F:/orders:/data/orders
  - F:/ordersettled:/data/ordersettled
  - C:/Users/fdemo/Downloads:/data/downloads

4.2 Django配置对应调整

python

# settings.py中配置容器内路径
ORDERS_UPLOADS_ROOT = '/data/orders'
ORDERS_SETTLED_ROOT = '/data/ordersettled'
KDZS_DOWNLOADS_ROOT = '/data/downloads'

4.3 权限设置脚本

创建Windows权限设置脚本set_permissions.bat

batch

@echo off
echo Setting Docker folder permissions...

icacls "F:\orders" /grant "SYSTEM:(OI)(CI)F" /T
icacls "F:\orders" /grant "Users:(OI)(CI)M" /T

icacls "F:\ordersettled" /grant "SYSTEM:(OI)(CI)F" /T  
icacls "F:\ordersettled" /grant "Users:(OI)(CI)M" /T

echo Permissions set for Docker data directories

5. 完整部署流程

5.1 首次部署

bash

# 1. 构建镜像
docker-compose build --no-cache

# 2. 启动服务
docker-compose up -d

# 3. 执行数据库迁移
docker-compose exec web python manage.py migrate

# 4. 创建超级用户
docker-compose exec web python manage.py createsuperuser

5.2 日常更新

bash

# 更新代码后重建web服务
docker-compose build web
docker-compose up -d web

# 或完整重启
docker-compose down
docker-compose up -d

5.3 服务管理

bash

# 查看服务状态
docker-compose ps

# 查看日志
docker-compose logs
docker-compose logs web

# 进入容器
docker-compose exec web bash

6. 常见问题与解决方案

6.1 网络问题:镜像拉取失败

解决方案:配置国内镜像源

json

// Docker Desktop设置中的Docker Engine配置
{
  "registry-mirrors": [
    "https://docker.mirrors.ustc.edu.cn",
    "https://hub-mirror.c.163.com"
  ]
}

6.2 权限问题:文件读写失败

解决方案:正确设置文件夹权限

  • 确保Docker Desktop有文件共享权限

  • 运行权限设置脚本

  • 检查卷挂载路径一致性

6.3 数据库连接问题

解决方案:检查配置一致性

  • settings.py中的HOST必须是服务名db

  • 数据库名、用户名、密码与docker-compose.yml一致

  • 等待数据库完全启动后再连接

7. 生产环境考量

7.1 安全配置

  • 使用强密码替换默认密码

  • 设置适当的ALLOWED_HOSTS

  • 关闭DEBUG模式

  • 使用HTTPS

7.2 性能优化

  • 调整Waitress线程数

  • 配置Nginx缓存策略

  • 设置MySQL缓冲池大小

  • 启用Gzip压缩

7.3 监控和维护

bash

# 资源监控
docker stats

# 日志管理
docker-compose logs -f web

# 备份数据库
docker-compose exec db mysqldump -u root -p database > backup.sql

8. 经验总结

成功关键点:

  1. 路径一致性:确保所有配置文件中路径统一

  2. 服务依赖:正确配置depends_on确保启动顺序

  3. 网络配置:使用Docker网络进行服务发现

  4. 数据持久化:合理使用卷保存重要数据

避坑指南:

  • 不要在Dockerfile中硬编码绝对路径

  • 确保数据库服务完全启动后再迁移

  • 使用restart: unless-stopped确保服务自愈

  • 定期清理无用镜像和容器释放空间

9. 学习收获

通过这次Docker部署实践,我深刻理解了:

  • 容器化部署的优势:环境一致性、快速部署、资源隔离

  • 微服务架构的思想:每个服务专注单一功能

  • 生产级部署的复杂性:需要考虑网络、存储、安全等多方面因素

虽然Docker在Windows环境下的网络问题耗费了不少时间,但掌握这项技能为后续的项目部署和团队协作奠定了坚实基础。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值