Published Date : 2020年10月30日12:59

サクッとDockerでDjango環境を構築してみよう
Quickly build a Django environment with Docker


This blog has an English translation


YouTubeにアップした動画、「【日本語解説】サクッとDockerでDjango環境を構築してみよう【WSL2, Docker】」の補足説明の記事です。

Here's a little more about the 「【WSL2, Docker】Quickly build a Django environment with Docker」 video I uploaded to YouTube.

字幕を付けるなら、英語音声と日本語音声の二つに分けたほうが良いと思ったので、今回から同じ動画だが音声が日本語と英語に分かれたものをアップしました。

I thought it would be better to separate the video into English audio and Japanese audio instead of adding subtitles to the video, so I uploaded the same video with Japanese and English audio separately.

ページの頭に日本語解説動画、ページの最後に英語解説動画のリンクが貼られてます。

There is a Japanese explanation video at the top of the page, and an English explanation video link at the end of the page.

Docker Docsを参考にしました。

クィックスタート: Compose と Django

I referred to Docker Docs.

Quickstart: Compose and Django


目次

Table of Contents




① 動画の説明
① Video Description



前回はDockerの環境をWSL2で構築しました。

Last time we built the Docker environment on WSL2.

今回はDockerを使ってDjangoの環境を構築してみましょう。

This time, let's build a Django environment with Docker.

まずUbuntu18.04のターミナルを立ち上げて、作業用ダイレクトリを作成してくだちぃ。

First, start your Ubuntu 18.04 terminal and create a working directory.

username@PC:~$ mkdir your-working-directory

作業用ダイレクトリの中に移動します。

Move into the working directory.

username@PC:~$ cd your-working-directory

[code .]でVS Codeを立ち上げます。

Launch VS Code at [code .].

username@PC:~/your-working-directory$ code .

[Dockerfile]を作成して、Dockerイメージのビルドを実行するコマンドを書き込みます。

Create a [Dockerfile] and write the command that will run the Docker image build.

Dockerfile
FROM python:3
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
ADD requirements.txt /code/
RUN pip install -r requirements.txt
ADD . /code/

FROMで指定しているのはベースとなるイメージです。

FROM specifies the base image.

つまりPython3をベースイメージとします。

That is, Python 3 is the base image.

このイメージを基にコンテナと呼ばれる仮想環境が作成される仕組みです。

A virtual environment called a container is created from this image.

次の行のenv(環境変数)で、Python3の出力をリアルタイムで見られるように設定します。

On the next line, env (Environment Variables), set the Python 3 output to be viewed in real time.

このPYTHONUNBUFFEREDに空でない数値を設定することによって、

Setting PYTHONUNBUFFERED to a non-empty number allows you to see the output

バッファ(一時的に情報を保存する領域)にPythonが出力する情報を保存せずに、

of an app like Django in real time without storing the Python output

そのままDjango等のアプリの出力をリアルタイムに見られるようになります。

in a buffer (A buffer is a temporary storage area for information.).

RUNの[mkdir /code]は[/](コンテナのルートディレクトリ)に[code]というディレクトリを作成するという意味です。

The [mkdir /code] of the RUN means to create a directory in the [/] (Root directory of the container) called [code].

次のWORKDIRは先ほど作った[code]ディレクトリを作業用のディレクトリに設定するという意味です。

The following WORKDIR means to set the [code] directory created earlier as the working directory.

作業用ディレクトリが存在しないときは自動で生成されます。

If the working directory does not exist, it is automatically generated.

ADDの命令文は、これから作成するDjangoアプリに必要なPythonモジュールをまとめてインストールする為に必要な

The meaning of the ADD statement is to add the [requirementstxt] in [code],

[requirements.txt]を[/code]内に加えるという意味です。

which is necessary to install all the Python modules required for the Django app you are about to create at once.

その後にまたRUN命令文で、[requirements.txt]で指定されたPythonモジュールをインストールするようにします。

The RUN statement then installs the Python module specified in [requirements.txt].

