dockerについてメモ


勉強したことをメモするだけ

## docekr周りの用語
- Dockerエンジン
    - Dockerにおいてコンテナ仮想化を実現するためのコアとなる機能を持った部分がDockerエンジン
    - Dockerエンジによってコンテナ作成などの機能が提供されている

- Dockerfile
    - Dockeイメージを作成するための指示書となる設定ファイル。
    - Dockerfileという名前のファイルがデフォルトでビルド時に使用される。(別名のものを使用することも可能)
- Dockerイメージ
    - dockerコンテナを作成するための雛形となるもの
    - アプリケーション、ライブラリ、設定ファイルなどのアプリケーションに必要なものを一式まとめたもの
    - 出来上がったアプリケーションをdocekerイメージとして保存して、別のサーバーに持っていくことで同じ環境(コンテナ)を別サーバー上で再現することができる
- ビルドキャッシュ
    - Dockerイメージをビルドした際に、イメージのレイヤーごとにビルド結果がキャッシュされる。このキャッシュのことをビルドキャッシュと呼ぶ。
    - Dockerfileをもとにビルドした内容に差がない場合、2回目以降のビルドは初回より早くなる。
    - Dockerfileに変更があったり、関連するファイルに差があった場合、ビルドキャッシュは使われず再度ビルドが行われるそうな
- Dockerコンテナ
    - dockerイメージをもとにされるコンテナ型仮想環境のことをdockerコンテナと呼ぶ
    - イメージからコンテナを作成することで、何度も同じ環境のコンテナを作成することができる
    - コンテナを起動することであらかじめイメージにセットアップしたアプリケーションの機能を提供することができる
- DockerHub
    - Dockerイメージを保存するためのサービス
    - AWSでいうところのECR
- ブリッジネットワーク
    - 同一のDockerホスト上でコンテナ間通信するために使用されるネットワーク。
    - 同一のブリッジネットワークに属するコンテン同志は相互に通信することができる。

## Dockerを使うメリット
- プログラムの実行環境を素早く立ち上げることができる
- 再現性のある環境を用意できる
    - 本番でもdockerを使う場合、開発環境と本番環境との差異が生まれにくくなる
- 設定ファイル(dockerfile)を共有することでプロジェクトメンバー間で同じ環境を立ち上げることができる
- PCの環境を汚さずに済む

## コンテナ起動時ににコマンドを実行する
```
$ docker run イメージ名 実行したいコマンド
```
イメージ名の後ろにコマンドをつければ実行されるそう
```
$ docker run docker/whalesay cowsay Hello~~~!
//これを実行すると

Unable to find image 'docker/whalesay:latest' locally
latest: Pulling from docker/whalesay
Image docker.io/docker/whalesay:latest uses outdated schema1 manifest format. Please upgrade to a schema2 image for better future compatibility. More information at https://docs.docker.com/registry/spec/deprecated-schema-v1/
e190868d63f8: Pull complete
909cd34c6fd7: Pull complete
0b9bfabab7c1: Pull complete
a3ed95caeb02: Pull complete
00bf65475aba: Pull complete
c57b6bcc83e3: Pull complete
8978f6879e2f: Pull complete
8eed3712d2cf: Pull complete
Digest: sha256:178598e51a26abbc958b8a2e48825c90bc22e641de3d31e18aaf55f3258ba93b
Status: Downloaded newer image for docker/whalesay:latest
 ___________
< Hello~~~! >
 -----------
    \
     \
      \
                    ##        .
              ## ## ##       ==
           ## ## ## ##      ===
       /""""""""""""""""___/ ===
  ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ /  ===- ~~~
       \______ o          __/
        \    \        __/
          \____\______/

```
鯨がしゃべっていて正常に動いていることがわりますね。

> latest: Pulling from docker/whalesay

docker/whalesayイメージのlatestがpullされています。

> e190868d63f8: Pull complete

imageっちゅうのはレイアーの積み重ねでできているそうで
その各レイアーイメージがpullされている。

> Digest: sha256:178598e51a26abbc958b8a2e48825c90bc22e641de3d31e18aaf55f3258ba93b

取得したイメージをsha256で暗号化している

> Status: Downloaded newer image for docker/whalesay:latest

イメージの取得結果

もう一回やってみましょう。
```
$ docker run docker/whalesay cowsay Hello~~~!
 ___________
< Hello~~~! >
 -----------
    \
     \
      \
                    ##        .
              ## ## ##       ==
           ## ## ## ##      ===
       /""""""""""""""""___/ ===
  ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ /  ===- ~~~
       \______ o          __/
        \    \        __/
          \____\______/

```

