Django-Docker容器化部署:Django-Docker-MySQL部署

上一章咱们成功搭建了容器化的 Django 项目,用到的数据库为默认的 Sqlite。Sqlite 虽然简单易用,可是线上部署时一般会选择更高效、更可靠的数据库,好比 MySQL。python

本章将在上一章的基础上,修改并构建 Docker + Django + MySQL 的容器项目。mysql

Docker-compose

咱们在学习面向对象的编程语言时,会千方百计把功能独立的模块给独立出来,方便复用和维护。git

容器也是同样的。虽然理论上能够把全部组件塞到同一个容器中去,但更好的作法是各模块在单独容器中,只要保持必要的通讯就能够了。github

也就是说,本教程中如今须要两个容器了:sql

  • 名称叫 app 的 Django 容器
  • 名称叫 db 的 MySQL 容器

因此如何构建 MySQL 镜像?别担忧,这么经常使用的镜像官方已经帮你构建好了,只须要把它从仓库拉取到本地就能够了。docker

修改上一章写的 docker-compose.yml ,增长 MySQL 容器:shell

version: "3"
services:
  app:
    restart: always
    build: .
    command: bash -c "python3 manage.py migrate && python3 manage.py runserver 0.0.0.0:8000"
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    depends_on:
      - db
  db:
    image: mysql:5.7
    volumes:
      - "./mysql:/var/lib/mysql"
    ports:
      - "3306:3306"
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=mypassword
      - MYSQL_DATABASE=django_app
复制代码

app 容器的 command 指令作了修改,让其在运行前先执行数据迁移;新增了配置 depends_on ,意思是此容器须要等待 db 容器启动完毕才可以启动。数据库

分析一下新添加的 db 容器:django

  • image :从仓库拉取 MySQL 5.7 。最新版本为 MySQL 8,不过很坑的是新版本修改了用户登陆的验证方法,致使很容易出现没法经过身份验证的问题。教程为了简单起见选用 5.7 版本。后期会在教程示例代码中添加mysql-8分支并给出操做方法,有兴趣的读者能够查看。
  • volumes :定义卷(这里实际是挂载),上一章已经讲过了,它实现了宿主机和容器目录的映射。功能是将容器中的 MySQL 数据映射到宿主机。
  • ports :MySQL 默认通讯端口为 3306 。
  • environment :定义容器的环境变量,设置了 MySQL 的 root 用户的密码、数据库的名称。

这里为何要用?就让数据在容器中、保持隔离很差吗?把数据保存在容器中,理论上确实是能够的,但有一个致命的问题,即数据和容器的生命周期挂钩了:万一哪天手贱把容器给删了,连同里面的数据随风而逝,你就是全公司那个删库跑路的传奇人物了。要知道容器的生命周期可能会很是短暂,删除指令也至关顺滑(docker-compose down)。将数据映射到宿主机,容器即便被删除掉,但数据仍是安全的躺在你的服务器中的。换句话说,容器内部很是适合运行无状态的应用;涉及到如数据之类有状态的东西,必定要谨慎思考。编程

Dockerfile

接下来修改 Dockerfile

FROM python:3.7
ENV PYTHONUNBUFFERED 1
 # 添加这两行
RUN apt-get update
RUN apt-get install python3-dev default-libmysqlclient-dev -y

RUN mkdir /code
WORKDIR /code
RUN pip install pip -U
ADD requirements.txt /code/
RUN pip install -r requirements.txt
ADD . /code/
复制代码

增长的两行代码在系统中安装了 MySQL 的链接器,具体解释见官方文档

其余配置

修改 requirements.txt ,增长 MySQL 驱动:

django==2.2
mysqlclient==1.3.14
复制代码

而后还须要修改 django_app/settings.py ,将数据库设置为 MySQL:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'django_app',
        'USER': 'root',
        'PASSWORD': 'mypassword',
        'HOST': 'db',
        'PORT': '3306',
        'OPTIONS': {'charset': 'utf8mb4'},
    }
}
复制代码

注意 HOST 填写的是容器的名称,即 db 。

这就能够啦。接下来测试。

测试

测试以前,请先确认没有其余程序占用了 3306 端口,好比宿主机安装的 MySQL。

从新生成镜像:

$ docker-compose build
复制代码

生成并启动容器:

$ docker-compose up

Creating network "django_app_default" with the default driver
Creating django_app_db_1 ... done
Creating django_app_app_1 ... done
Attaching to django_app_db_1, django_app_app_1
db_1   | 2019-10-06T12:24:57.183860Z 0 [Note] mysqld (mysqld 5.7.27) starting as process 1 ...

...

db_1   | 2019-10-06T12:24:58.120480Z 0 [Note] mysqld: ready for connections.
db_1   | Version: '5.7.27'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server (GPL)

app_1  | Operations to perform:
app_1  |   Apply all migrations: admin, auth, contenttypes, sessions
app_1  | Running migrations:
app_1  |   Applying contenttypes.0001_initial... OK
...
app_1  |   Applying sessions.0001_initial... OK

app_1  | Watching for file changes with StatReloader
app_1  | Performing system checks...
app_1  | 
app_1  | System check identified no issues (0 silenced).
app_1  | October 06, 2019 - 12:24:58
app_1  | Django version 2.2, using settings 'django_app.settings'
app_1  | Starting development server at http://0.0.0.0:8000/
app_1  | Quit the server with CONTROL-C.
复制代码

打开浏览器访问 127.0.0.1:8000 ,又能看到 Django 小火箭啦。

**注意:**第一次启动容器时可能会出现没法链接 MySQL 的错误,这是因为虽然 db 容器已经启动,但初始化并未完成;从新启动容器以后就能够正常工做了。若屡次启动都没法正常工做,那就是别的缘由了,好好检查吧。

总结

本章加入了 MySQL 容器,并实现了多容器协同工做。

下一章将实现正式部署的 Docker + Django + MySQL + Nginx + Gunicorn 项目。


相关文章
相关标签/搜索