Dockerにおけるコンテナ

## はじめに
こちらはDockerコンテナについてまとめた記事になります。情報が陳腐化している箇所があるかもですがご了承いただければ幸いです。:bow:

以下は、私がDocker関連についてまとめている記事になります。もし興味がありましたらご覧になってください。
* [Dockerにおけるコンテナ](https://qiita.com/Hirohana/items/c881118021fd156ccefe "Dockerにおけるコンテナ") 
* [Dockerにおけるイメージとは](https://qiita.com/Hirohana/items/a7b11c72e525c48d34bf "Dockerにおけるイメージとは") 
* [Dockerにおけるネットワーク](https://qiita.com/Hirohana/items/3fff1a1d11a0f1505dad "Dockerにおけるネットワーク") 
* [Dockerにおけるデータ管理](https://qiita.com/Hirohana/items/59a22d549fcfb096f0b9 "Dockerにおけるデータ管理")

## Dockerコンテナとは
:::note info
Dockerコンテナは実行に必要なすべての依存関係（ライブラリ、実行環境、設定ファイルなど）をカプセル化し、実行するための環境を提供します。
:::

Dockerコンテナに関連するコマンドを説明していきます。

最初にコンテナを作成、起動するために一番使われる`docker run`コマンドについて確認したいと思います。

## コンテナを作成、起動するdocker runコマンド

```terminal: terminal
$ docker run hello-world
```
![スクリーンショット (246).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1220815/7b08b341-54fe-fa57-d62c-cf1443c1f276.png)

:::note info
**docker run** コマンドの流れ
1. DockerクライアントからDockerデーモンに対して`hello-world`のimageファイルを探しに行く。もしimageファイルがあればDocker Hubに対してimageファイルを探しに行かない。
2. DockerデーモンがDocker Hubに対してimageファイルを探しにいく。
2. imageが見つかったらダウンロードしてPC上に保存する。
2. Dockerデーモンは保存したimageを元にコンテナを立ち上げて、コンテナで定義されたコマンドを実行する。
:::

実は`docker run`は、イメージを取得するコマンド`docker pull`、コンテナを作成する`docker create`、コンテナを起動する`docker start`をひとまとめにしたコマンドです。

![スクリーンショット (247).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1220815/6df548c0-1f19-c6d0-0cf3-e100daab9a5f.png)

### docker runに引数を渡して実行

以下のように、`docker run dokcer/whalesay`の後に、`cowsay Hello!`と記述することでコンテナが立ち上がった後にコマンドを実行することができます。

```terminal: terminal
$ docker run docker/whalesay cowsay Hello!
```

### docker runにオプションを渡して実行

`$ docker run --name <コンテナ名> -d -p <ホスト側のポート番号>:<コンテナ側のポート番号> <イメージ名>`コマンドで、オプションを渡してコンテナを立ち上げることも可能です。
```terminal: terminal 
$ docker run --name some-nginx -d -p 8080:80 some-content-nginx
```

`--rm`オプションはコンテナを停止した際に、コンテナそのものも破棄するオプションです。
```terminal: termina
$ docker run --name tmp-nginx --rm -d nginx
```

`docker run --name <コンテナ名> -d -v <ホスト側のディレクトリ>:<コンテナ側のマウントポイント>:<オプション>`　コマンドの`-v`オプションは、dockerホストのファイルやディレクトリをコンテナに紐づけるバインドマウントが設定できるオプションです。

-vオプションで指定するディレクトリは絶対パスで書く必要があります。
```terminal: terminal
$ docker run --name some-nginx -v /some/content:/usr/share/nginx/html:ro -d nginx
```

また、Dockerコンテナと対話式にやり取りする場合には`-it`オプションを使います。
```terminal: terminal
$ docker create --name status-test -it alpine /bin/sh
```

## コンテナのライフサイクル

以下は、コンテナの状態遷移図です。コンテナの状態は`docker ps -a`や`docker inspect コンテナ名orID`コマンドで確認することができます。

![スクリーンショット (250).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1220815/95ce3cbf-dde1-73bd-e7f3-a5e6a6a4532c.png)

どのDockerコマンドを実行したら、どう状態が遷移するかを箇条書きでまとめました。

:::note info
**コンテナのライフサイクル**
* `Created`状態は`docker create`コマンドでコンテナを作成した時の状態です。
* `Running`状態は`docker start`コマンドでコンテナを起動したときの状態です。
* `docker run`コマンドはイメージの取得⇒コンテナの作成⇒コンテナの起動を行うので、`Created`から`Running`と1つのコマンドで状態が遷移します。
* `Paused`は`docker pause`コマンドで`Running`から`Paused`状態へ遷移します。そして、`docker unpause`コマンドで`Paused`から`Running`状態へ戻ります。
* `Exited`は`docker stop`コマンドでコンテナを停止した時の状態です。
* `Restart`は`docker restart`コマンドでコンテナを再起動したときに一瞬遷移します。ただ`Restart`から`Running`に遷移するのではなく一度`Exited`に遷移してから`Running`状態に戻ります。
* `Dead`状態はコンテナ内でエラーが発生した時などに遷移することがあります。
* `Removing`は`docker rm`コマンドでコンテナを破棄するときの状態です。
:::

## コンテナへの接続

コンテナには、`docker exec`コマンドを使って接続することができます。

```terminal: terminal
$ docker run -d --name connect-test ubuntu tail -f /dev/null

$ docker exec -it connect-test /bin/bash
```

* Ubuntuイメージを基にしたconnect-testという名前のコンテナがバックグラウンドで作成・実行されます。
* tail -f /dev/nullは、無限に継続するプロセスであり、コンテナが実行中のままになります。
* 外部からDockerコンテナ内に対話的なセッションを開き、コンテナ内部でBashシェルを利用できます。

## 終わりに
最後まで記事をご覧いただきありがとうございました。

間違い等ありましたらご指摘いただけると幸いです:bow:

## 参考

https://docs.docker.jp/