最後にまたADDの後の命令文で、現在のディレクトリ(今Dockerfileを作成しているディレクトリ)をコンテナ内の[code]にマウントします。

Finally, the statement after ADD mounts the current directory (The directory where you are currently creating the Dockerfile) to the [code] in the container.

作成して起動したDockerコンテナは仮想環境として、環境が切り離されているように振る舞います。

When you create and launch a Docker container, it acts as a virtual environment, as if the environment is isolated.

ここでいうマウントとは簡単に言うと、このコンテナが、現在のディレクトリ(今Dockerfileを作成しているディレクトリ)

In a nutshell, [mount] means making this container aware of changes

内の変更を認識できるようにするということです。

in the current directory (Directory in which you are creating the Dockerfile).

こうすることで、Pythonコードの変更をする度にイメージの再構築を行わずに、

This way, every time you make a change to your Python code,

コンテナを再起動させるだけで、その変更が反映されるという仕組みです。

you can simply restart the container to reflect the change without rebuilding the image.

通常だと複数回にわたって、[docker]コマンドを使って、

Normally, you use the [docker] command multiple times to pull a specified image

Dockerhubから指定したイメージを引っ張ってきて、

from Dockerhub to build an environment,

環境を構築したり、コンテナの作成や起動等を行います。

create a container, or launch a container.

この[docker-compose.yml]は、その複数のコマンド作業を、

This [docker-compose.yml] is a file that

一つにまとめて一度に実行できるようにしたファイルです。

allows you to execute multiple command operations at once.

この[docker-compose.yml]を動かすには[docker-compose]コマンドを使用します。

Use the [docker-compose] command to run [docker-compose.yml].

docker-compose.yml
version: '3'

services:
  db:
    image: postgres
  web:
    build: .
    command: python3 manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    depends_on:
      - db

この[docker-compose.yml]の中の、versionは[docker-compose.yml]のファイルフォーマットのバージョンを指定しています。

In this [docker-compose.yml], version specifies the [docker-compose.yml] file format version.

現時点での最新バージョンは3になってます。この動画が古くなるとバージョンが変わる可能性があります。

Currently, the latest version is 3. However, if the content of this video becomes old, the version may change.

バージョンが変わると[docker-compose.yml]の書き方に違いが生じる可能性がある為、注意が必要です。

Please note that there may be differences in the way [docker-compose.yml] is written if the version changes.

次の[services]は[docker]が管理するアプリケーションを指します。

The following [services] refers to applications managed by [docker].

この[services]内には今回のように複数の子要素が存在します。

In this [services] there are several child elements, as in this case.

簡単に言うと、一つのサービスに対して、一つのコンテナが起動すると考えてください。

In a nutshell, think of a service as a container.

そして、[db]や[web]はこの各サービスの名称です。

[db] and [web] are the names of these services.

この[db]や[web]はエンドポイント名としても機能します。

This [db] or [web] also serves as the endpoint name.

つまり、[db]サービスと[web]サービスがそれぞれこのエンドポイント名を使って通信できることを意味しています。

This means that the [db] and [web] services can each communicate using this endpoint name.

[db]には[postgresqlイメージ]を使用します。

[db] Use [image of postgresql] for.

そして[web]のコンテナの[build]には[Dockerfile]の場所を指定します。

The [web] container [build] specifies the [Dockerfile] location.

つまりこの[docker-compose.yml]と同じディレクトリ[.]に[Dockerfile]があることを指しています。

This means that there is a [Dockerfile] in the same directory as this [docker-compose.yml](.).

そして、[docker-compose up]を実行した時に[command]に書かれた内容が実行されます。

When [docker-compose up] is executed, the contents of [command] are executed.

この場合、Pythonを使って[web]サーバーを[0.0.0.0]の[8000番ポート]を使用して立ち上げるコマンドを実行します。

In this case, use Python and start the web server using [port 8000] at address [0.0.0.0].

[0.0.0.0]はすべてのネットワーク・インターフェースを表しています。

[0.0.0.0] refers to all network interfaces.

