docker-Django容器化部署

Posted 封灵寒武

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了docker-Django容器化部署相关的知识,希望对你有一定的参考价值。

首先实现Django+docker本地部署

前期准备

软件安装

软件安装Docker:学习 Docker 当然要安装 Docker 软件了(免费的社区版),安装方法见官方文档。
 Docker-compose:这是 Docker 官方推出的用于编排、运行多个容器的工具,安装方法见官方文档。本教程大部分内容都与它有关。
Python3:教程部署的是 Django 项目,那 Python3 是当然要有的了(包括 python 的包管理工具 pip)。

安装Python虚拟环境

创建虚拟环境
python3 -m venv blog_test

激活虚拟环境
. blog_test/bin/activate

创建Django项目

安装Django2.2版本
pip install django==2.2 -i https://pypi.douban.com/simple/

去到一个喜欢的目录
cd /Users/zhihu/PycharmProjects/

创建DjangoAPP
django-admin startproject django_app

切换进Django app内
cd django_app

迁移数据
python manage.py migrate

注意:
教程后面的内容全部都在此目录中操作了。
为方便阅读,命令提示符 $ 代表目前在项目根目录 django_app/,
mysql $ 则代表目前在目录 django_app/mysql/ 中,请读者操作时稍加留意当前的工作目录

docker构建项目

Docker 的整个生命周期由三部分组成:镜像(image)+ 容器(container)+ 仓库(repository)。

容器是由镜像实例化而来 ,这有点像面向对象的概念:镜像就是类,容器是类实例化之后的对象。

镜像 是一个只读的模板,它包括了运行容器所需的数据。镜像可以包含一个完整的 Linux 操作环境,里面仅安装了 Python 或者其他用户需要的程序。

容器 是由镜像创建出来的实例,类似虚拟机,里面可以运行特定的应用,并且容器与容器是相互隔离的。

仓库 概念与 Git 和 Github 类似,如果你用过它们就非常容易理解。Docker 使用的默认仓库是由官方维护的 Docker hub 公共仓库,从中上传、拉取的操作类似 Git。

docker基本命令

查看镜像
docker images

查看容器
docker ps -a

docker rmi [images ID]  # 删除此 ID 的镜像
docker container stop [container ID]  # 停止此 ID 的容器
docker container start [container ID]  # 启动此 ID 的容器
docker container rm [container ID]  # 删除此 ID 的容器

Dockerfile

Docker 允许通过文本格式的配置文件来构建镜像,默认名称为 Dockerfile。因此在项目根目录新建文件 Dockerfile,写入:

# 从仓库拉取 带有 python 3.8 的 Linux 环境
FROM python:3.8

# 设置 python 环境变量
ENV PYTHONUNBUFFERED 1

# 创建 code 文件夹并将其设置为工作目录
RUN mkdir /code

# 移动至code目录
WORKDIR /code

RUN pip install pip -U -i https://pypi.douban.com/simple/ 

ADD requirements.txt /code/

RUN pip install -r requirements.txt -i https://pypi.douban.com/simple/

# 将当前目录复制到容器的 code 目录
ADD . /code/

理解这些 Docker 指令的关键在于,一定要牢记容器里的环境和外界(宿主机)是隔离的,它两是完全不一样的。
换句话说,要搞清楚哪些操作是针对宿主机、哪些操作是针对容器。
FROM python:3.7 指令从仓库拉取一个包含 python 3.7 的 Linux 操作系统环境(Linux 版本为 Debian)。
RUN 和 WORKDIR 指令都是针对容器的,功能是在容器里创建目录、并将其设置为工作目录。注意宿主机是没有这个目录的。
ADD 指令出现了两次。
ADD requirements.txt /code/ 意思是将宿主机当前目录(即 Dockerfile 所在目录)的 requirements.txt 文件复制到容器的 /code 目录中。
ADD . /code/ 意思是把当前目录所有内容复制到容器 /code/ 目录,注意中间那个点。

导入当前虚拟环境的依赖

pip freeze > requirements.txt

当前文件目录

django_app
  - Dockerfile
  - requirements.txt
  - manage.py
  - django_app
  - db.sqlite3

Docker-compose

Docker-compose在线上环境中,通常不会将项目的所有组件放到同一个容器中;更好的做法是把每个独立的功能装进单独的容器,这样方便复用。比如将 Django 代码放到容器A,将 Mysql 数据库放到容器B,以此类推。
因此同一个服务器上有可能会运行着多个容器,如果每次都靠一条条指令去启动,未免也太繁琐了。 Docker-compose 就是解决这个问题的,它用来编排多个容器,将启动容器的命令统一写到 docker-compose.yml 文件中,以后每次启动这一组容器时,只需要 docker-compose up 就可以了。因此教程也会用 docker-compose 来管理容器。

