【云原生| 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文件

sql 复制代码
.git
settings/local.py
**/__pycache__

2) Dockfile

  1. 使用pip freeze > requirements.txt命令打包好项目的依赖包列表 (这种方式只适合在虚拟环境中导出虚拟环境中的包,如果不是在虚拟环境下就会导出全局环境的python的环境包)
  2. 要想在全局环境中导出我们项目的依赖包,可以利用python包pipreqs
bash 复制代码
# 进入到项目所在目录,在执行下面的命令
$> pip install pipreqs
$> pipreqs . --encoding=utf8 --force

 
# "." 指的是将导出依赖包的文件放在当前目录下
# "--encoding=utf8" 指的是存放文件的编码为utf-8,否则会报错
# "--force"  --force 强制执行,当 生成目录下的requirements.txt存在时强子覆盖
  1. 创建dockfile文件
php 复制代码
# 指定基础镜像
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" ]
  • FROM python:3.7 指令从仓库拉取一个包含 python 3.7 的 Linux 操作系统环境(Linux 版本为 Debian)。

  • RUNWORKDIR 指令都是针对容器的,功能是在容器里创建目录、并将其设置为工作目录。注意宿主机是没有这个目录的。

  • ADD 指令出现了两次。ADD requirements.txt /code/ 意思是将宿主机当前目录(即 Dockerfile 所在目录)的 requirements.txt 文件复制到容器的 /code 目录中。ADD . /code/ 意思是把当前目录所有内容复制到容器 /code/ 目录,注意中间那个点。

3) docker-compose.yml

json 复制代码
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,不需要改动它。

从整体上看,我们定义了二个容器,分别是appdb,容器之间通过定义的端口进行通讯。定义了网络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_network depends_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(没有数据)

python 复制代码
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 复制代码
bash
python manage.py migrate

5.2 数据迁移

  1. django先连接回原来的数据库,
bash 复制代码
python manage.py dumpdata > data.json
  1. 导出数据,并修改文件编码! 不然后面 loaddata会报错!
  1. 进入mysql终端,设置忽略外键 和 删除 auth_permissiondjango_content_type 表 ( 由于在数据迁移过程中这两个表数据默认生成)
sql 复制代码
set foreign_key_checks=0;
truncate table django_content_type;
truncate table auth_permission;
set foreign_key_checks=1;
  1. 回到项目容器终端

进入到sh命令窗口

bash 复制代码
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命令查看。
相关推荐
程序员爱钓鱼7 分钟前
Go语言实战案例 — 项目实战篇:图书管理系统(文件存储)
后端·google·go
元闰子11 分钟前
OLTP上云,哪种架构最划算?·VLDB'25
数据库·后端·云原生
IT_陈寒27 分钟前
Vite 5.0重磅升级:8个性能优化秘诀让你的构建速度飙升200%!🚀
前端·人工智能·后端
hui函数44 分钟前
scrapy框架-day02
后端·爬虫·python·scrapy
Moshow郑锴1 小时前
SpringBootCodeGenerator使用JSqlParser解析DDL CREATE SQL 语句
spring boot·后端·sql
小沈同学呀7 小时前
创建一个Spring Boot Starter风格的Basic认证SDK
java·spring boot·后端
方圆想当图灵9 小时前
如何让百万 QPS 下的服务更高效?
分布式·后端
凤山老林9 小时前
SpringBoot 轻量级一站式日志可视化与JVM监控
jvm·spring boot·后端
凡梦千华9 小时前
Django时区感知
后端·python·django
Chan1610 小时前
JVM从入门到实战:从字节码组成、类生命周期到双亲委派及打破双亲委派机制
java·jvm·spring boot·后端·intellij-idea