docker compose 配置 django mysql 站点

本文主要记录使用 docker compose 配置 Django + Mysql 的 web 站点的过程。

环境信息

  • Centos7
  • Docker version 20.10.17

目录结构及说明

项目目录结构及简要说明如下:

.
├── compose
│ └── mysql
│ └── my.cnf
├── django_project
│ ├── db.sqlite3
│ ├── django_app
│ │ ├── admin.py
│ │ ├── apps.py
│ │ ├── __init__.py
│ │ ├── migrations
│ │ ├── models.py
│ │ ├── tests.py
│ │ └── views.py
│ ├── django_project
│ │ ├── asgi.py
│ │ ├── __init__.py
│ │ ├── __pycache__
│ │ ├── settings.py
│ │ ├── urls.py
│ │ └── wsgi.py
│ ├── Dockerfile
│ ├── manage.py
│ └── requirements.txt
├── docker-compose.yml

  • compose : 存放应用配置文件,如 mysql 配置文件 compose/mysql/my.cnf
  • django_project : Django project 项目目录, django-admin startproject django_project 生成
  • django_project/django_app : Django project 项目下的 app 目录,django-admin startapp django_app 生成
  • docker-compose.yml : 项目的 compose 文件

编写 django 运行镜像的 Dockerfile

编写构建 django 镜像的 Dockerfile,文件位置 django_project/Dockerfile

django_project/Dockerfile
FROM python:3.10

# 将上下文环境中(django_project/)的 requirements.txt 拷贝到镜像的 /code 目录
COPY requirements.txt /code/

WORKDIR /code/

# 安装 python 项目依赖
RUN pip install -r requirements.txt && rm -rf requirements.txt

# 解决 django 无法加载 MySQLdb 模块的问题
RUN echo "import pymysql" > /usr/local/lib/python3.10/site-packages/django/db/backends/mysql/__init__.py && \
echo "pymysql.install_as_MySQLdb()" >> /usr/local/lib/python3.10/site-packages/django/db/backends/mysql/__init__.py

# 安装常用工具,方便容器启动后的调试
RUN apt-get update && apt install -y netcat && apt install -y vim && \
apt-get install -y iputils-ping && \
apt-get install -y net-tools

# 健康检查,环境变量 ${DJANGO_SERVER_PORT} 来自 docker-compose.yml 文件
HEALTHCHECK CMD curl -fs http://localhost:${DJANGO_SERVER_PORT}/ || exit 1

构建镜像时,只将构建镜像所需的文件(requirements.txt)拷贝进镜像,使用完成后删除,容器运行时需要的代码文件,通过 docker-compose.yml 中的 volumes 命令进行挂载,这样更新代码时,只需要在宿主机上面更新代码,不用再对镜像进行变更,只有需要更新运行环境时才需要更新镜像

django 镜像构建文件的 Dockerfile 中先不写 CMD 或者 ENTRYPOINT 启动 web 服务器,因为数据库还没启动,配置 CMD 启动 django 服务会报错(无法连接数据库)

修改 django 工程配置文件 django_project/django_project/settings.py,提前配置好 mysql 配置:

django_project/django_project/settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
# 此处 'HOST' 配置的主机地址,要和 docker-compose.yml 中配置的 mysql 服务名称一致
'HOST': "db",
'NAME': "ops",
'USER': "root",
"PASSWORD": "123456",
"PORT": '3306',
}
}

编写项目的 docker-compose.yml

项目的 docker-compose.yml 文件内容及说明如下

docker-compose.yml
version: "3"


volumes:
mysql_data_vol: # mysql datadir 需要挂载的数据卷

networks:
django_network: # 本项目使用的 network ,方便项目中的服务容器之间互相通信,直接使用服务名

services:
db: # mysql 服务名
image: mysql:5.7
env_file:
- .env # 服务要加载的环境变量文件,路径为相对于 docker-compose.yml 的路径
networks:
- django_network
volumes:
- mysql_data_vol:/var/lib/mysql:rw
- ./compose/mysql/my.cnf:/etc/my.cnf

ports:
- "3307:3306"
restart: always