つまり同じネットワーク上にいる全てのサーバーからのアクセスを許可します。

This allows access from all servers on the same network.

外部サーバーは通常はDokcerコンテナの外側からはそのコンテナと通信できませんが、

External servers normally cannot communicate with the Dokcer container from outside,

このようにするとホストマシンからループバックアドレスでコンテナアプリにアクセスすることができるようになります。

but this allows the host machine to access the container's apps with a loopback address.

一時的に一行飛ばして、次の行の説明をします。[ports]で指定してある[8000:8000]は、[ホストマシンのポート、コロンで区切って、コンテナのポート]を意味します。

Next, I'll temporarily skip a line and explain the next line. The [8000:8000] indicated by the [ports] means [Host machine ports, separated by colons, container ports].

つまり、先ほどの[0.0.0.0:8000]はコンテナ以外のホストマシン(あなたが今使用しているOS)と8000番ポートを介して通信できることを意味しています。

This means that the [0.0.0.0 : 8000] mentioned above can communicate with non-container host machines (OS you are using now) via port 8000.

[localhost:8000]とホストマシンのOS側のブラウザからアクセスすれば、

In a nutshell, if [localhost: 8000] is accessed from the browser on the OS side of the host machine,

8000番ポートを通じてコンテナのDjangoアプリとブラウザ(クライアント)は通信できることになります。

the container's Django app can communicate with the browser (Client) via port 8000.

その前の行にある[volumes]の[.:/code]は、先程のportsと同様に「ホストマシンのパス、コロンで区切って、コンテナのパス」と書きます。

The [.:/code] in the [volumes] in the previous line, like the ports above, means [host machine path, colon-separated container path].

つまり、ymlファイルが置かれているディレクトリをコンテナ内の[/code]ディレクトリにマウント、つまり認識できるようにします。

This means that the directory in which the yml file resides will be mounted to the [/code] directory in the container, making it visible to the container.

最後の行の[depends_on]はコンテナ間の起動の順番を決めます。

The [depends_on] in the last line determines the order of startup between containers.

この場合は[db]サービスから起動を開始してから、[web]サービスの起動を開始します。

Start the [db] service first, and then start the [web] service.

さあ、準備ができたら、[docker-compose run]コマンドを使って、イメージのプルとコンテナ作成を行います。

Now, when you are ready, use the [docker-compose run] command to pull the image and create a container.

username@PC:~/your-working-directory$ docker-compose run web django-admin.py startproject your_project_name

そして[web]、つまりDjangoアプリのコンテナに対して[django-admin.py startproject your_project_name]を実行させて、Djangoのプロジェクトを作成します。

Then let the [web] service, the container of the Django app, run [django-admin.py startproject your_project_name] to create a Django project.

WSL2のUbuntuではdjango-adminが作ったフォルダやファイルの所有者が[root]になってしまいます。

In WSL2 Ubuntu, the owner of the folders and files created by django-admin is the [root].

そこでVS Codeでファイルの編集が行えるようにするため、[sudo chown]を使ってファイルの所有者をユーザーに変更します。

To allow VS Code to edit the file, use [sudo chown] to change the owner of the file to the user.

username@PC:~/your-working-directory$ sudo chown -R $USER:$USER .

作成されたDjangoのプロジェクトの[settings.py]を開いて、データベースにpostgresqlを使うように設定します。

Open the [settings.py] of the Django project you just created and configure it to use postgresql for its database.

settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'postgres',
        'USER': 'postgres',
        'HOST': 'db',
        'PORT': 5432,
    }
}

では、[docker-compose up]を使ってDjangoサーバーを立ち上げましょう。

Now start the Django server with [docker-compose up].

username@PC:~/your-working-directory$ docker-compose up

DBのエラーが出てしまったら、[contorl + C]でサービスを停止して、

If you get a DB error, stop the service with [contorl + C],

[docker-compose.yml]の[db]サービス内の環境変数に、DBのユーザーネームやパスワードを設定して、

