Dockerの基本操作 ~WEBサーバを起動する~

## はじめに
Docker の基本操作コマンドを使って、WEBサーバを起動してみます。

## 事前準備
ローカル環境で Docker を操作するため、Docker Desktop をインストール。

https://qiita.com/R_R/items/a09fab09ce9fa9e905c5

## 操作の流れ

1. Docker Hub でイメージを探す
2. イメージを取得する
3. イメージからコンテナを起動する
4. コンテナ内に入って操作する
5. コンテナを停止・再開してみる
6. コンテナを削除する
7. イメージを削除する

## 1. Docker Hub でイメージを探す
まずはじめに、[Docker Hub](https://hub.docker.com/) で、目的のイメージを探します。
WEBサーバなので、nginx のイメージを探したいと思います。

1-1. [Docker Hub](https://hub.docker.com/) にアクセスし、 Explore をクリックします。
![1-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/917499/302ece2c-ab03-325a-fd97-005847d64a80.png)

1-2. イメージの一覧が表示されるので、検索ボックスから、 nginx を検索します。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/917499/701d0bda-fb0f-87aa-5586-66ebab3e8d42.png)

1-3. nginx をクリックします。
　（Docker Hubには、公式のイメージとサードパーティのイメージがあります。公式のイメージには、OFFICIAL IMAGE タグが付いています。）
![3-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/917499/cd83990c-8e2f-aa28-2cf9-06726fb81097.png)

1-4. イメージの詳細を確認する。

赤枠のコマンド（ `$ docker pull [イメージのリポジトリ名]` ）を実行するとイメージを取得できます。
![4-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/917499/20595f22-63ac-1a89-45a5-b2576746d022.png)

Tags のページに行くと、nginx イメージのタグ一覧が確認できます。
タグを付けることで一意のイメージ名にし、バージョン管理をします。
`$ docker pull [リポジトリ名]:[タグ名]` と実行することで、指定したタグのイメージを取得できます。
タグ名を指定しなければ、最新（ `latest` タグ）のイメージを取得します。
![99.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/917499/c40a629c-5b93-ce38-9306-402823a145b3.png)


Description の下の方へスクロールすると、マニュアルが確認できます。
今回は、赤枠のコマンド実行し、WEBサーバを起動します。
![5-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/917499/7006a2b5-434c-9ab9-72e5-c2e0b22413f3.png)

## 2. イメージを取得する
Docker Hub で確認した nginx イメージの取得コマンドを実行します。
`$ docker pull nginx`
今回はタグは指定せず、最新のイメージを取得してみます。

```bash
$ docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
45b42c59be33: Pull complete
8acc495f1d91: Pull complete
ec3bd7de90d7: Pull complete
19e2441aeeab: Pull complete
f5a38c5f8d4e: Pull complete
83500d851118: Pull complete
Digest: sha256:f3693fe50d5b1df1ecd315d54813a77afd56b0245a404055a946574deb6b34fc
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
```
イメージが取得できているか、以下のコマンドを実行して確認します。
`$ docker images`

```bash
$ docker images
REPOSITORY                    TAG                 IMAGE ID       CREATED         SIZE
nginx                         latest              35c43ace9216   2 weeks ago     133MB
```
`$ docker images` コマンドを実行することで、イメージの一覧を表示できます。
`latest` タグの nginx イメージを取得できていることが確認できました。

### ~ 備考 ~
※ Docker Hub からの pull の回数には制限が設けられているので、ご注意ください。

https://matsuand.github.io/docs.docker.jp.onthefly/docker-hub/download-rate-limit/

制限内容はユーザーの種別により異なります。

- Docker Hubに未登録のユーザー: 6時間あたり100回まで
- Docker Hubに登録済みのユーザー: 6時間あたり200回まで
- 有料のProプランまたはTeamプランのユーザー: 無制限
 

## 3. イメージからコンテナを起動する
イメージが取得できたので、イメージを元にコンテナを起動します。
コンテナを起動には、以下のコマンドを実行します。
`$ docker run --name [任意のコンテナ名] -d -p [ホストのポート:コンテナのポート] [リポジトリ名 もしくは IMAGE ID]`

```bash
$ docker run --name my-container -d -p 8080:80 nginx
7d1d101ba0d7794e0b7bd81e3da5a49dd09dc523057e1b6ceb8287bd52b35cce
```

- `$ docker run` コマンド実行時のオプションについて

|オプション|省略形|説明|補足|
|---|---|---|---|---|
|--detach|-d|Run container in background and print container ID|バックグラウンドで実行するオプション|
|--publish|-p|Publish a container's port(s) to the host|ポートフォワーディング|

次に、コンテナが起動できたか確認してみます。
`$ docker container ls` もしくは `$ docker ps` コマンドで起動中のコンテナ一覧が確認できます。

```bash
$ docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED              STATUS              PORTS                  NAMES
7d1d101ba0d7   nginx     "/docker-entrypoint.…"   About a minute ago   Up About a minute   0.0.0.0:8080->80/tcp   my-container
```
STATUS が Up （起動中）であることが確認できました。

この状態で `http://localhost:8080/` にアクセスしてみてください。
![88.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/917499/1526a4b1-3487-4224-06ed-f8f0e38d3b0c.png)

nginxが起動していることを確認できました。

- `$ docker ps` コマンドの実行結果の見方

|項目|意味|
|---|---|
|CONTAINER ID|コンテナID。ランダムな64文字で構成されているが、表示されるのは先頭の12文字|
|IMAGE|コンテナ作成元のイメージ名|
|COMMAND|コンテナ起動時に与えられたコマンド|
|CREATED|コンテナが作成されてから経過した時間|
|STATUS|コンテナのステータス。起動時は「Up」、停止時は「Exited」となる|
|PORTS|バインドしているポート番号|
|NAMES|任意でつけたコンテナ名|


## 4. コンテナ内に入って操作する
以下のように `docker exec` コマンドを実行することで、起動中のコンテナの中でコマンドを実行し操作ができます。

`docker exec -it <コンテナ名> bash`

```bash
$ docker exec -it fd5229760afd bash
root@fd5229760afd:/#
```
- ターミナルからコンテナ内で操作するために、 `-it` オプションを付与しています。

|オプション|省略形|説明|補足|
|---|---|---|---|---|
|--interactive|-i|Keep STDIN open even if not attached|コンテナ内でコマンドを実行するオプション。標準入出力をコンテナに対して結びつける。つまり、入力した文字はコンテナに渡され、コンテナからの出力が画面に表示されるようになる。|
|--tty|-t|Allocate a pseudo-TTY|コンテナ内に入るオプション。疑似tty割り当て。|

試しにindex.htmlの内容を書き換えて、操作できることを確認してみます。

```bash
echo "Hello Docker!" > /usr/share/nginx/html/index.html
```

この状態で `http://localhost:8080/` にアクセスすると、 `Hello Docker!` の文字が表示されているはずです。

## 5. コンテナを停止・再開してみる
5-1. 起動中のコンテナを停止・再開してみます。

停止するには以下のコマンドを実行します。
`$ docker stop [コンテナ名 もしくは CONTAINER ID]`

```bash
$ docker stop my-container
my-container
```
`$ docker ps` で状態を確認してみます。

```bash
$ docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
```
起動中のコンテナがないことが確認できました。

`$ docker ps` に `-a` オプションを指定して、停止中のコンテナも含めすべて表示してみます。

```bash
$ docker ps -a
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS                      PORTS     NAMES
7d1d101ba0d7   nginx     "/docker-entrypoint.…"   30 minutes ago   Exited (0) 12 seconds ago             my-container
```
STATUS が Exited（停止状態）であることが確認できます。

この状態で `http://localhost:8080/` にアクセスしてみてください。
nginx は動いていないので、アクセスできなくなります。
![87.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/917499/e3134391-c3bf-a8f0-f550-561d17231e70.png)

5-2. 続けて、コンテナを再開したいと思います。
コンテナの再開には以下のコマンドを実行します。
`$ docker start [コンテナ名 もしくは CONTAINER ID]`

```bash
$ docker start my-container
my-container
```
`$ docker ps` で状態を確認してみます。

```bash
$ docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS         PORTS                  NAMES
7d1d101ba0d7   nginx     "/docker-entrypoint.…"   38 minutes ago   Up 4 seconds   0.0.0.0:8080->80/tcp   my-container
```
STATUS が Up （起動中）になりました。

ブラウザをリロードすれば、起動していることを確認できます。
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3931373439392f31353236613462312d333438372d343232342d303665642d6638663065333864336230632e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/917499/59f16445-dc08-db53-f3cf-0464b84af38f.png)

