使用 Docker 容器化 Django Web 应用

1,383 阅读5分钟
原文链接: zhuanlan.zhihu.com

此专栏我会不定期分享一些 Django 最前沿的文章,内容偏重技巧、经验的归纳总结,来源暂时有:

  1. Medium
  2. Twitter 知名博主

如果大家感兴趣,请一定点个关注,给我一些动力,毕竟翻译整理是需要时间的,谢谢大家

--

原文:Dockerizing Django for Development(有改动)
作者: Mark Winter
译者: 临书
难度:✨✨
推荐:✨✨✨

在这篇文章中,我将展示如何使用 Docker 容器化现有项目。我从 GitHub 中挑选了一个随机项目,该项目有一个公开的 issue,称 Docker 化(后文使用 Dockerize)可以在这里作为示例进行贡献和使用。

为什么要在现实世界中 Dockerize 现有的 Django Web 应用程序呢?有很多原因,但如果你没有,那么就当玩玩,哈哈

我决定使用 Docker,因为我的一个应用程序很难部署。有太多的系统依赖,太多的数据库,还有需要单独部署的 Celery 和 rabbitMQ。因此,每当新开发人员加入团队或不得不使用新计算机时,系统的部署都需要很长时间。

部署的麻烦导致时间的损失,而时间损失又导致懒惰,懒惰又导致不良习惯,并这样继续下去...例如,懒可能会使你决定使用 SQLite 而不是 Postgres。(译注:前者是文件数据库,无需部署)

如果你不知道 Docker 是什么,你只需要将它理解成一个巨大的 virtualenv(一种 Python 虚拟环境),它实际上不仅只包含一些 Python 软件包,且使用 Containers(容器)将操作系统中的所有依赖与应用程序,数据库,Worker(译注:应该说的是 Celery Worker) 等等打包结合。


Docker

好吧,「Talk is cheap,Show me some code」,老兄。

首先,使用 Ubuntu 和 Mac OS 安装 Docker 我没有遇到任何问题,但在 Windows 上我没装成功(尴尬)

为了告诉 Docker 如何将您的应用程序作为容器运行,您必须创建一个 Dockerfile:

FROM python:3.6
ENV PYTHONUNBUFFERED 1

RUN mkdir /webapps
WORKDIR /webapps

# Installing OS Dependencies
RUN apt-get update && apt-get upgrade -y && apt-get install -y \
libsqlite3-dev

RUN pip install -U pip setuptools

COPY requirements.txt /webapps/
COPY requirements-opt.txt /webapps/

RUN pip install -r /webapps/requirements.txt
RUN pip install -r /webapps/requirements-opt.txt

ADD . /webapps/

# Django service
EXPOSE 8000

然后我们一行一行看

Docker 镜像

FROM python:3.6

在这里,使用来自 Docker Hub 的镜像,它帮助我们建立一个已经安装了 Python3.6 的Ubuntu 容器。

环境变量(ENV)

你可以使用 Env 关键字创建任意的环境变量

ENV PYTHONUNBUFFERED 1

例如,如果你使用它来存储你的 Django 密钥,你可以这样写:

ENV DJANGO_SECRET_KEY abcde0s&&$uyc)hf_3rv@!a95nasd22e-dxt^9k^7!f+$jxkk+$k-

在你的代码里这样使用:

import os
SECRET_KEY = os.environ['DJANGO_SECRET_KEY']

执行命令(RUN)

Docker 运行命令很容易理解。就是在你的容器里面运行一个命令。我在里面引用是因为docker 创建了一些子容器,因此在重建容器时不必再次运行相同的命令。

RUN mkdir /webapps
WORKDIR /webapps

# Installing OS Dependencies
RUN apt-get update && apt-get upgrade -y && apt-get install -y \
libsqlite3-dev

RUN pip install -U pip setuptools

COPY requirements.txt /webapps/
COPY requirements-opt.txt /webapps/

RUN pip install -r /webapps/requirements.txt
RUN pip install -r /webapps/requirements-opt.txt

ADD . /webapps/

在这种情况下,我们创建用来保存我们项目的 /webapps 目录。

WORKDIR 也是不言而喻的。它只是让 docker 知道后面 RUN 时的目录。

之后,我们安装操作系统依赖项(apt-get 是操作系统的包管理工具),然后安装 Python 依赖项(pip 是 Python 的包管理工具)。

复制(COPY)和添加(ADD)

COPYADD 是相同的。都将您的计算机(主机)中的文件复制到容器中。

暴露端口(EXPOSE)

EXPOSE 指令用于将端口从 Docker 内映射到主机。

# Django service
EXPOSE 8000

好了,现在怎么样?但是我们如何添加更多容器并使它们一起工作?比如在容器中还需要PostgreSQL 呢?别担心,我们继续往下看。


Docker-Compose

Docker-compose 是一个用于运行多个 Docker 容器的工具。表征是一个 yml 文件,你只需要在你的项目文件夹中创建一个 docker-compose.yml 文件。

version: '3.3'

services:
  # Postgres
  db:
    image: postgres
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
      - POSTGRES_DB=postgres

  web:
    build: .
    command: ["./run_web.sh"]
    volumes:
      - .:/webapps
    ports:
      - "8000:8000"
    links:
      - db
    depends_on:
      - db

在这里,我使用 Docker Hub 中的 Postgres 镜像。

现在,让我们更改 settings.py 以配置 Postgres 作为数据库。

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'postgres',
        'USER': 'postgres',
        'PASSWORD': 'postgres',
        'HOST': 'db',
        'PORT': '5432',
    }
}

我们差不多完成了。我来谈谈一下 docker compose 文件。

卷(VOLUMES)

当您在共享卷上写入文件时,该文件也正在写入您的容器中。

volumes:
  - .:/webapps

在这,当前目录(.)将作为 /webapps 目录在容器上共享。

LINKS

links:
  - db

您可以使用其名称引用你的另一个容器。既然我们为我们的 Postgres 创建了一个 db 容器,我们可以将它连接到我们的 web 容器上。你可以在我们的 settings.py 文件中看到我用 'db' 作为 HOST。(这里蛮神奇的)

DEPENDS_ON

为了你的应用程序正常工作,你的数据库必须在 web 容器之前准备好,否则会引发异常。

depends_on:
  - db

Command

Command 是容器在启动后立即运行的默认命令。

对于我们的示例,我创建了一个 run_web.sh 脚本,它将运行迁移(migrations),收集静态文件并启动开发服务器。

如下:

#!/usr/bin/env bash

cd django-boards/
python manage.py migrate
python manage.py collectstatic --noinput
python manage.py runserver 0.0.0.0:8000

可能会有人会争辩说,每次容器启动都自动运行迁移不是一个好习惯。我也同意,你可以直接在网络机器上运行它。

你可以这样访问你的容器:

docker-compose run web bash

如果你希望可以在不访问容器本身的情况下运行它,只需更改上一个命令的最后一个参数 bash 即可,如:

docker-compose run web python manage.py migrate

其它命令也一样:

docker-compose run web python manage.py test
docker-compose run web python manage.py shell

运行 Docker

我们的 Dockerfile,docker-compose.yml 和 run_web.sh 已经就位了,我们可以一起运行它们:

docker-compose up

项目在这里:github.com/ffreitasalv…

--

正文完


转载请注明出处:zhuanlan.zhihu.com/p/33855891

如果大家觉得此类文章对你有用,请务必点个关注,谢谢啦