在经历了三天的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. 经验总结
成功关键点:
-
路径一致性:确保所有配置文件中路径统一
-
服务依赖:正确配置depends_on确保启动顺序
-
网络配置:使用Docker网络进行服务发现
-
数据持久化:合理使用卷保存重要数据
避坑指南:
-
不要在Dockerfile中硬编码绝对路径
-
确保数据库服务完全启动后再迁移
-
使用
restart: unless-stopped确保服务自愈 -
定期清理无用镜像和容器释放空间
9. 学习收获
通过这次Docker部署实践,我深刻理解了:
-
容器化部署的优势:环境一致性、快速部署、资源隔离
-
微服务架构的思想:每个服务专注单一功能
-
生产级部署的复杂性:需要考虑网络、存储、安全等多方面因素
虽然Docker在Windows环境下的网络问题耗费了不少时间,但掌握这项技能为后续的项目部署和团队协作奠定了坚实基础。
454

被折叠的 条评论
为什么被折叠?