## 6. コンテナを削除する
WEBサーバの起動ができたので、コンテナを削除していきます。
コンテナを削除するには、まず起動中のコンテナを停止状態にする必要があります。

```bash
$ docker stop my-container
my-container
```

停止ができたら、以下のコマンドを実行してコンテナを削除します。
`$ docker rm [コンテナ名 もしくは CONTAINER ID]`

```bash
$ docker rm my-container
my-container
```
コンテナの削除が完了すると、`$ docker ps -a` で確認しても表示されなくなります。

```bash
$ docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
```

※ `$ docker rm` に `-f` オプションを付けると、コンテナが起動状態でも削除可能です。

```bash
$ docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS     NAMES
a7a816853a9d   nginx     "/docker-entrypoint.…"   7 seconds ago   Up 6 seconds   80/tcp    bold_khayyam

$ docker rm -f a7a816853a9d
a7a816853a9d

$ docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
```

## 7. イメージを削除する
最後にイメージを削除していきます。
イメージの削除には、以下のコマンドを実行します。
`$ docker rmi [IMAGE ID]`

```bash
$ docker images
REPOSITORY                    TAG                 IMAGE ID       CREATED         SIZE
nginx                         latest              35c43ace9216   2 weeks ago     133MB

$ docker rmi 35c43ace9216
Untagged: nginx:latest
Untagged: nginx@sha256:f3693fe50d5b1df1ecd315d54813a77afd56b0245a404055a946574deb6b34fc
Deleted: sha256:35c43ace9216212c0f0e546a65eec93fa9fc8e96b25880ee222b7ed2ca1d2151
Deleted: sha256:61f2666cb67e4572a31412367fa44567e6ac238226385762ea65670ed39034a8
Deleted: sha256:622fb7fb6a35078e3a2d446bb0e74c6a0cd500e3a211fd17ecbbcea5377ded38
Deleted: sha256:69a8591f1aaa7d694fa79a187886f6690e6e51e8c2bc91727be01a9e87daacd2
Deleted: sha256:8a451c701633832102e10093db7545eada8e5639a1b35bb14afaf48601948802
Deleted: sha256:2edbde38832e9e0e07d113df74817dc736fd49ea2f9c0d7ce8e40e3446b49b82
Deleted: sha256:9eb82f04c782ef3f5ca25911e60d75e441ce0fe82e49f0dbf02c81a3161d1300

$ docker images
REPOSITORY                    TAG                 IMAGE ID       CREATED         SIZE
```
`docker images` でイメージが表示されなければ、削除完了です。

## 次回
- Dockerfile の作成
- 作成した Dockerfile からイメージ作成、コンテナ起動
- 作成したイメージをリポジトリへプッシュ