django_server:
build: ./django_project/ # 使用 ./django_project/Dockerfile 构建镜像
env_file:
- .env # 加载环境变量,其中的变量可以在 docker-compose.yml 和 Dockerfile 中使用

volumes:
- ./django_project/:/code/
# command : 容器要运行的命令
command: python manage.py runserver 0.0.0.0:${DJANGO_SERVER_PORT}
networks:
- django_network
ports:
- '${DJANGO_SERVER_PORT}:${DJANGO_SERVER_PORT}'
depends_on:
- db
restart: always

其中使用的 .env 文件内容如下:

.env
MYSQL_ROOT_PASSWORD=123456

DJANGO_SERVER_PORT=8081

启动 docker compose 项目

使用 docker compose build 之前,可以先检查一下配置,确保配置无误:

$ docker compose config
name: dockerproject
services:
db:
environment:
DJANGO_SERVER_PORT: "8081"
MYSQL_ROOT_PASSWORD: 123456
image: mysql:5.7
networks:
django_network: null
ports:
- mode: ingress
target: 3306
published: "3307"
protocol: tcp
restart: always
volumes:
- type: volume
source: mysql_data_vol
target: /var/lib/mysql
volume: {}
- type: bind
source: /root/dockerProject/compose/mysql/my.cnf
target: /etc/my.cnf
bind:
create_host_path: true
django_server:
build:
context: /root/dockerProject/django_project
dockerfile: Dockerfile
command:
- python
- manage.py
- runserver
- 0.0.0.0:8081
depends_on:
db:
condition: service_started
environment:
DJANGO_SERVER_PORT: "8081"
MYSQL_ROOT_PASSWORD: 123456
networks:
django_network: null
ports:
- mode: ingress
target: 8081
published: "8081"
protocol: tcp
restart: always
networks:
django_network:
name: dockerproject_django_network
volumes:
mysql_data_vol:
name: dockerproject_mysql_data_vol

配置无误,docker compose config 命令会输出配置,有错误会显示错误,docker compose 其他常用命令参考

使用 docker compose build 命令构建镜像

$ docker compose build
[+] Building 0.1s (11/11) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 32B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/python:3.10 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 982B 0.0s
=> [1/6] FROM docker.io/library/python:3.10 0.0s
=> CACHED [2/6] COPY . /code 0.0s
=> CACHED [3/6] WORKDIR /code 0.0s
=> CACHED [4/6] RUN pip install -r requirements.txt 0.0s
=> CACHED [5/6] RUN echo "import pymysql" > /usr/local/lib/python3.10/site-packages/django/db/backends/mysql/ 0.0s
=> CACHED [6/6] RUN apt-get update && apt install -y netcat && apt install -y vim 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:9da868de3de9538931f9d60a7fd40d6197c332f4aadc03c8b8ca8446df7cee23 0.0s
=> => naming to docker.io/library/dockerproject_django_server 0.0s


也可以直接使用 docker compose up(会先构建镜像,然后启动项目中的所有服务)

$ docker compose up
[+] Running 3/2
⠿ Network dockerproject_django_network Created 0.1s
⠿ Container dockerproject-db-1 Created 0.0s
⠿ Container dockerproject-django_server-1 Created 0.0s
Attaching to dockerproject-db-1, dockerproject-django_server-1

查看 compose 项目的状态

$ docker compose ls
NAME STATUS CONFIG FILES
dockerproject running(2) /root/dockerProject/docker-compose.yml

查看 compose 项目中的容器情况

$ docker compose ps
NAME COMMAND SERVICE STATUS PORTS
dockerproject-db-1 "docker-entrypoint.s…" db running 0.0.0.0:3307->3306/tcp, :::3307->3306/tcp
dockerproject-django_server-1 "python manage.py ru…" django_server running (healthy) 0.0.0.0:8081->8081/tcp, :::8081->8081/tcp

查看 compose 项目中的镜像

$ docker compose images
Container Repository Tag Image Id Size
dockerproject-db-1 mysql 5.7 daff57b7d2d1 430MB
dockerproject-django_server-1 dockerproject_django_server latest 9da868de3de9 1.02GB

参考链接

docker compose 说明
docker compose 常用命令