set the DB username and password in the environment variable in [docker-compose.yml]'s [db] service,

docker-compose.yml
version: '3'

services:
    db:
        image: postgres
        environment: 
            POSTGRES_DB: postgres
            POSTGRES_USERS: postgres
            POSTGRES_PASSWORD: test_postgres
    web:
        build: .
        command: python3 manage.py runserver 0.0.0.0:8000
        volumes:
            - .:/code
        ports:
            - "8000:8000"
        depends_on:
            - db

Djangoプロジェクトの[settings.py]にそのパスワード等を書くように修正しましょう。

and modify it to write the password on the [settings.py] of Django project.

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

ではもう一度[docker-compose up]でサーバーを立ち上げ、ブラウザを立ち上げて[localhost:8000]でアクセスしてみましょう。

Now, let's launch the server again with [docker-compose up], launch the browser and access it with [localhost:8000].

username@PC:~/your-working-directory$ docker-compose up

日本語の表示対応や日本時間の設定も[settings.py]に書くことができます。

You can also write settings for Japanese display and Tokyo time in [settings.py].

settings.py
LANGUAGE_CODE = 'ja-jp'

TIME_ZONE = 'Asia/Tokyo'

それでは[docker-compose run]を使って簡単なDjangoのアプリケーションを作成しましょう。

Let's use [docker-compose run] to create a simple Django application.

username@PC:~/your-working-directory$ docker-compose run web python manage.py startapp your-app-name

[sudo chown]を使ってファイルの所有者をユーザーに変更します。

Use [sudo chown] to change the owner of the file to the user.

username@PC:~/your-working-directory$ sudo chown -R $USER:$USER .

後はいつものようにアプリの[urls.py]と[views.py]、そしてプロジェクトの[urls.py]を設定して動作を確認してくだちぃ。

Then, as usual, set [urls.py] and [views.py] of the application and [urls.py] of the project, and check the operation.

サービスを停止する別の方法を試してみましょう。

Let's try another way to stop the service.

別の[ubuntuターミナル]を立ち上げて、作業用ディレクトリに移動して、[docker-compose down]を実行するだけです。

Just launch another [ubuntu Terminal], change to your working directory, and run [docker-compose down].

username@PC:~/your-working-directory$ docker-compose down

試しに、コンテナのPythonに何か新しいモジュールをインストールしてみましょう。

Let's try installing some new module in the container's Python.

[docker-compose up]でコンテナを立ち上げて、別の[ubuntuターミナル]から[docker exec]コマンドを使って[gunicorn]をインストールしてみます。

Try launching the container in the [docker-compose up] and installing the [gunicorn] using the [docker exec] command from another [Ubuntu terminal].

username@PC:~/your-working-directory$ docker ps
username@PC:~/your-working-directory$ docker exec [container-id] pip install gunicorn

最後に[Dockerコンテナ]と[Dcokerイメージ]を別々に一括で削除してみましょう。

Finally, delete [Docker Container] and [Dcoker Image] separately.

その前に[docker ps]を使用して[container id]を調べておくと便利です。

Before doing so, it is useful to check [docker ps] for [container id].

やり方は簡単で[docker ps -a]コマンドで一覧表示したコンテナに対して、[docker rm]コマンドを実行するだけどぅえす。

It's easy to do. Simply execute the [docker rm] command on the containers listed with the [docker ps -a] command.

Dockerイメージの削除も同様に、[docker images -a]コマンドで一覧表示したイメージに対して[docker rmi]コマンドを実行するだけどぅえす。

To delete a Docker image, simply run the [docker rmi] command on the images listed with the [docker images -a] command.

username@PC:~/your-working-directory$ docker rm $(docker ps -aq)
username@PC:~/your-working-directory$ docker images -aq | xargs docker rmi

パイプと[xargs]、$マークを使用、どちらでも使い易いほうを使ってくだちぃ。

You can use a pipe and either [xargs] or $ mark. Please use the one you think is easy to use.



以上です。お疲れ様です。

That's all. Thank you for your hard work.