すでにimageがpullされているので、
先ほどpullしたimageが使われていますね。

```
$ docker image ls | grep docker/whalesay
docker/whalesay                       latest      6b362a9f73eb   7 years ago     247MB
```
localにあるimageを見てみると先ほどpullしたイメージがありますね。

## イメージ取得 / コンテナ削除 / イメージ削除

### イメージ取得
```
$docker pull イメージ名
```
tagを指定しない場合latestタグのものが自動的に選ばれる。
latestタグと言ってもそれが最新であるというものではないらしい
```
$docker pull hello-world
$ docker image ls | grep hello
hello-world                           latest      feb5d9fea6a5   13 months ago   13.3kB
```
```
$ docker run hello-world
Hello from Docker!
```

### コンテナ削除
imageを削除する前に立ち上げたコンテナを削除する必要がある
```
$docker rm コンテナid
```

```
//コンテナ確認
$docker container ls -a | grep hello
21983004b274   hello-world              "/hello"                 2 minutes ago   Exited (0) 2 minutes ago                                      brave_elion

//コンテナ削除
$docker rm 21983004b27
```

### イメージ削除
```
$ docker image rm イメージid
//もしくは
$ docker rmi イメージid
```
```
//イメージ確認
$ docker image ls | grep hello

//イメージ削除
$ docker rmi feb5d9fea6a5
```

## Dockerfile

## Dockerのネットワーク
### 作成されているネットワークの確認
```
$ docker network ls
NETWORK ID     NAME                      DRIVER    SCOPE
286e88a25efd   bridge                    bridge    local
19f3778cfa48   host                      host      local
```

### ネットワーク詳細の確認
```
$ docker network inspect bridge
[
    {
        "Name": "bridge",
        "Id": "286e88a25efd0cdb9f346f962767d641f90ded6217930238a9ae3b4b9aa59f27",
        "Created": "2022-11-03T07:28:07.469054236Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]
```

## DockerCompose
### 実行ステップ
- イメージの指定
    - Dockerfileを指定、もしくはDockerHubなどにあるものを使う
- docker-composer.ymlを定義する
    - dockerコンテナ起動時の設定を定義するもの
    - dokcer runコマンドにオプションで色々つけるようなこと
- docker-compose upを実行

## コンテナログイン
### dockerコマンドの場合
```
$ docker exec -it コンテナ名 /bin/bash
or
$ docker exec -it コンテナ名 /bin/sh
```
```
//立ち上がってるコンテナを確認
$ docker ps
CONTAINER ID   IMAGE                COMMAND                  CREATED          STATUS          PORTS                NAMES
471f14219833   sample_nginx         "/docker-entrypoint.…"   20 minutes ago   Up 20 minutes   0.0.0.0:80->80/tcp   sample_nginx
81f7898f575f   sample_app           "docker-php-entrypoi…"   20 minutes ago   Up 20 minutes   9000/tcp             sample_app
08a95be64589   postgres:12-alpine   "docker-entrypoint.s…"   20 minutes ago   Up 20 minutes   5432/tcp             sample_db

//sample_appコンテナに入ってみる
$ docker exec -it sample_app /bin/bash
OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: exec: "/bin/bash": stat /bin/bash: no such file or directory: unknown
//↑入れなかった
/bin/shで入る
$ docker exec -it sample_app /bin/sh
/app #
```
/bin/bashがダメで/bin/shで行ける理由がよくわからない。

### docker-compose使ってる場合
```
$ docker-compose exec サービス名 /bin/sh
```
今回はappというサービス名で立ち上げているので
```
$ docker-compose exec app /bin/sh
/app #
```
## Dockerの3種類のマウント

- ボリュームマウント
    - ホストPC上にコンテナ用のデータファイルを作成し、コンテナ内の特定のディレクトリパスにマッピングする。複数のコンテナから1つのボリュームを共有することができる。コンテナ内で作成したファイルの永続化にはこのボリューム方法が推奨されている。
 
- バインドマウント
    - ホストPCの特定のディレクトリ(絶対パス指定)を、コンテナ内の特定のディレクトリパスにマッピングする。ホスト側からコンテナで操作したファイルを確認する際にはバインドマウントは有効。開発する際などに利用すると良さそう。

- tmpfsマウント
    - ホストPCのメモリ領域を、コンテナの特定のディレクトリパスにマッピングする。