Django REST framework Docker 部署

1,785 阅读4分钟

这是我参与更文挑战的第25天,活动详情查看: 更文挑战

写在前面

接上一篇 Django REST framework 部署实战 Uwsgi + Nginx 的部署是今天文章的基础,它属于传统部署方式步骤比较繁琐,流程比较复杂,不太适合真实的运维场景,今天就聊一聊真实项目中的部署。

正文开始

随着容器化时代的到来,如今的运维不再是简单的写脚本部署服务,而是使用 K8s + Docker 的方式去部署服务。使得运维更关注服务器,开发人员更注重业务。感兴趣的可以查看相关的文档。

1. Dcokerfile

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。

大致介绍一下 Dcokerfile 中用到的语法

  • FROM 基础镜像选择
  • WORKDIR 工作目录
  • COPY 拷贝文件到工作目录
  • RUN 需要运行的命令
  • EXPOSE 容器对外暴露的端口
  • ENTRYPOINT 类似于 CMD 指令,一般用来执行真实的部署脚本
FROM python:3.6

WORKDIR /opt/app

COPY . .

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

EXPOSE 8080

ENTRYPOINT ["sh", "entrypoint.sh"]

2. 部署脚本

entrypoint.sh 主要是关于运行的脚本,可以配置部署的逻辑,下面的文件根据环境变量选择是否执行数据库变更(生产环境数据库变更需要执行对应的SQL文件,因为 migrate 存在不确定性,会使生产环境产生不确定性)

# 是否需要执行数据库变更
if [ "$ENABLE_MIGRATE" == "true" ];then
  python3 manage.py migrate
fi

echo "start demo web service"

# 根据配置环境指定运行方式
if [ "$ENV" == "local" ];then
  exec python3 manage.py runserver 0.0.0.0:8080
else
  python3 manage.py collectstatic
  exec gunicorn demo.wsgi:application \
    --name main_django \
    --max-requests 2000 \
    --max-requests-jitter 500 \
    --bind 0.0.0.0:8080 \
    --workers 4 \
    --threads 4 \
    "$@"
fi

这里使用 gunicorn 部署服务,详情可以查看官方文档 Gunicorn

Gunicorn是一个unix上被广泛使用的高性能的Python WSGI UNIX HTTP Server。 和大多数的web框架兼容,并具有实现简单,轻量级,高性能等特点。

功能上与 uwsgi 没有太大的区别,主要区别在于网络模型。个人对于这两者的认知总结一下:

gunicorn 使用协程来提供并发支撑, 对于网络IO密集的服务比较有利,优点就是 更稳定,性能高,适用于轻量级部署。

uWSGI uWSGI是使用C写的,通过 python 调用 C 的接口实现转发。支持http协议、wsgi协议等协议。优点是功能很全面,有缓存、队列、 rpc 等功能的支持。

3. Docker 运行

# 构建docker 镜像
docker build -t demo  . 

# 运行 docker 服务
docker run -dit demo -p 8080:8080 /bin/bash

4. Docker Compose

Docker Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。

version: '2'
services:
  nginx:
    image: nginx:1.15-alpine
    restart: always
    ports:
      - "8000:8080"
    volumes:
      - ./docker_nginx.conf:/etc/nginx/conf.d/default.conf:ro

  api:
    build:
      context: .
      dockerfile: Dockerfile
    restart: always
    ports:
      - "8001:8080"
    volumes:
      - ./:/opt/app:rw
    depends_on:
      - nginx

在此配置文件中共指定了两个容器 一个是 api 服务另一个是 nginx,这就满足开发的基本要求,当然这里还可以指定数据库的容器;这样可以使用docker来配置一个完美的开发环境。

在 docker-compose.yaml 目录下运行服务,如果是前台启动,可以查看到服务的实时日志;如果是后台启动可以指定容器查看日志。具体命令如下

# 前台运行服务 
docker-compose up 

# 以下是常用的一些命令
# 后台运行服务
docker-compose up -d

# 重新 build + 启动
docker-compose up -d --build

# 查看日志 指定容器
docker-compose logs -f --tail=100 api

一些解释:

  • yaml 文件中 version 代表语法的版本为 2.0,不同的版本语法会有所差别。
  • 各个服务之间的依赖通过 depends_on 指定,构建的时候会先构建依赖项。
  • service 中的各服务之间可以通过 yaml 中定义的名称访问(docker-compose 内部的构建的虚拟网络)。
  • volumes: ./:/opt/app:rw 代表对宿主机目录拥有可读可写的权限,可以根据文件的使用指定不同的权限。

参考资料