首先确认 docker-compose 是否安装成功:

$ docker-compose -v
docker-compose version 1.24.1, build 4667896b

确认无误后,在项目根目录创建 docker-compose.yml 并写入:

version: "3"
services:
  app:
    restart: always
    build: .  # \'点\'代表当前目录
    command: "python3 manage.py runserver 0.0.0.0:8000"
    volumes:
      - .:/code
    ports:
      - "8000:8000"


让我们来分解一下其中的各项含义。
version 代表 docker-compose.yml 的版本,目前最新版为 3,不需要改动它。
接着定义了一个名叫 app 的容器。后面的内容都是 app 容器的相关配置:

  • restart :除正常工作外,容器会在任何时候重启,比如遭遇 bug、进程崩溃、docker 重启等情况。
  • build :指定一个包含 Dockerfile 的路径,并通过此 Dockerfile 来构建容器镜像。注意那个 "." ,代表当前目录。
  • command :容器运行时需要执行的命令。这里就是我们很熟悉的运行开发服务器了。
  • volumes :卷,这是个很重要的概念。前面说过容器是和宿主机完全隔离的,但是有些时候又需要将其连通;比如我们开发的 Django 项目代码常常会更新,并且更新时还依赖如 Git 之类的程序,在容器里操作就显得不太方便。所以就有卷,它定义了宿主机和容器之间的映射:"." 表示宿主机的当前目录,":" 为分隔符,"/code" 表示容器中的目录。即宿主机当前目录和容器的 /code 目录是连通的,宿主机当前目录的 Django 代码更新时,容器中的 /code 目录中的代码也相应的更新了。这有点儿像是在容器上打了一个洞,某种程度上也是实用性和隔离性的一种妥协。
    严格意义上讲,这里用到的 .:/code 并不是卷,而是叫挂载,它两是有区别的,只不过 docker-compose 允许将挂载写到卷的配置中。后面章节会讲到。
  • ports :定义了宿主机和容器的端口映射。容器的隔离不止环境,甚至连端口都隔离起来了。但 web 应用不通过端口跟外界通信当然不行,因此这里定义将宿主机的 8000 端口映射到容器的 8000 端口,即访问宿主机的 8000 端口就是访问到了容器的 8000 端口,但要确保端口没有被其他程序占用

配置就写好了。现在项目的目录结构如下:

django_app
  - docker-compose.yml
  - Dockerfile
  - requirements.txt
  - manage.py
  - django_app
  - db.sqlite3

测试

在项目跟目录启动输入指令 docker-compose up 启动容器服务:
可以看到 Docker 按照配置文件的要求,成功构建了镜像及容器,并启动了容器。

打开浏览器,输入本地 IP 端口 127.0.0.1:8000 :

看到 Django 的小火箭,项目成功运行起来啦。按 Ctrl + C 即可停止开发服务器运行。

停止服务器后实际上容器还存在,只是停止运行了而已。输入:

删除容器
$ docker-compose down
如果想在后台运行容器,则输入:
$ docker-compose up -d
如果你需要重新构建镜像,则输入命令
$ docker-compose build
启动和停止已有的容器:
$ docker-compose start
$ docker-compose stop


正常流程
docker-compose up 启动容器
启动和停止已有的容器即可:
$ docker-compose start
$ docker-compose stop

速度太慢

解决方法就是将资源拉取链接修改为国内的镜像源,比如清华的镜像源。

修改 Dockerfile 如下:


FROM python:3.8
ENV PYTHONUNBUFFERED 1

# 添加 Debian 清华镜像源
RUN echo \\
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ buster main contrib non-free\\
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ buster-updates main contrib non-free\\
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ buster-backports main contrib non-free\\
deb https://mirrors.tuna.tsinghua.edu.cn/debian-security buster/updates main contrib non-free\\
    > /etc/apt/sources.list

RUN mkdir /code
WORKDIR /code
# 添加 pip 清华镜像源
RUN pip install pip -U -i https://pypi.tuna.tsinghua.edu.cn/simple
ADD requirements.txt /code/
# 添加 pip 清华镜像源
RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
ADD . /code/

总结

本章初步感受了 Docker 的工作流程,并且很轻松的构建了一个容器化的 Django 项目。

下一章将 MySQL 数据库也加入到容器编排中。

参考

杜赛

docker相关线上文档

以上是关于docker-Django容器化部署的主要内容,如果未能解决你的问题,请参考以下文章

容器化部署是什么意思?有什么优势?

容器化部署和传统部署的四个区别详细讲解-行云管家

容器化部署和传统部署的四个区别详细讲解-行云管家

azure App 服务部署为代码还是容器?

Django应用的容器化部署

容器化 在 KubeSphere 中部署 MySQL 集群