【ふくだ学習録】Docker入門 part7【26日目】

# ふくだ学習録とは？
ふくだが学習したことの備忘録。
目に見える形で残すことによってやる気を出す個人的な作戦です。
他人に見せるように書いているわけではないので、すごく読みにくいです。

### 読了した本
[データベースエンジニア養成読本 [DBを自由自在に活用するための知識とノウハウ満載!]](https://www.amazon.co.jp/dp/4774158062/ref=cm_sw_r_tw_dp_U_x_FPphEbQFPPQRM )
[ゼロから作るDeepLearning](https://www.amazon.co.jp/dp/4873117585/ref=cm_sw_r_tw_dp_U_x_y3UiEbF3P6EG7)
[PHPフレームワーク CakePHP 3入門](https://www.amazon.co.jp/dp/4798048577/ref=cm_sw_r_tw_dp_U_x_.YIjEbS1K4JY2)
[SQLアンチパターン](https://www.amazon.co.jp/dp/4873115892/ref=cm_sw_r_tw_dp_U_x_XlokEbJQK2N7P )

### 今読んでいる本

[Docker入門](https://www.amazon.co.jp/dp/480071091X/ref=cm_sw_r_tw_dp_U_x_xVlmEbN8ZTHZK)

# Docker入門

### Dockerfileの基本書式
「命令行」「コメント行」「空行」から構成されている。
行頭に命令を記述し、それに続いて引数を記述した行が「命令行」。buildサブコマンドは、この行に従ってイメージを作成する。
行頭に#を記述した行は「コメント行」、何も書いていないのが「空行」。

### ベースイメージを使用せずにイメージ作成をする時。
ベースイメージを使用する際は、一番初めに`FROM イメージ`を記載するが、０→１でイメージを作っていく場合は、`FROM scratch`と記載する。


```dockerfile
# ベースイメージを指定する時(リポジトリ指定をしない場合は、DockerHubからイメージ取得する)
FROM [リポジトリ名[:タグ名]]

# ０→1で作っていく時
FROM scratch
```

### buildサブコマンドで生成される中間イメージの確認方法
buildサブコマンドを使用すると。Dockerfile内の命令行を処理するたびに、作業用コンテの作成と、そのコンテナからの中間イメージ生成の2つの処理が実行されていく。
途中で生成された中間イメージを確認したいときは。`history`サブコマンドを使うことで確認できる。

### Dockerfileでの命令行は少なくしていこう
前述したようにdockerでは命令行ごとに中間イメージが作成されていくため、命令行が増えていくと中間イメージも増えていき、消費するディスク容量や、イメージ管理の手間が増える。

#### 解決策１：コマンドを繋げる
例えばコマンドは`&&`で繋げていくなどして命令行数を減らしていくことが結構大事になってくる。（もちろん可読性も重要なので、バランスが大事。）

`&&`：前のコマンドが正常終了した場合に、次のコマンドを実行する。
`;` ：単純に、前のコマンドが終了してから次のコマンドを実行する。
`&` ：前のコマンドと次のコマンドを同時に実行する。

#### export,importで中間イメージを使わないイメージを生成する（そもそもDockerfile使用しないパターン）
`export`は、コンテナのファイルシステムデータをtarアーカイブに変換して出力するサブコマンド。
`import`は、そうして出力されたtarアーカイブなどから、イメージを生成するサブコマンド。

これらを組み合わせて、基のイメージから生成されたコンテナからexportサブコマンドでtarアーカイブを生成し、そのtarアーカイブからimportサブコマンドでイメージを生成することで、中間イメージのない単一階層のイメージを生成できる。

ただし注意点としては、export/import処理によって、ファイルシステムデータ以外のイメージ設定情報は全て抜け落ちてしまうため、-cオプションを使用して、Dockerfileに記述するのと同様の命令を指定する工夫が必要。

### 命令行が長くなる場合
`\`で開業して書くことができる。

### 余分なファイルをDockerサーバーにコピーしない
Dockerfileを格納する作業ディレクトリ内のファイルやサブディレクトリは、buildサブコマンド実行時にDockerサーバーにまとめて送られるため。不要なファイルを格納していた場合、余分な通信が発生してしまう。できるだけ不要なファイルを置かないようにする（もしくは`.dockerignore`というファイルが置かれたディレクトリ以下のデータはDockerサーバーに送信されないため、それを活用する。）

### ADD命令とCOPY命令では、コピー先の末尾「/」に注意する
「/」をつけるとディレクトリ、「/」をつけないとファイル名と解釈される。

### プライベートレジストリの構築方法
下記のコマンドを入力すると、プライベートレジストリを作成できる。

```console
$ sudo mkdir -p /var/lib/docker-registry
$ docker run -d -p 5000:5000 -v /var/lib/docker-registry:/var/lib/registry --restart=always registry:2
```

2回目以降の起動時には、mkdirコマンドは実行しなくてもよい。
runサブコマンドのオプションの意味は、
`5000:5000`→ Dockerサーバーが稼働するホストのTCP5000番ポートで通信を待ち受けるための設定。
`/var/lib/docker-registry`→ リポジトリのデータを格納するためのホスト上のディレクトリ。
`--restart=always`→ エラーなどで停止した場合に、自動的にコンテナを再起動する設定。

上記コマンドだけでは完全版のレジストリを構築できているわけではない。理由としては、Dockerでは、Dockerサーバーとレジストリとの間の通信を保護するため、TLSプロトコルで通信路の暗号化と通信相手の認証を行なっているが、前述のコマンドだけではTLSで使用するデジタル証明書や暗号鍵が設定されていないため、TLSを使用した通信に対応できないから。（Dockerサーバーの規定設定では、TLSに非対応のレジストリとは同じホスト上でしか通信できないようになっている）

その方法は
**①プライベートレジストリをTLS対応にする（正攻法）**
レジストリ用の秘密鍵/公開鍵のペアを作成した上で、証明書を格納する。
**②TLSを無効にした通信を許可させる。（手軽）**
特定のレジストリに対して、TLSを無効にした通信を許可するには、Dockerサーバーを`--insecure-registry=レジストリのIPアドレス:ポート番号`というオプション付きで起動する必要がある。

### --linkオプション
コンテナ実行時に使用しておくと、他のコンテナとの通信を容易に実現できるようになるオプション。

# 今日の一言
今日は起きるのが7:10とかで、始めるのがだいぶ遅れてしまった。
6:20に池田エライザからモニコかかってきてほしい！