【面向Django初学者】使用Docker Compose快速搭建Django开发环境(本地环境篇)
这篇帖子是2021年Django Advent Calendar的第24天的文章。
首先
因为在Django的圣诞节日历上感觉到缺少针对初学者的文章,所以我决定为那些打算在年末年初的假期尝试学习Django的人们写一篇文章。
作者
该人在IT行业拥有10年以上的经验,但一直在遗留环境中开发COBOL,如主机等,最近甚至不再编写COBOL,而是完全使用Excel制作文件。对于Django和Python的使用经验也没有,是初学者。
我想写这篇文章的原因
公開起已经两年,我以前用Django制作过第一个网页应用程序。时间过去了,我已经忘记了很多内容,所以在回顾Django开发的同时,我想写一篇文章。以下是我以前创建的应用程序的链接。
网站
星图
Github (hayatek/star-chart)
Github(hayatek/star-chart)
这是一个从Github获取存储库的收藏数量并将其制成图表进行比较的应用程序。
我清楚地知道,仅通过Github的收藏数量无法衡量框架或语言的受欢迎程度,但我认为它可能成为一个指标。
例如,在上述应用程序中,我们可以查看Django、Flask和Rails收藏数量的变化趋势。

从仅仅看星标数增长来看,我们可以发现Django比Flask或Rails增长得更快。
在第一次创建Web应用程序时,使用Docker和GraphQL的API,进行定期批处理等各种细节实现非常困难,但令人惊喜的是,它在没有太多维护的情况下奇迹般地运行了2年。通过这次使用Django的经验,我认为即使是初学者也能够轻松理解,所以我推荐它。
阻碍初次开发Django应用的因素。
虽然我自己也有过这样的经历,即使想要用Django创建应用程序,但在此之前要安装Python实际上有很多种方法(比如venv、pyenv、anaconda…),容易被其中某一点所困扰。
使用Docker可以解决这些问题,并且使用Docker本身并不是什么很高的门槛。
由於這次時間有限,我想專注於使用Docker運行Django,重新嘗試一次。
正如開頭所說,我自己也是Django的初學者,如果有任何錯誤或不足之處,請給予指正和補充。那麼,我們就開始吧!
这次要制作的东西。
我们将使用Docker和Docker Compose,在本地环境中运行Django。
-
- Django
-
- Docker
- Docker-compose
参考视频
因为之前做应用程序的时候也参考了这位的Udemy视频,非常易懂,所以我会一直按照这个视频做下去。关于使用Docker Compose部署Django的方法,请参考上述的博客文章(英文)。
前提(Qian2 ti2)
我使用的是Mac环境,所以将以Mac为基础进行解释。(尽管很可能在Windows上也能实现相同的操作,但我没有确认的方法,因此无法确定。。)
操作系统版本为MacOS Catalina(10.15.7)
Docker桌面版版本为Docker Desktop(4.1.1)
安装Docker桌面版
需要事先安装Docker Desktop。
这里提供了关于如何安装Docker Desktop Mac版的详细解释。
在本教程中,我们将会学习如何在 Mac 上安装 Docker Desktop,并设置 CentOS 的虚拟环境。
首先快速建立开发环境。
那么,让我们立即开始吧。
为了快速地建立环境,事先准备好的模板将被克隆并将相应的 DockerFile、docker-compose 和 requirements.txt 文件复制到本地。
模板文件(Github)
hayatek/docker-django-app
我将克隆上述的存储库。
git clone git@github.com:hayatek/docker-django-app.git
这样一来,docker-django-app文件夹(项目的根文件夹)将具有以下结构。

在同一层级下创建.dockerignore文件。
使用以下内容创建.dockerignore文件。此文件用于在构建Docker镜像时不将不必要的文件添加到Docker镜像中。即使没有此文件,Docker也可以运行。
# Git
.git
.gitignore
# Docker
.docker
# Python
app/__pycache__/
app/*/__pycache__/
app/*/*/__pycache__/
app/*/*/*/__pycache__/
.env/
.venv/
venv/
# Local PostgreSQL data
data/
项目的构建
当您在终端中导航至项目的根文件夹后,请执行以下操作:构建Docker镜像。
cd docker-django-app #プロジェクトのルートフォルダに移動
docker-compose build
如果没有错误,Docker环境的构建就完成了。
接下来,我们将创建一个Django项目。
docker-compose run --rm app sh -c "django-admin startproject app ."
创建Django项目后,项目的结构如下所示。

