使用docker-compose构建Django + MySQL的开发环境
首先
这篇文章的标题可能已经有人写过了,但这是我为了更容易理解而写的备忘录。
我会写下一些单独学习过程中遇到的困难点以及设置文件的描述内容,并附上一些注释。
我会讲解如何将Django教程中的投票应用程序进行迁移,一直写到完成为止。
请注意:下面的结构颇为冗长。
请查看最终的源代码(GitHub链接)。
环境
-
- OS: Mac
Docker Desktop
Docker version 19.03.12
docker-compose version 1.26.2
我在使用VSCode作为编辑器,并且通过Docker扩展功能来进行操作。
这样我可以通过图形界面来登录容器以及重新启动容器,非常方便。
搭建开发环境
我要建立Web服务(Django)和数据库服务(MySQL)的容器。
1. 创建工作目录
最开始,您需要在终端上进行操作。
docker-compose.yml文件所在的目录名称将成为容器名称和卷名称的前缀。
如果容器名称已存在,则无法成功启动,因此需要使用未被使用的项目名称等。
$ mkdir sample-pj
$ cd sample-pj/ # 作業ディレクトリに移動
文件的布局
在创建的工作目录中,放置Dockerfile、docker-compose.yml和requirements.txt文件。
$ touch Dockerfile docker-compose.yml requirements.txt
编辑Dockerfile
从这里开始,我们将使用VSCode进行操作。
可以通过[cmd + shift + m] -> [终端选项卡]来一起操作终端。
我将写出用于创建Web服务(Django)的docker镜像的命令。
我们将基于Docker Hub提供的python:3执行环境镜像,附加一些其他的内容,创建一个新的镜像。
FROM python:3 # 元となるdockerイメージを指定
ENV PYTHONUNBUFFERED 1 # この環境変数に値を入れることでバッファを無効化する('1'じゃなくてもいい)
RUN mkdir /code # codeディレクトリを作成
WORKDIR /code # codeディレクトリに移動
COPY requirements.txt /code/ # txtファイルをcodeディレクトリに配置
RUN pip install --upgrade pip && pip install -r requirements.txt
# pipコマンドを最新にし、txtファイル内のパッケージ(後述)をpipインストール
COPY . /code/ # sample-pj/配下のファイルをcodeディレクトリにコピー
编辑requirements.txt
指定需要安装在网络服务中的软件包。
Django==3.1 # Django3.1
mysqlclient # pythonでMySQLに接続するためのドライバ
编辑docker-compose.yml
创建容器的指令
version: '3' # 1
services: # 2
db:
image: mysql:5.7 # 3
environment: # 4
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: django-db
MYSQL_USER: django
MYSQL_PASSWORD: django
TZ: 'Asia/Tokyo'
command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci
# 5
web:
build: . # 6
command: python3 manage.py runserver 0.0.0.0:8000 # 7
volumes: # 8
- .:/code
ports: # 9
- "8000:8000"
depends_on: # 10
- db
我会解释10个地方。
-
- 版本:’3′
指定docker-compose.yml文件的格式版本
服务:
将启动2个容器,一个是db服务,一个是web服务。服务名称可以任意取名,容器的名称将是[docker-compose.yml所在的目录名称]_[服务名称]
镜像:mysql:5.7
使用Docker Hub提供的mysql:5.7镜像,不使用Dockerfile。选择5.7而不是最新版本的原因是,mysql在8.0之后更改了认证方式,无法成功从web服务器连接。参考文章:如果在从Python连接到MySQL时出现caching_sha2_password错误
环境:
设置根用户的密码,根用户似乎是自动创建的
设置Django项目使用的数据库名
设置连接Django项目时的用户名
设置之前设置的用户的密码
设置db服务器的时区
命令:mysqld –character-set-server=utf8 –collation-server=utf8_unicode_ci
在容器启动时执行的命令,将MySQL的默认字符集转换为utf8。参考文章:在Docker官方镜像中为MySQL指定字符集
构建:.
根据Dockerfile构建镜像。.代表Dockerfile所在的位置
命令:python3 manage.py runserver 0.0.0.0:8000
在容器启动时(只有在没有指定命令参数时)执行的命令,使用指定端口启动Django轻量级服务器
卷:
将当前目录绑定挂载到/code目录
端口:
“8000:8000″左边是公开用的端口,右边是转发到容器的端口。转发端口必须与上述Django服务器指定的端口对应
依赖:
设置先启动db服务,然后再启动web服务
现在,我们已经准备好启动两个容器了。
创建 Django 项目
启动Web服务的容器,并执行Django项目创建命令。
docker-compose run web django-admin.py startproject djangopj .
-
- docker-compose run web
webサービスだけを指定します
django-admin.py startproject djangopj .
djangopjという名前のプロジェクトを作成します
このカレントディレクトリは、Dockerfileで指定した/codeです
执行命令后,项目目录和manage.py文件被创建。
这是因为/code目录和当前工作目录已经绑定挂载到容器上了。
$ ls
Dockerfile docker-compose.yml requirements.txt
djangopj manage.py
编辑DB的配置
打开djangopj/settings.py文件,编辑DATABASES部分。
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'django-db',
'USER': 'django',
'PASSWORD': 'django',
'HOST': 'db',
'PORT': '3306'
}
}
请在NAME、USER和PASSWORD字段中填写docker-compose.yml中设置的值。
请在HOST字段中填写服务名称。
启动各项服务
$ docker-compose up -d
-d选项是分离模式,容器将在后台持续运行。
如果没有显示,请检查容器的运行日志。
如果安装了VSCode的Docker扩展功能,可以通过左侧的Docker选项卡轻松访问日志。
由于数据库服务启动较慢,导致网页服务有时会崩溃,因此只需右键单击网页服务,选择”重新启动”即可解决问题。
如果能访问,我们可以确认MySQL端是否创建了适用于Django的数据库。
以同样的方式,在db服务的容器上右键单击,
点击“附加 Shell”。
然后,您将进入终端界面上的db服务状态,
接着进行mysql登录操作。
# mysql -u root -proot
当显示DB列表时,
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| django-db |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
一切平安,django-db已经成功创建!
使用民意调查应用程序确认数据同步
为了确认能够实现Web服务和数据库服务的协调,参考Django官方教程创建一个小型应用程序。
https://docs.djangoproject.com/ja/3.1/intro/tutorial01/#creating-the-polls-app
创建应用程序
请进入包含docker-compose.yml文件的目录(sample-pj),然后输入以下命令。
$ docker-compose run web python3 manage.py startapp polls
如果执行了ls命令并且出现了名为polls的目录,则表示创建成功。
制作模型
编辑位于polls目录中的models.py文件
from django.db import models
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
在 djangopj/settings.py 文件的 INSTALLED_APPS 中,添加 polls 应用程序。
INSTALLED_APPS = [
'polls.apps.PollsConfig', # 追加
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
将模型应用于数据库中
请回到docker-compose.yml所在的目录(sample-pj),然后执行以下命令。
$ docker-compose run web python3 manage.py makemigrations polls
$ docker-compose run web python3 manage.py migrate
我已经将此模型应用到数据库中。我会在MySQL端进行确认。
mysql> use django-db;
mysql> show tables;
+----------------------------+
| Tables_in_django-db |
+----------------------------+
| auth_group |
| auth_group_permissions |
| auth_permission |
| auth_user |
| auth_user_groups |
| auth_user_user_permissions |
| django_admin_log |
| django_content_type |
| django_migrations |
| django_session |
| polls_choice |
| polls_question |
+----------------------------+
12 rows in set (0.00 sec)
已创建 polls_choice 和 polls_question 表。
参照这个,尝试从管理界面输入数据,
可以确认数据已经被注册到表中。
mysql> select * from polls_question;
+----+---------------+----------------------------+
| id | question_text | pub_date |
+----+---------------+----------------------------+
| 1 | test | 2020-08-21 08:58:07.000000 |
+----+---------------+----------------------------+
1 row in set (0.00 sec)
通过这个,我们可以确认在web服务和数据库服务之间可以进行数据的交流。
“尾声”
最近我终于搞清楚了 docker-compose.yml 文件和 settings.py 中 DATABASES 的写法,之前一直对此感到困惑。现在我写了一篇文章,把这个问题解释清楚了。
我个人认为,如果不重新启动Web容器,就不好改善,所以可能有改进的余地。
如果能够传达出VSCode扩展功能的优点,我将不胜感激。