Dockerコンテナ構築手順① Dockerfile編

## 概要
Dockerでコンテナを構築するハンズオン勉強会の資料(初級者向け)
Windows10での利用を想定していますが、Macでもコマンドは全く同一です。

## Dockerのコンテナ構築の流れ

**１．Docker Desktopをインストールする**
※アカウント登録が必要
:point_right: https://www.docker.com/products/docker-desktop

**２．Docker Hubでベースになるイメージを探す**
※ docker searchコマンドでも検索できるが、タグ(バージョン)が確認できないのでWebから　
:point_right: https://hub.docker.com/

**３．イメージを元にコンテナを構築する(操作はコマンド)**

---

## Dockerコマンドとライフサイクル
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140013/9b7c1b0b-c166-a54f-4860-75bb57fe1bdd.png)

---

## 基本コマンド

- **ps**：コンテナの確認

```bash
> docker ps [オプション]
# Example
> docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS               NAMES
3e53409e35f7        mysql:latest        "docker-entrypoint.s…"   9 seconds ago       Exited (1) 5 seconds ago                       frosty_cori
88bd2626a86b        python:3.6-slim     "python3"                3 hours ago         Up 3 hours                                     py
```
|よく使うオプション|意味|
|:--:|:--:|
|-a|停止中含め全て|

---

- **images**：イメージの確認

```bash
> docker images [オプション]
# Example
> docker images
REPOSITORY                                                 TAG                 IMAGE ID            CREATED             SIZE
web/python                                                 1.0                 a8bd9ef27d77        23 hours ago        138MB
httpd                                                      alpine              324a76ee954f        13 days ago         124MB
mysql                                                      latest              990386cbd5c0        2 weeks ago         443MB
python                                                     3.6-slim            903e8a0f0681        2 months ago        138MB
```

- **pull**：イメージの取得

```bash
> docker pull [オプション] <イメージ[:タグ]>
# Example
> docker pull python:3.6-slim
```

---

- **run**：新しいコンテナの起動

```bash
> docker run [オプション] <イメージ[:タグ]> [コマンド]
# Example
> docker run -itd -p 5000:80 --name pyweb python:3.6-slim
```
|よく使うオプション|意味|
|:--:|:--:|
|-i|コンテナの標準入力にアタッチ|
|-t|疑似ターミナルを割り当て|
|-d|コンテナをバックグラウンドで実行<br>(デタッチドモード)|
|-p|コンテナのポートをローカルに公開<br>(ポートのマッピング)<br>"ホスト側ポート:コンテナ側ポート"で指定|
|--name|コンテナに名前をつける|

---

- **build**：Dockerfileからイメージを構築

```bash
> docker build [オプション] <Dockerfileが置かれているディレクトリパス>
# Example
> docker build -t web/python:1.0 dockerdir
```

|よく使うオプション|意味|
|:--:|:--:|
|-t|'名前:タグ' 形式で生成するイメージに名前とタグをつける|

---

- **exec**：起動中のコンテナ上でコマンドを実行

```bash
> docker exec [オプション] <コンテナ名orコンテナID> <コマンド>
# Example
> docker exec -it ubuntu bash
```
|よく使うオプション|意味|
|:--:|:--:|
|-i|アタッチしていなくても標準入力をオープンにし続ける|
|-t|疑似ターミナルを割り当て|
|-d|コマンドをバックグラウンドで実行(デタッチドモード)|

- コンテナ上で実行中のBashを終了する(ホストに戻る)
`ctrl + D`  

---

- **cp**：ホスト/コンテナ間でファイルをコピーする

```bash
# ホストからコンテナ
> docker cp <ホストパス> <[コンテナ名orコンテナID:]パス>
# コンテナからホスト
> docker cp <[コンテナ名orコンテナID:]パス> <ホストパス>
# Example
> docker cp conf.ini /var/www
> docker cp ubuntu:/var/www/log/ ./log/
```

---

- **start**：作成済みコンテナの起動

```bash
> docker start [オプション] <コンテナ名orコンテナID> [コンテナ名orコンテナID...]
# Example
> docker start ubuntu
```
|よく使うオプション|意味|
|:--:|:--:|
|-a|標準出力にアタッチする|
|-i|コンテナの標準入力にアタッチ|

---

- **stop**：コンテナの停止

```bash
> docker stop [オプション] <コンテナ名orコンテナID> [コンテナ名orコンテナID...]
# Example
> docker stop ubuntu
```

- **rm**：コンテナの削除

```bash
> docker rm [オプション] <コンテナ名orコンテナID> [コンテナorコンテナID...]
# Example
> docker rm ubuntu
```

---

- **rmi**：イメージの削除

