【とりあえずハンズオン】Dockerfileでコンテナを作ろう

# はじめに

この記事では AWS Cloud Tech を通して Docker を学習して実践していく記事です。
主な内容としては実践したときのメモを中心に書きます。（忘れやすいことなど）
誤りなどがあれば書き直していく予定です。

https://aws-cloud-tech.com/

## 動作環境

### Windows10 Pro

Docker for Windows v20.10.5

### M1 CPU 搭載型 MacBook

Docker for Mac v20.10.3

## Dockerfile

### Dockerfile を書くとは

コンテナ技術において Dockerfile を書くということは
アプリケーションの動作環境をコードにして起こすことを指す。

### Dockerfile を書くことのメリット

Docker ファイルを書くことで
アプリケーションの動作環境をコードにして起こすことが可能になる為
動作環境ドキュメントとしても利用できる。

具体的にはそのアプリケーションに必要なパッケージやコンフィグファイルを
イメージという単位で 1 箇所にまとめて管理することで
動作環境の構成をクリーンに保つことができる。

## ひとつ書いて実行してみるその前に

### 今回ハンズオンで利用するコード

https://github.com/ymd65536/django_test/

### Dockerfile に書く命令

CloudTech の Docker 講座で閲覧できる Dockerfile の構成
CloudTech では Python の Web フレームワークである Django を例に
コンテナ作成を紹介しています。

```Dockerfile

# Test stage
FROM alpine AS test
LABEL application=todobackend

# Install basic utilities
RUN apk add --no-cache bash git

# Install build dependencies
RUN apk add --no-cache gcc python3-dev py3-pip libffi-dev musl-dev linux-headers mariadb-dev
RUN pip3 install wheel -U

# Copy requirements
COPY /src/requirements* /build/
WORKDIR /build

# Build and install requirements
RUN pip3 wheel -r requirements_test.txt --no-cache-dir --no-input
RUN pip3 install -r requirements_test.txt -f /build --no-index --no-cache-dir

# Copy source code
COPY /src /app
WORKDIR /app

# Test entrypoint
CMD ["python3", "manage.py", "test", "--noinput", "--settings=todobackend.settings_test"]


```

### FROM

いろんなテキスト、記事を読むと以下のような説明が書いてある。

> コンテナのベースとなるベースイメージを指定する。

つまりは、どういうことかというと
コンテナ上で動作する OS を指定するという意味に近い。

今回は alpine Linux と呼ばれる LinuxOS をベースイメージとしている。

### LABEL

イメージ情報にコメントや作成者情報を入れる。

### COPY

ホスト OS(Docker を動かす OS)のファイルを
イメージ内にコピーで取り込む

このときホスト OS 上で参照できるファイルは
Docker を起動したパス(ビルドコンテキスト)に限る。

### WORKDIR

Dockerfile に定義された命令をどのディレクトリで実行するかを決める。
いわゆる、cd コマンド

### RUN

イメージを生成するときに実行するコマンドを指定する。

### CMD

RUN はイメージを生成するときに利用するコマンドであるのに対して
CMD はイメージをもとに生成したコンテナ上で実行するコマンドを指定する。

## 実際に動かしてみよう

イメージを作成
イメージからコンテナを作成
コンテナに bash で入る
コンテナを実行
コンテナを削除
イメージを削除

```powershell

# 現在のDocker イメージを確認
$ docker images

# まずは不要なイメージをすべて削除
$ docker rmi -f $(docker images -q)

# 現在参照しているDockerfileをmyimage1というタグをつけてビルド
$ docker build -t myimage1 .

# コンテナに入ってみる。コンテナnameはtest
$ docker run -it --name test --rm myimage1 /bin/bash

# 入れることがわかったのでexit
bash-5.1 $ exit
exit

# Django を実行 コンテナnameはtest
$ docker run -it --name test --rm myimage1
nosetests --verbosity=2 --nologcapture --with-coverage --cover-package=todo --with-spec --spec-color --with-xunit --xunit-file=./unittests.xml --cover-xml --cover-xml-file=./coverage.xml
Creating test database for alias 'default'...

----------------------------------------------------------------------
XML: /app/unittests.xml
Name                              Stmts   Miss  Cover
-----------------------------------------------------
todo/__init__.py                      0      0   100%
todo/admin.py                         1      1     0%
todo/migrations/0001_initial.py       8      3    62%
todo/migrations/__init__.py           0      0   100%
todo/models.py                        6      6     0%
-----------------------------------------------------
TOTAL                                15     10    33%
----------------------------------------------------------------------
Ran 0 tests in 0.000s

OK

Destroying test database for alias 'default'...

```

補足
PowerShell の場合のイメージ一括削除は

```powershell
# まずは不要なイメージをすべて削除
$ docker rmi -f $(docker images -q)
```

となるが、MacBook および Linux では以下のコマンドがイメージの一括削除となる。

```bash
# まずは不要なイメージをすべて削除
$ docker rmi -f `docker images -q`
```

## まとめ

今回は Django でコンテナを作成してテストコマンドをコンテナ上で実行しました。

今回のポイント

- Dockerfile を利用することでアプリケーションの動作環境をコードにできる。
- 動作環境をコードにすることで Dockerfile 自体が動作環境ドキュメントとして利用できる。
- コンテナ内にファイルを取り込むときはホスト OS 上のビルドコンテキストを意識する。

## おわり