云原生Docker部署Django和mysql项目全过程
作者:计算机魔术师
一、准备工作



镜像加速源
| 镜像加速器 | 镜像加速器地址 |
|---|---|
| Docker 中国官方镜像 | https://registry.docker-cn.com |
| DaoCloud 镜像站 | http://f1361db2.m.daocloud.io |
| Azure 中国镜像 | https://dockerhub.azk8s.cn |
| 科大镜像站 | https://docker.mirrors.ustc.edu.cn |
| 阿里云(需要注册,建议) | https://<your_code>.mirror.aliyuncs.com |
| 七牛云 | https://reg-mirror.qiniu.com |
| 网易云 | https://hub-mirror.c.163.com |
| 腾讯云 | https://mirror.ccs.tencentyun.com |

二、部署 Django & Mysql

1) .Dockignore
创建.dockignore文件
.git settings/local.py **/__pycache__
2) Dockfile
1.使用pip freeze > requirements.txt命令打包好项目的依赖包列表(这种方式只适合在虚拟环境中导出虚拟环境中的包,如果不是在虚拟环境下就会导出全局环境的python的环境包)
2.要想在全局环境中导出我们项目的依赖包,可以利用python包pipreqs
# 进入到项目所在目录,在执行下面的命令 $> pip install pipreqs $> pipreqs . --encoding=utf8 --force # “.” 指的是将导出依赖包的文件放在当前目录下 # “--encoding=utf8” 指的是存放文件的编码为utf-8,否则会报错 # “--force” --force 强制执行,当 生成目录下的requirements.txt存在时强子覆盖
3.创建dockfile文件
# 指定基础镜像
FROM python:3.7
#ENV server.params=
# updata太慢 设置镜像源
RUN sed -i s@/deb.debian.org/@/mirrors.aliyun.com/@g /etc/apt/sources.list \
&& apt-get clean \
&& apt-get update \
&& apt-get install python3-dev default-libmysqlclient-dev -y
# 创建 code 文件夹并将其设置为工作目录
RUN mkdir /code
WORKDIR /code
# 将 requirements.txt 复制到容器的 recruitment 目录
ADD requirements.txt /code/
# 更新 pip 并 安装依赖库
RUN pip install pip -U && pip install -r requirements.txt
# COPY 是不解压的
ADD . /code/
# CMD [ "/bin/sh", "/code/start.local.bat" ]
FROMpython:3.7 指令从仓库拉取一个包含 python 3.7 的 Linux 操作系统环境(Linux 版本为 Debian)。RUN和WORKDIR指令都是针对容器的,功能是在容器里创建目录、并将其设置为工作目录。注意宿主机是没有这个目录的。ADD指令出现了两次。ADD requirements.txt /code/意思是将宿主机当前目录(即Dockerfile所在目录)的requirements.txt文件复制到容器的/code目录中。ADD . /code/意思是把当前目录所有内容复制到容器/code/目录,注意中间那个点。
3) docker-compose.yml
version: "3"
services:
# 设置应用 容器
app:
restart: always
build: . # todo 根据当前项目 dockerfile生成,相当于 docker build -t="ouruser/sinatra:v2" . # bash shell窗口 -c命令行 默认迁移 和 运行
command: bash -c "python manage.py runserver 0.0.0.0:8080" # bash -c "python manage.py runserver 0.0.0.0:8080"
volumes:
- .:/code
ports:
- "8080:8080"
depends_on:
- db
networks:
- db_network
# 设置数据库 容器
db:
image: mysql:8 # 版本一定要对应!
volumes:
- "./mysql/data:/var/lib/mysql" # 设置timestamp 可为 null # 设置字符集 (不是utf8会报错 # collation 这是排序规则
# - "./mysql/conf/my.cnf:/etc/mysql/my.cnf"
command: "mysqld --user=root --explicit_defaults_for_timestamp --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci"
# - -character-set-server=utf8mb4 # 设置默认字节
# - -collation-server=utf8mb4_general_ci # 设置排序
# - -explicit_defaults_for_timestamp=true # 设置可为 null
# --default-authentication-plugin=mysql_native_password # 使用 5.7 版本的密码验证
# "mysqld --user=root --explicit_defaults_for_timestamp --character-set-server=utf8mb4"
ports:
- "3307:3306"
restart: always
environment:
- MYSQL_ROOT_PASSWORD=123456 # 一定要配置
- MYSQL_DATABASE=django_recruitment
networks:
- db_network
# 设置网络
networks:
db_network:
driver: bridge
version代表 docker-compose.yml 的版本,目前最新版为 3,不需要改动它。
从整体上看,我们定义了二个容器,分别是app、db,容器之间通过定义的端口进行通讯。定义了网络db_network,只有处在同一网络下的容器才能够互相通讯。不同网络之间是隔离的,即便采用同样的端口,也无法通讯。
定义了一个名叫 app 的容器。后面的内容都是 app 容器的相关配置:
restart:除正常工作外,容器会在任何时候重启,比如遭遇 bug、进程崩溃、docker 重启等情况。build:指定一个包含Dockerfile的路径,并通过此Dockerfile来构建容器镜像。注意那个 “.” ,代表当前目录。command:容器运行时需要执行的命令。这里就是我们很熟悉的运行开发服务器了。volumes:卷,这是个很重要的概念。前面说过容器是和宿主机完全隔离的,但是有些时候又需要将其连通;比如我们开发的 Django 项目代码常常会更新,并且更新时还依赖如 Git 之类的程序,在容器里操作就显得不太方便。所以就有卷,它定义了宿主机和容器之间的映射:“.” 表示宿主机的当前目录,“:” 为分隔符,“/code” 表示容器中的目录。即宿主机当前目录和容器的 /code 目录是连通的,宿主机当前目录的 Django 代码更新时,容器中的 /code 目录中的代码也相应的更新了。这有点儿像是在容器上打了一个洞,某种程度上也是实用性和隔离性的一种妥协。
严格意义上讲,这里用到的 .:/code 并不是卷,而是叫挂载,它两是有区别的,只不过 docker-compose 允许将挂载写到卷的配置中。
expose:暴露容器的8000端口供其他容器访问,宿主机和外界无法访问networks:能够访问db_networkdepends_on: 意思是此容器需要等待 db 容器启动完毕才能够启动。
分析一下 db 容器:
image:从仓库拉取 MySQL 5.7 。volumes:这里出现的 static-volume 叫卷。它的使用方式像这样:static-volume:/code/collected_static ,冒号后面还是容器内的目录,但冒号前的却不是宿主机目录、仅仅是卷的名称而已。从本质上讲,数据卷也是实现了宿主机和容器的目录映射,但是数据卷是由Docker进行管理的,你甚至都不需要知道数据卷保存在宿主机的具体位置。
相比挂载,数据卷的优点是由于是 Docker统一管理的,不存在由于权限不够引发的挂载问题,也不需要在不同服务器指定不同的路径;缺点是它不太适合单配置文件的映射。和挂载一样,数据卷的生命周期脱离了容器,删除容器之后卷还是存在的。下次构建镜像时,指定卷的名称就可以继续使用了。
ports:MySQL 默认通信端口为 3306 。environment:定义容器的环境变量,设置了 MySQL 的 root 用户的密码、数据库的名称。network:只能够访问db_network。添加db容器后记得的修改Django里的数据库设置。
4)修改项目settings.py
我们在开发项目中,往往是使用
django自带的sqlite进行快速开发测试,后面部署再使用mysql,这里也是一样的,个人建议部署到服务器可以先使用带过去的sqlite进行测试(且此时数据库是有数据的), 进行真正上线则使用mysql(没有数据)
ALLOWED_HOSTS = [ '*']
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# 部署用数据库配置
# DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.mysql',
# 'NAME': 'django_recruitment',
# 'USER': 'root',
# 'PASSWORD': '123456',
# 'HOST': 'db',
# 'HOST': '127.0.0.1',
# 'PORT': '3306',
# 'OPTIONS': {'charset': 'utf8mb4'},
# }
# } # todo 注意:这里使用的是db别名,docker会自动解析成ip 部署!
5)生成表&数据迁移
由于我们所配置的数据是空的,此时我们需要生成表和数据迁移
5.1 生成表
进入到sh命令窗口
bash python manage.py migrate
5.2 数据迁移
1.django先连接回原来的数据库,
python manage.py dumpdata > data.json
2.导出数据,并修改文件编码! 不然后面 loaddata会报错!

3.进入mysql终端,设置忽略外键 和 删除 auth_permission 和 django_content_type 表 ( 由于在数据迁移过程中这两个表数据默认生成)

set foreign_key_checks=0; truncate table django_content_type; truncate table auth_permission; set foreign_key_checks=1;
4.回到项目容器终端
进入到sh命令窗口
bash python manage.py loaddata data.json # mysql版本一定要一样 不然报错
部署命令
运行命令docker-compose build构造镜像,再使用docker-compose up即可启用服务。
下面附上一下经常用到的命令:
- 停止容器,docker-compose down
- 后台运行docker容器:docker-compose up -d
- 只想启动其中的一个容器:docker-compose up -d db或者docker-compose up -d app即可启动db容器或app容器。
- 进入容器:docker exec -it container_id /bin/bash
上面的container_id如果不知道如何获取可以通过docker ps命令查看。
总结
到此这篇关于云原生Docker部署Django和mysql项目的文章就介绍到这了,更多相关Docker部署Django mysql内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