```bash
> docker rmi [オプション] <イメージ名:タグorイメージID> [イメージ名:タグorイメージID...]
# Example
> docker rmi web/python:1.0
```

その他のコマンド(公式リファレンス): http://docs.docker.jp/engine/reference/commandline/index.html

---

## コンテナを手動で構築する
まずは手動でコンテナを構築してみましょう
練習用にPythonで動くHTTPサーバを作ります

１. [Docker Hub](https://hub.docker.com/)にアクセスし、ベースになるコンテナイメージを探す
![docker01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140013/f9afecd4-fdbc-fbdd-44f1-01762546853c.png)


２. Docker Hubからpythonのコンテナイメージをコピー
今回はpythonが動けばなんでもいいので、軽量な「3.6-slim」を利用します

```bash

C:¥Users¥USERNAME> docker pull python:3.6-slim
```

３. イメージを元にコンテナを起動
5000番ポートを80番ポートにマッピングして、なまえは「pyweb」にします

```bash
C:¥Users¥USERNAME> docker run -itd -p 5000:80 --name pyweb python:3.6-slim
```

---

４. コンテナの起動状態の確認

```bash
C:¥Users¥USERNAME> docker ps -a
```

５. 起動中のコンテナ内のBashを呼ぶ

```bash
C:¥Users¥USERNAME> docker exec -it pyweb bash
```

６. コンテナ内にHTMLを配置するディレクトリを作成

```bash:
pyweb@b1d94102fcea:/# mkdir /var/www
```
７. コンテナ内のBashを終了(ローカルに戻る)
`ctrl + D`

---

８. ローカルのユーザディレクトリの配下にHTMLを作成
>C:¥Users¥USERNAME(※PCにより"USERNAME"が異なります)
>　　└ index.html

```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
</head>
<body>
  <h1>Hello Docker!!</h1>
</body>
</html>
```

---

９. ホストからコンテナへHTMLファイルをコピー

```bash
C:¥Users¥USERNAME> docker cp ./index.html pyweb:/var/www/index.html
```

１０. もう一度起動中のコンテナのBashを呼ぶ

```bash
C:¥Users¥USERNAME> docker exec -it pyweb bash
```

１１. index.htmlのあるディレクトリへ移動し、PythonのHTTPサービスを実行

```bash
pyweb@b1d94102fcea:/# cd /var/www
pyweb@b1d94102fcea:/# python -m http.server 80
```

１２. ローカルのブラウザから確認（index.htmlの内容が表示されれば完成！）
`localhost:5000`

---

## Dockerfileを利用してコンテナを構築する
実際に上で手動構築したコンテナと同じものをDockerfileを使って構築してみましょう

:point_down: Dockerfileとは
https://qiita.com/aminosan000/private/e5e5c0028ff2e67c07c5

１. 上で作ったコンテナの停止と削除
※ ローカル側のポート or コンテナ名が重複するとビルドできないので手動作成したコンテナをまず削除
サービスが起動中の場合、`ctrl + C`で停止後`ctrl + D`でローカルに戻ってから

```bash
C:¥Users¥USERNAME> docker stop pyweb
C:¥Users¥USERNAME> docker rm pyweb
```

---

２. Dockerfile用のディレクトリを作成し、index.htmlを移動
※Dockerfileからのビルド時はディレクトリ内のファイルすべてがコピーされるので、必ずDockerfile用のディレクトリを作成してください。
>C:¥Users¥USERNAME
>　　└ dockerdir
>　　　　└ index.html

---

３. Dockerfile(ファイル名"Dockerfile"のテキストファイル)を作成
※Windowsで拡張子.txtがついている場合、"名前の変更"で拡張子を削除
>C:¥Users¥USERNAME
>　　└ dockerdir
>　　　　├ Dockerfile
>　　　　└ index.html

先ほどの手順をそのままDockerfileにします

```docker:Dockerfile
FROM python:3.6-slim
RUN mkdir /var/www
COPY ./index.html /var/www
WORKDIR /var/www
CMD python -m http.server 80
```

---

４. Dockerイメージのビルド
「web/python」というイメージ名と「1.0」というタグをつけておきます

```bash
C:¥Users¥USERNAME> docker build -t web/python:1.0 dockerdir
```

５. ビルドしたイメージの確認

```bash
C:¥Users¥USERNAME> docker images
```

---

６. ビルドしたイメージを元にコンテナを起動

```bash
C:¥Users¥USERNAME> docker run -itd -p 5000:80 --name pyweb web/python:1.0
```

７. ローカルのブラウザから確認（index.htmlの内容が表示されれば完成！）
`localhost:5000`

---

## Next
Dockerコンテナ構築手順② Docker Compose編:
https://qiita.com/aminosan000/private/6f1d1b1e730e01907fbc