Django、Docker 和 PostgreSQL 教程
wemake-django-template
在本教程中,我们将使用 Docker 和 PostgreSQL 创建一个新的 Django 项目。Django 内置了 SQLite 支持,但即使是本地开发,最好也使用像 PostgreSQL 这样与生产环境一致的“真正”的数据库。
虽然可以使用Postgres.app之类的工具在本地运行 PostgreSQL ,但如今许多开发者更倾向于使用Docker,这是一款用于创建隔离操作系统的工具。你可以把它想象成一个大型虚拟环境,其中包含了 Django 项目所需的一切:依赖项、数据库、缓存服务以及其他任何必要的工具。
使用 Docker 的一大优势在于它彻底解决了本地开发环境搭建的种种问题。您无需操心安装了哪些软件包,也无需在项目旁边运行本地数据库,只需运行整个项目的 Docker 镜像即可。更棒的是,这种镜像可以共享给团队成员,大大简化了团队开发流程。
安装 Docker
第一步是在本地计算机上安装桌面版 Docker 应用:
Docker 的首次下载可能需要一些时间,因为它是一个大文件。此时您可以稍作休息!
Docker 安装完成后,我们可以确认运行的是正确的版本。在终端中运行命令docker --version。
$ docker --version
Docker version 19.03.5, build 633a0ea
Docker Compose是一个附加工具,它会自动包含在 Mac 和 Windows 版 Docker 的下载包中。但是,如果您使用的是 Linux 系统,则需要手动添加它。您可以sudo pip install docker-compose在 Docker 安装完成后运行相应的命令来完成此操作。
Django项目
我们将使用《Django for Beginners》中的留言板应用程序。它提供了使用 SQLite 的基本留言板应用程序的代码,可以在后台进行更新。
在桌面上创建一个新目录,并将仓库克隆到该目录中。
$ cd ~/Desktop
$ git clone https://github.com/wsvincent/djangoforbeginners.git
$ cd djangoforbeginners
$ cd ch4-message-board-app
然后安装指定的软件包Pipenv并启动一个新的 shell。如果看到输出(ch4-message-board-app),则说明虚拟环境已激活。
$ pipenv install
$ pipenv shell
(ch4-message-board-app) $
migrate这些更改完成后,请务必更新我们的数据库。
(ch4-message-board-app) $ python manage.py migrate
如果您现在使用该命令,您可以在http://localhost:8000python manage.py runserver上看到我们应用程序的运行版本。
Docker(再次)
希望此时 Docker 已经安装完成。要确认安装成功,请使用 `docker quit` 命令退出本地服务器,Control+c然后docker run hello-world在命令行输入 `docker docker run`。你应该会看到类似这样的响应:
$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
d1725b59e92d: Pull complete
Digest: sha256:0add3ace90ecb4adbf7777e9aacf18357296e799f81cabc9fde470971e499788
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image whi
ch runs the executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client,
which sent it to your terminal.
To try something more ambitious, you can run an Ubuntu container
with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
图片和容器
在 Docker 中,有两个重要的概念需要掌握:镜像和容器。
- 图片:项目中所有软件包的使用说明列表
- 容器:镜像的运行时实例
换句话说,镜像描述了将要发生的事情,而容器才是实际运行的。
要配置 Docker 镜像和容器,我们使用两个文件:Dockerfile和docker-compose.yml。
它包含镜像Dockerfile的指令列表,也就是容器环境中实际发生的情况。
创建一个新Dockerfile文件。
(ch4-message-board-app) $ touch Dockerfile
然后将以下代码添加到文本编辑器中。
# Dockerfile
# Pull base image
FROM python:3.7
# Set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# Set work directory
WORKDIR /code
# Install dependencies
RUN pip install pipenv
COPY Pipfile Pipfile.lock /code/
RUN pipenv install --system
# Copy project
COPY . /code/
首先,我们使用官方的Python 3.7 Docker 镜像。接下来,我们创建两个环境变量。`PYTHONDONTWRITEBYTECODE`PYTHONUNBUFFERED确保控制台输出格式熟悉,并且不会被 Docker 缓冲,这是我们不希望看到的。`PYTHONDONTWRITEBYTECODE`则表示 Python 不会尝试写入.pyc文件,这也是我们不希望看到的。
下一行将 设置WORKDIR为/code。这意味着工作目录位于 ,/code因此将来要运行任何类似 的命令,manage.py我们只需使用 ,WORKDIR而无需记住我们的代码在 Docker 上的确切位置。
然后我们安装依赖项,确保我们拥有最新版本pip,安装pipenv,将本地文件复制Pipfile到Pipfile.lockDocker 容器中,然后运行它来安装依赖项。该RUN命令允许我们在 Docker 容器中运行命令,就像在命令行中一样。
接下来我们需要一个新docker-compose.yml文件。这个文件会告诉 Docker如何运行我们的 Docker 容器。
(ch4-message-board-app) $ touch docker-compose.yml
然后输入以下代码。
version: '3.7'
services:
db:
image: "postgres:11"
volumes:
- postgres_data:/var/lib/postgresql/data/
web:
build: .
command: python /code/manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- 8000:8000
depends_on:
- db
volumes:
postgres_data:
在顶层,我们使用的是最新版本的 Compose,即3.7。
对于db数据库,我们需要 Postgres 10.1 的 Docker 镜像,并使用该volumes镜像告诉 Compose 容器应该位于我们的 Docker 容器中的哪个位置。
因为web我们需要指定 Web 服务的运行方式。首先,Compose 需要从当前目录构建镜像,并在指定位置启动服务器0.0.0.0:8000。我们使用 ` volumes--save-image` 告诉 Compose 将代码存储在 Docker 容器中/code/。` ports--save-image` 配置允许我们将自己的 8000 端口映射到 Docker 容器中的 8000 端口。这是 Django 的默认端口。最后,`--save-image`depends_on指示我们应该db在运行 Web 服务之前先启动 Docker 容器。
最后一部分volumes是因为 Compose 有一条规则,即必须在顶级volumes键中列出命名卷。
我们exit现在可以启动虚拟环境了,因为我们即将切换到运行 Docker。
(ch4-message-board-app) $ exit
$
现在使用命令启动 Docker 容器up,添加 ` -d--detached` 标志使其以分离模式运行,并添加--build`--build` 标志来构建我们的初始镜像。如果我们不添加此标志,则需要打开一个单独的命令行标签页来执行命令。
$ docker-compose up -d --build
Docker 已准备就绪!您可以访问http://127.0.0.1:8000/上的留言板主页,它将显示“现在通过 Docker 运行”。
更新至 PostgreSQL
我们需要将留言板应用更新为使用 PostgreSQL 而不是 SQLite。首先,psycopg2-binary请安装 PostgreSQL 数据库绑定。
$ pipenv install psycopg2-binary
然后更新settings.py文件,指定我们将使用 PostgreSQL 而不是 SQLite。
# settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'postgres',
'USER': 'postgres',
'HOST': 'db', # set in docker-compose.yml
'PORT': 5432 # default postgres port
}
}
migrate此时我们应该将数据库部署在 Docker 上。
$ docker-compose exec web python manage.py migrate
行政
由于留言板应用需要使用管理员权限,请在 Docker 上创建一个超级用户。运行以下命令后,请填写提示信息。
$ docker-compose exec web python manage.py createsuperuser
现在访问http://127.0.0.1:8000/admin并登录。您可以通过后台添加新文章,然后在首页上看到它们,就像《Django 入门》中描述的那样。
完成后,别忘了关闭 Docker 容器。
$ docker-compose down
快速回顾
以下是本文中涉及的术语和概念的简要版本:
- 图片:您项目的“定义”
- 容器:你的项目实际运行所在的环境(镜像的一个实例)
- Dockerfile:定义镜像的外观
- docker-compose.yml:一个YAML文件,它接收 Dockerfile 并添加额外的指令,用于指定 Docker 容器在生产环境中的行为方式。
我们使用Dockerfile来告诉 Docker 如何构建镜像。然后,我们在容器内运行实际的项目。docker -compose.yml文件提供了关于 Docker 容器在生产环境中如何运行的附加信息。
后续步骤
如果您想了解更多关于如何将 Django 和 Docker 结合使用的信息,我已经写了一本关于这个主题的书,名为《Django for Professionals》。
文章来源:https://dev.to/learndjango/django-docker-and-postgresql-tutorial-be3

