1.确保已经安装并配置好了 Docker
2.在 demo 项目的根目录中创建一个名为 Dockerfile 的文件,文件内容如下:
FROM python:3.9
# 设置 Python 环境变量
ENV PYTHONUNBUFFERED 1
# 安装 MySQL 客户端库
RUN apt-get update && apt-get install -y default-libmysqlclient-dev
# 创建项目目录并设置工作目录
RUN mkdir /app
WORKDIR /app
# 复制项目依赖文件并安装依赖
COPY requirements.txt /app/
RUN pip install -r requirements.txt
# 复制项目文件
COPY . /app/
# 设置环境变量
ENV DB_HOST=db
ENV DB_NAME=database_name
ENV DB_USER=user_name
ENV DB_PASSWORD=user_password
# 运行 Django 项目
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
该 Dockerfile 从 Python 3.9 镜像开始构建,设置了 PYTHONUNBUFFERED 环境变量,并将工作目录设置为 /app。然后安装依赖包并将整个项目复制到容器的 /app 目录中。
3.在项目根目录中创建一个名为 requirements.txt 的文件,并在其中列出所有 Django 项目的依赖项,例如:
Django==3.2.4
psycopg2-binary==2.8.6
可以根据项目需要添加或删除依赖项。
如果该项目依赖mysql,还需要创建一个 docker-compose.yml 文件,来定义如何启动 Docker 容器。
这个文件可以放在和 Dockerfile 文件相同的目录下:
version: '3'
services:
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: mysecretpassword
MYSQL_DATABASE: database_name
MYSQL_USER: user_name
MYSQL_PASSWORD: user_password
volumes:
- db-data:/var/lib/mysql
web:
build: .
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/app
ports:
- "8000:8000"
depends_on:
- db
volumes:
db-data:
在这个配置文件中,我们定义了两个服务:db 和 app。db 服务使用 Docker Hub 上的 MySQL 8.0 镜像,并设置了一些环境变量和数据卷。app 服务使用你的 Django 镜像,并将容器的 8000 端口映射到主机的 8000 端口。同时,我们设置了一些环境变量,用于连接到 MySQL 数据库。最后,我们定义了一个数据卷,用于持久化 MySQL 数据库的数据。
在这个配置文件中,我们将 DB_HOST 环境变量设置为 db,这意味着 Django 容器将连接到 db 服务中的 MySQL 数据库。我们还设置了一些其他的环境变量,包括数据库名称、用户名和密码。这些环境变量将在 Django 容器启动时被传递给应用程序,以便它可以连接到 MySQL 数据库。
最后,我们定义了一个名为 db-data 的数据卷,它将 MySQL 数据库的数据持久化存储在本地主机上。这个数据卷可以确保即使 Docker 容器被删除或重新创建,数据库的数据也可以得到保留。
4.修改settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': os.getenv('DB_NAME'),
'USER': os.getenv('DB_USER'),
'PASSWORD': os.getenv('DB_PASSWORD'),
'HOST': os.getenv('DB_HOST'),
'PORT': '3306',
}
}
5.使用以下命令来构建和运行 Docker 容器:
docker-compose up --build
6.进入容器
#进入docker-compose.yml文件所在目录
docker-compose exec web bash
或者:
docker exec -it <container_name> bash
执行:
python manage.py runserver 0.0.0.0:8000
7.在本地浏览器中输入 http://localhost:8000/
访问的 Django 应用程序
在 docker inspect 命令的输出中,容器的IP地址可以在 Networks 字段下找到,其中 NetworkSettings.Networks 是容器的网络设置,IPAddress 则是容器的IP地址。
可以使用以下命令来获取容器的IP地址:
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <CONTAINER_NAME>
然后就可以使用 http://$IP:8000/
来访问django了
docker-compose up --build 和 docker build 的区别如下:
docker-compose up --build 会构建并启动一个由 docker-compose.yml 文件定义的多个服务容器的应用程序。如果镜像不存在,docker-compose 会自动构建镜像。如果镜像已经存在,它将不会重复构建。此命令还会创建所需的网络和卷。
docker build 只会构建一个 Docker 镜像,并在当前目录中查找 Dockerfile。它不会启动容器,也不会创建网络或卷。
因此,如果要构建并启动一个多容器应用程序,应使用 docker-compose up --build。如果只需要构建一个 Docker 镜像,则应使用 docker build 命令。
示例2
基于 Docker Compose 的完整高可用 Django 网站部署方案,涵盖负载均衡、MySQL 主从同步、Redis 集群、Nginx 反向代理等组件,并附带流量处理流程说明。
一、整体架构图
用户请求 → DNS → Nginx 负载均衡集群 → Django 容器组 → Redis 集群 → MySQL 主从集群
二、目录结构
project/
├── django_app/
│ ├── Dockerfile # Django 应用镜像构建文件
│ ├── requirements.txt # Python 依赖
│ └── src/ # Django 项目代码
├── nginx/
│ ├── nginx.conf # Nginx 负载均衡配置
│ └── conf.d/
│ └── helloworld.conf # 站点配置
├── mysql/
│ └── my.cnf # MySQL 主从配置模板
├── redis/
│ └── redis.conf # Redis 集群配置
└── docker-compose.yml # Docker Compose 核心文件
三、docker-compose.yml
完整配置
version: '3.8'
# 自定义网络
networks:
frontend:
driver: bridge
backend:
driver: bridge
# 共享卷定义
volumes:
mysql_master_data:
mysql_slave_data:
redis_data:
services:
# Django 应用容器组(横向扩展)
django_app:
build: ./django_app
image: django_app:latest
environment:
- DJANGO_SETTINGS_MODULE=config.settings.production
- MYSQL_HOST=mysql_master
- REDIS_HOST=redis
networks:
- backend
depends_on:
- mysql_master
- redis
deploy:
replicas: 4 # 启动 4 个实例
restart_policy:
condition: on-failure
# Nginx 负载均衡集群
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/conf.d:/etc/nginx/conf.d
networks:
- frontend
- backend
depends_on:
- django_app
# MySQL 主从集群
mysql_master:
image: mysql:8.0
command: --server-id=1 --log-bin=mysql-bin --binlog_do_db=helloworld
environment:
MYSQL_ROOT_PASSWORD: rootpass
MYSQL_DATABASE: helloworld
MYSQL_USER: django_user
MYSQL_PASSWORD: djangopass
volumes:
- mysql_master_data:/var/lib/mysql
- ./mysql/my.cnf:/etc/mysql/conf.d/my.cnf
networks:
- backend
mysql_slave:
image: mysql:8.0
command: --server-id=2 --relay-log=mysql-relay-bin --read-only=1
environment:
MYSQL_ROOT_PASSWORD: rootpass
volumes:
- mysql_slave_data:/var/lib/mysql
- ./mysql/my.cnf:/etc/mysql/conf.d/my.cnf
networks:
- backend
depends_on:
- mysql_master
# Redis 集群(3 主 3 从)
redis:
image: redis:7.0
command: redis-server --cluster-enabled yes --appendonly yes
volumes:
- redis_data:/data
networks:
- backend
deploy:
replicas: 6 # 6 节点(3 主 3 从)
restart_policy:
condition: on-failure
四、关键组件配置说明
1. Nginx 负载均衡配置 (nginx/nginx.conf
)
user nginx;
worker_processes auto;
events {
worker_connections 1024;
}
http {
upstream django_servers {
least_conn; # 最少连接负载均衡策略
server django_app_1:8000; # 自动解析容器名称
server django_app_2:8000;
server django_app_3:8000;
server django_app_4:8000;
}
server {
listen 80;
server_name helloworld.com;
location / {
proxy_pass http://django_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# 静态文件处理
location /static/ {
alias /var/www/static/;
expires 30d;
}
}
}
2. MySQL 主从同步配置
-
主库 (
mysql_master
):# my.cnf [mysqld] server-id=1 log-bin=mysql-bin binlog_do_db=helloworld
-
从库 (
mysql_slave
):-- 在从库容器中执行 CHANGE MASTER TO MASTER_HOST='mysql_master', MASTER_USER='root', MASTER_PASSWORD='rootpass', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=154; START SLAVE;
3. Redis 集群初始化
# 进入任意 Redis 容器执行
redis-cli --cluster create \
redis_1:6379 redis_2:6379 redis_3:6379 \
redis_4:6379 redis_5:6379 redis_6:6379 \
--cluster-replicas 1
4. Django 配置 (settings.py
)
# 数据库配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'HOST': os.getenv('MYSQL_HOST', 'mysql_master'),
'NAME': 'helloworld',
'USER': 'django_user',
'PASSWORD': 'djangopass',
'OPTIONS': {
'read_default_file': '/etc/mysql/my.cnf',
}
}
}
# Redis 缓存配置
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://redis:6379/0",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
}
}
五、流量处理流程
-
用户发起请求
访问http://helloworld.com
,DNS 解析到 Nginx 负载均衡器的公网 IP。 -
Nginx 负载均衡
- 根据
nginx.conf
配置,使用least_conn
策略将请求分发到 4 个 Django 容器中的一个。 - 静态文件(如
/static/
)直接由 Nginx 处理,不经过 Django。
- 根据
-
Django 处理请求
- 若请求需要读取数据库:
- 写操作(如创建订单)发送到 MySQL 主库。
- 读操作(如查询商品)优先从 MySQL 从库读取。
- 若请求需要缓存数据(如用户会话):
- 通过 Redis 集群进行读写,数据自动分片到不同节点。
- 若请求需要读取数据库:
-
MySQL 主从同步
- 主库将写操作的 binlog 同步到从库,从库重放日志保证数据一致性。
- 从库设置为
read-only
,防止误写入。
-
Redis 集群
- 数据分片存储在 3 个主节点,每个主节点有 1 个从节点。
- 任一主节点故障时,从节点自动提升为新主节点。
六、启动与验证
-
启动所有服务
docker-compose up -d --scale django_app=4 --scale redis=6
-
验证组件状态
-
MySQL 主从:
docker exec -it mysql_master mysql -uroot -prootpass -e "SHOW MASTER STATUS;" docker exec -it mysql_slave mysql -uroot -prootpass -e "SHOW SLAVE STATUS\G"
-
Redis 集群:
docker exec -it redis_1 redis-cli cluster nodes
-
Nginx 负载均衡:
访问http://helloworld.com
,查看 Nginx 日志确认请求分发:docker logs nginx
-
七、高可用保障
-
容器故障恢复
- 所有服务配置
restart_policy: on-failure
,容器异常退出时自动重启。
- 所有服务配置
-
数据库高可用
- 可扩展为多从库架构,使用
HAProxy
或ProxySQL
实现读负载均衡。
- 可扩展为多从库架构,使用
-
横向扩展能力
- 动态扩展 Django 容器:
docker-compose up -d --scale django_app=8
- 动态扩展 Django 容器: