はじめに
Python のフレームワークである Django のアプリケーションを用いて Dockerfile を作成してみた備忘録です。
事前準備
事前準備として Docker の image と container は空の状態からスタートします。
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
$docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Django プロジェクトの作成
今回はこちらの記事で作成した Django で作成したアプリを使用します。
記事を読まなくもよいように抑えておくべきことだけを説明すると、以下のコマンドを実行することでアプリが起動します。
$ python manage.py runserver
アプリが起動している状態で http://localhost:8000/hello
にアクセスすると以下のような Hello World が表示される簡単なアプリです。
構造
以下に示したような構造になります。
GitHub にも公開しております。
$ tree
.
├── Dockerfile
├── requirements.txt
├── hello
│ └── (省略)
├── helloWorldProject
│ └── (省略)
├── README.md
├── db.sqlite3
└── manage.py
Dockerfile
と requirements.txt
は今回作成すべきファイルになるのでそちらについて解説します。
Dockerfile の作成
今回は以下のように作成しました。
# python:3.8の公式 image をベースの image として設定
FROM python:3.8
# 作業ディレクトリの作成
RUN mkdir /code
# 作業ディレクトリの設定
WORKDIR /code
# カレントディレクトリにある資産をコンテナ上の指定のディレクトリにコピーする
ADD . /code
# pipでrequirements.txtに指定されているパッケージを追加する
RUN pip install -r requirements.txt
# 起動(コンテナのポート8002番で受け付けるように起動する)
CMD python3 manage.py runserver 0.0.0.0:8002
今回のファイルの内容は以下のようになります。
- python:3.8の公式 image をベースにして、作業ディレクトリ(
/code
) を作成する - 現在のソースを全てこのコンテナに写し換える
- 必要なモジュールを pip でインストールする
- コンテナ起動時にアプリケーションを起動するということが書かれております。
Dockerfile の書き方については説明を省略いたします。
RUN
と CMD
の違いはこちらの記事がわかりやすかったです。
(簡単に説明すると、RUN
は build 中に実行されるコマンドで、CMD
はコンテナ起動時に実行されるコマンドです。)
requirements.txt の作成
Dockerfile で記述したように pip コマンドでインストールするモジュールは requirements.txt
に記述するようにしました。
今回は Django が必要になるため、そちらを記述します。
Django==3.1
今回のようにモジュールが一つの場合は外部ファイルにする必要はあまりないですが、インストールするモジュールが複数ある場合はこのように記載すると管理が楽です。
Dockerfile から image の作成
Dockerfile を用意した後に docker build -t [作成する image 名] [Dockerfileまでの相対パス]
コマンドを実行することで image が作成されます。
今回は hello-world
という名前の image を作成します。
$ docker build -t hello-world .
(省略)
Successfully tagged hello-world:latest
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest 6e2fc6616ab1 About a minute ago 922MB
python 3.8 6feb119dd186 5 days ago 882MB
このように hello-world
という image が作成されたことがわかります。
ついでに python:3.8
の image も pull されて表示されます。
SIZE
の項目をみると python
よりも hello-world
の方が大きいことから、元にした image に色々と追加されていることが伺えますね。
コンテナの起動
image を作成したので、コンテナを起動させます。
$ docker container run -d -p 8001:8002 hello-world
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ff92b40204f3 hello-world "/bin/sh -c 'python3…" About an hour ago Up About an hour 0.0.0.0:8001->8002/tcp funny_antonelli
run
コマンドのオプションについて補足は以下の通りになります。
-
-d
:バックグラウンドで起動する -
-p
:コンテナのポートを公開する
今回は 8001:8002
と指定しているので、「ホストの 8001 番ポート」と「コンテナの 8002 番ポート」を紐づけいているという意味になります。
(本来は 8001番 や 8002 番のポートは使用しませんが、ホストとコンテナのポート番号を意識するためにあえて変わった番号を用いております。)
http://localhost:8001/hello
にアクセスすると以下のように表示されるはずです。
メリット
Dockerfile ファイルを記述することで、
『この Docker Image を pull してから、docker container run コマンドを実行した際は、必ず毎回、そのコンテナにログインして、このコマンドとこのコマンドを実行して〜(省略)』
などの手順書が
『 Dockerfile があるディレクトリで docker build -t [イメージ名] . コマンドを実行する。』
の1行で済むようになります。
例えば、今回のケースであれば Dockerfile の FROM python:3.8
より下は全部手順書に示さなければなりません。
まとめ
- Dockerfile を作成した
- Dockerfile から image を作成した
- 作成した image からコンテナを起動して挙動を確認した