设定SECRET_KEY
在app文件夹中编辑创建的settings.py文件。
1. 添加import os语句。
2. 将SECRET_KEY设置为通过os.environ.get()函数访问。
import os #追加
from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.environ.get('SECRET_KEY') #変更
本次是因为本地环境的原因,所以将SECRET_KEY设置如下,放在docker-compose.yml中。
environment:
- SECRET_KEY=devsecretkey
创建应用程序
我們在Django上創建一個名為core的應用程式(應用程式名稱可以是任意的)。
在終端上執行以下命令。
docker-compose run --rm app sh -c "python manage.py startapp core"
在settings.py的INSTALLED_APPS中添加一个名为core的应用程序。
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'core', #追加
]
将数据库的描述更改为使用postgre。
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'HOST': os.environ.get('DB_HOST'),
'NAME': os.environ.get('DB_NAME'),
'USER': os.environ.get('DB_USER'),
'PASSWORD': os.environ.get('DB_PASS'),
}
}
设定模型
接下来打开app/core/models.py文件。
删除”# Create your models here.”,然后添加以下内容。
from django.db import models
class Sample(models.Model): #追加
attachment = models.FileField() #追加
请打开app/core/admin.py文件,并添加以下内容。
from django.contrib import admin
from core.models import Sample #追加
admin.site.register(Sample) #追加
完成上述设置之后,请在终端中执行以下命令。
docker-compose run --rm app sh -c "python manage.py makemigrations"
等待数据库
使用Docker来运行Django和PostgreSQL似乎存在以下问题。
尽管将depends_on块添加到应用程序服务中可以确保在应用程序之前启动数据库服务,但无法确保数据库已初始化。
这可能导致Django在完全启动之前尝试连接到数据库而导致崩溃的问题。
我们将进行以下设置以避免这个问题。
首先,在下面的路径上创建一个空的init.py文件。
应用程序核心管理的初始化文件 app/core/management/init.py 和 app/core/management/commands/init.py。
在`app/core/management/commands/`下创建一个名为`wait_for_db.py`的文件,并写入以下内容。
"""
Django command to wait for the database to be available.
"""
import time
from psycopg2 import OperationalError as Psycopg2OpError
from django.db.utils import OperationalError
from django.core.management.base import BaseCommand
class Command(BaseCommand):
"""Django command to wait for database."""
def handle(self, *args, **options):
"""Entrypoint for command."""
self.stdout.write('Waiting for database...')
db_up = False
while db_up is False:
try:
self.check(databases=['default'])
db_up = True
except (Psycopg2OpError, OperationalError):
self.stdout.write('Database unavailable, waiting 1 second...')
time.sleep(1)
self.stdout.write(self.style.SUCCESS('Database available!'))
等待DB的设置已经完成。
执行Docker Compose
在终端上使用以下命令执行Docker Compose。
docker-compose up
在浏览器中输入http://127.0.0.1:8000/。

Django在4.0版本开始运行了!
说明

Django==4.0
下面是Dockerfile。
我们将使用Docker Hub上的Python alpine镜像,其中包含了Python的安装程序。
我们将在Run语句中追加以下内容。
FROM python:3.10.1-alpine3.15
ENV PYTHONUNBUFFERED 1
COPY ./requirements.txt /requirements.txt
COPY ./app /app
WORKDIR /app
EXPOSE 8000
RUN python -m venv /py && \
/py/bin/pip install --upgrade pip && \
apk add --update --no-cache postgresql-client && \
apk add --update --no-cache --virtual .tmp-deps \
build-base postgresql-dev musl-dev && \
/py/bin/pip install -r /requirements.txt && \
apk del .tmp-deps && \
adduser --disabled-password --no-create-home app
ENV PATH="/py/bin:$PATH"
USER app
下一个是docker-compose文件。在command中指定了wat_for_db,并在本地和容器中都指定了8000端口。在db中使用了postgres:13-alpine。
version: '3.9'
services:
app:
build:
context: .
command: >
sh -c "python manage.py wait_for_db &&
python manage.py migrate &&
python manage.py runserver 0.0.0.0:8000"
ports:
- 8000:8000
volumes:
- ./app:/app
environment:
- SECRET_KEY=devsecretkey
- DB_HOST=db
- DB_NAME=devdb
- DB_USER=devuser
- DB_PASS=changeme
depends_on:
- db
db:
image: postgres:13-alpine
environment:
- POSTGRES_DB=devdb
- POSTGRES_USER=devuser
- POSTGRES_PASSWORD=changeme
根据 Postgre 的设置,在 requirements.txt 中也添加了以下的 Postgre 驱动程序。
psycopg2>=2.8.6,<2.9
Finally (in Chinese: 最后)
虽然感觉解释还不够详细,不过Django已经成功运行了吗?一旦应用程序运行成功,接下来只需要继续创建应用程序的具体内容。大家辛苦了。另外,感谢大家一直以来阅读完整文章。