Docker再入門

Dockerにあまり触れる機会が少なく、たまに使うとコマンドとか仕組みをすぐに忘れてしまう。そんな自分へのナレッジ

# 公式ドキュメント

[Docker Documentation](https://docs.docker.com/)
上部のメニューで、[Guides](https://docs.docker.com/), [Product manuals](https://docs.docker.com/ee/), [Glossary](https://docs.docker.com/glossary/), [Reference](https://docs.docker.com/reference/), [Samples](https://docs.docker.com/samples/) に分かれていて、選択すると左側にコンテンツがツリーで表示される。

特によく使うであろうリファレンスはこちら
[Docker CLI コマンド](https://docs.docker.com/engine/reference/commandline/docker/)
[Dockerfile reference](https://docs.docker.com/engine/reference/builder/)

# Dockerコンテナを起動・実行する

### コンテナを生成して起動する
```
docker run [OPTIONS] IMAGE [COMMAND] [引数...]
```
- Dockerイメージからコンテナを作成して、指定したプロセスを起動する。
- Dockerイメージは、ホスト内にあればそれを使い、なければ設定されているReposityからPullする。
- docker create -> docker start をまとめて実行しているイメージ
- `--name [コンテナ名]` 定義しておくと他のコマンドでコンテナを指定するときに、この名前が使える。
- `-it` は、コンテナの起動時コマンドが `/bin/bash` などの場合に指定する。そうしないとコンテナが起動してもすぐ終了してしまう。 

コンテナが起動してもすぐ終了してしまうのは、バックグラウンドで動かそうとしていたからの模様。
以下のリンク先ブログのように、実行コマンドを `tail -f /dev/null` にするのが良いみたい。
[コンテナをバックグラウンドで動かすハック](http://kimh.github.io/blog/jp/docker/gothas-in-writing-dockerfile-jp/#hack_to_run_container_in_the_background)

(追記：久しぶりに読み返ていたら結局どうしたらいいかわからなかったのでコマンド例。こうするとバックグランドで起動したままにできる)
`docker run --name <Container Name> -d IMAGE tail -f /dev/null`

ちなみにBambooのDocker Runnerからコンテナを実行した時にプロセスを見たら、 `tail -f /dev/null` となっていた。

### 作成済のコンテナを起動する
```
docker start [OPTIONS] CONTAINER [CONTAIER...]
```

### 起動中のコンテナを停止する
```
docker stop [OPTIONS] CONTAINER [CONTAINER...]
```

### イメージからコンテナを生成する
```
docker create [OPTIONS] IMAGE [COMMAND] [ARG...]
```
- イメージからコンテナを作成するだけで、起動はしない
- だから、起動するには、 `docker start` を実行する
- docker run からコンテナの起動部分を除いた感じ
- なので、docker run とほぼ同じオプションを指定できる

# Dockerコンテナを管理する

### ホストPCから起動中のコンテナに接続する
```
docker attach [OPTIONS] CONTAINER
```
- サーバーにSSH接続するようなイメージで、コンテナ内部にアクセスできる
- :warning: 切断してコンテナから抜けるには、 `Ctrl + P` -> `Ctrl + Q` を使わないと、**プロセス自体も終了する**ので気を付ける。
- 実行中のコンテナプロセスがshellを起動していればアクセスできる。
- Shellが起動していなければ、後述の`docker exec` でShellを起動する

### 起動中のコンテナでコマンドを実行する
```
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
```
- コンテナに、別のプロセスを実行させる時に利用する
- 例えば起動中のコンテナがShellを起動していないので、 `docker attach` でアクセスできない場合に代わりに `docker exec -it CONTAINER /bin/bash` を実行するとアクセスできる

### コンテナを一覧表示する
```
docker ps [OPTIONS]
```
- `-a` をつけると、起動していないコンテナも表示できる

### コンテナのログを表示する
```
docker logs [OPTIONS] CONTAINER
```

### コンテナのリソース使用量の統計情報を表示する
```
docker stats [OPTIONS] [CONTAINER...]
```
- 起動中のコンテナにおける現在のCPU使用率やメモリ使用量・使用率を表示する
- 表示を終了するときは、 Ctrl + C

### コンテナのプロセス実行状況を表示する
```
docker top CONTAINER [ps OPTIONS]
```

### コンテナを削除する
```
docker rm [OPTIONS] CONTAINER [CONTAINER...]
```

# Dockerイメージを管理する

### Dockerfileから、イメージを生成する
```
docker build [OPTIONS] PATH | URL | -
```
- Dockerfileの指定は、ファイルパス, URLを指定できる
- `-t name:tag` オプションでイメージ名とタグを指定する

Dockerfileの主なコマンド
- `FROM` で、ベースとなるイメージを指定する
- `RUN` で、プロセス起動に必要なパッケージやコマンドを実行する
- `ADD` で、外部サイトからのファイルダウンロードを行う。  (curlして、tar.gzを展開するような操作なんだけど、あくまでもtarを解凍するのにADDを使って、ダウンロードはCurlなりWgetを使った方が良いと述べられていたりするので要検討)
- `COPY` で、ホストのファイルをコンテナにコピーする
- `ENV` で
- `ENTRYPOINT` と `CMD` で、コンテナ起動時に実行するプロセスコマンドを定義する。(ENTRYPOINT と CMDは役割が違うので使い方はよく調べること)

流れはこんな感じ
1. `FROM` でコンテナのベースを作る
2. `RUN` `ADD` `COPY` `ENV` などでコンテナで実行するプロセスに必要なパッケージのインストール、設定を行う
3. `ENTRYPOINT` `CMD` でプロセスを実行する

コマンドの詳細やDockerfileの書き方は [Dockerfile reference](https://docs.docker.com/engine/reference/builder/) や [Best practices for writing Dockerfiles](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/) などを参照

### ホストに存在するDockerイメージを一覧表示する
```
docker images [OPTIONS] [IMAGE[:TAG]]
```
- イメージのサイズなどもここで見ることができる。

### Dockerイメージをレジストリからプル(ダウンロード)する
```
docker pull [OPTIONS] NAME[:TAG|@DIGEST]
```
- Docker Hub などのRepositoryにあるDockerイメージをダウンロードする。
- `docker run` や `docker create` でダウンロードしていないイメージを使おうとした場合は、自動的にPullされる

### ホスト内のDockerイメージを削除する
```
docker rmi [OPTIONS] IMAGE [IMAGE...]
```
- 削除する時には、ImageIDやRepository:TAG が必要なので、`docker images` で確認する。
- コンテナが作成済のImageは削除できないので、 `--force` オプションをつけるか、該当のコンテナを削除する

# Dockerをインストールする

## Linux にインストールする

Docker Community Engine として以下の3つをインストールする

```
- docker-ce
- docker-ce-cli
- containerd.io
```

もちろん依存しているパッケージがあり、インストールの手順はLinuxのディストリビューションによっても異なるので、詳細は、[Get Docker](https://docs.docker.com/install/) を見ること

## MacやWindows にインストールする

MacやWindowsの場合、Docker-ce を実行するための動作環境(Linuxの仮想環境)が必要になる。
この仮想環境や拡張機能なども含まれている、Docker Desktop for Mac / Docker Desktop for Winows をインストールする

### Docker Desktop for Mac

こちらのDocumentを参考にインストールする
https://docs.docker.com/docker-for-mac/

homebrew caskを使っている場合は、以下でもインストールできる

```
brew cask install docker
```

`brew install docker` もあるがこれは、Docker-ceのみしかインストールしないので、brew caskでインストールすること。
これは`brew cask info docker` と `brew info docker` のVersion番号から判断できる。

### Docker Desktop for Windows

使ったことが無いので詳細は不明だが、こちらのDocumentを参考にインストールしていけば良いと思う。
https://docs.docker.com/docker-for-windows/