Docker

# 概要

Dockerに関する基礎知識。

# Dockerとは

コンテナ船に載っているコンテナのように、サーバを起動させる上での土台（環境）をひとまとめにしてアプリケーションの実行環境を作れるサービス。

# Dokcerのコマンド

|コマンド|説明|
---|---
docker image build|Dockerfileからイメージを構築する
docker image ls|イメージを一覧で表示する
docker image rm|イメージを削除する
docker container run|新しいコンテナを実行する<br>（ローカルに指定された名前のDockerイメージがないかを探し、見つからない場合はDockerHubから自動的にダウンロードする仕組み）
docker container ls|コンテナの一覧を表示する
docker container ls -a|コンテナの一覧を表示する（停止したコンテナを含む）
docker container rm|コンテナを削除する
docker-compose up -d|（`docker-compose.yml`に記述された内容で）<br>バックグラウンドで複数のコンテナを起動する
docker-compose down|コンテナを停止し、 up で作成したコンテナ、ネットワーク、ボリューム、イメージを削除
docker container exec -it コンテナ名 bash|コンテナ内に入る
docker-compose logs -f|バックグラウンドで起動しているコンテナのログを見る



# Docker Composeとは

* `Docker Compose`とは複数のコンテナを扱うアプリケーションを定義・実行するツールのこと。
* `docker-compose.yml`というファイルにコンテナ起動時のあるべき状態を記述。
    * 簡単にコンテナのライフサイクルを回すことができる。
* 複雑なオプションを設定ファイルに記述しておくことで実行を容易にする。

### Dokcer composeを使わない場合


```毎回起動オプションを指定
docker container run -d --name php-project -v $(pwd):/var/www/html -p 80:80 php:7.4-apache
```

* 補足説明
    * `-d`：バックグラウンドで行う
    * `--name`:起動したコンテナにつける名前
    * `-v $(pwd):/var/www/html`:カレントディレクトリ(`$(pwd)`)をコンテナの`/var/www/html`ディレクトリにマウント
        * これにより以下のメリットがある
            * コンテナの中で作ったファイルがコンテナを削除しても消えない
            * ホストでphpファイルを編集した時にコンテナ内に反映されるようになる
    * `-p`:ホストの80番ポートにコンテナの80番ポートをポートフォワードしている
    * `php:7.4-apache`:Docker HubにあるPHPの公式イメージの中でも`php:7.4-apache`と名前がついたイメージを使う
        * Dockerイメージの指定でこのように`:`がついている場合は`:`の後ろをタグと呼ぶ
            * タグにより使用するバージョンを指定できる

### Dokcer composeを使った場合

コマンドはシンプルになる✨（複数人で開発するときにも楽）

```オプションはdocker-compose.ymlに記述
docker-compose up -d
```

```docker-compose.yml
version: '3'
services:
  web:
    container_name: php-project
    image: php:7.4-apache
    ports:
      - "80:80"
    volumes:
      - .:/var/www/html
```

# Dockerfileとは

* Docker Hub等にある公開されているDockerイメージをベースにして独自のDockerイメージを作ることができるもの。
* Dockerfileには、コンテナに必要なミドルウェアのインストールや各種設定を記述する。
* 同じDockerfileから起動されるコンテナはどこで立ち上げても同じ状態で起動されるためDockerエンジンを動かすプラットフォームの差異（macOS,Linux,Windows）を吸収することができる。

### Dockerfileを書くうえで基本となるコマンド

|命令句|意味|
---|---
FROM|ベースイメージを指定する。<br>パブリックリポジトリで公開されているイメージを指定するのが一般的。
RUN|コマンドを実行し、その結果をDockerイメージにコミットする。<br>独自のDockerイメージを作る際に最もよく使われるコマンド。<br>`RUN yum install hoge`のような形でシェルで実行するコマンドを記述する。
WORKDIR|作業ディレクトリを指定。<br>`RUN cd xxx`を使うより、`WORKDIR xxx`を使うことが推奨されている。
COPY|Dockerビルドを実行するホスト上からファイルやディレクトリをコピーする。
CMD|コンテナ実行時のデフォルトのコマンドを指定。<br>CMD句は一度だけ指定可能で、複数ある場合は一番後ろにあるCMD句が有効になる。

```dockerfile
FROM php:7.4-apache

RUN apt-get update

RUN apt-get install -y vim
```

```terminal
//ビルド
docker image build -t php-project:ver1 .

//コンテナ起動
docker image build -t php-project:ver1 .

//コンテナ内に入る
docker container exec -it php-project-vim bash

//Vimが使える
vim --version
```

# マウントとは

* Linux特有の言葉で、「ディスク装置をLinuxのディレクトリに埋め込み使えるようにする」こと。
* イメージしやすいのは、USBメモリ。
    * USBメモリをパソコンに挿すとFinderにボタンが出てきてUSBメモリ内の画像を消したり編集したりできる。
    * 同じようにDockerのコンテナをマウントさせて、ソースコードを書き換えて動作を見ながら、機能等を作っていく。
    * その「くっつけて操作できるようにする」ことをマウントという。


# BindとVolumeの違い

* そのマウントさせる方法がいくつかあり、代表的な方法として「Bind」と「Volume」がある。

## Bind

* コンテナを、”ファイルシステム”にくっつけること。
    * さっきのUSBメモリと似ている。
    * Finderから対象のフォルダ・ファイルに移動して編集すると、Dockerの内容も書き変わっていく。
    * ただし「重くて遅くなる」という特性がある。（非推奨）

## Volume

* コンテナを、”ファイルシステム内にあるDocker Area”にくっつけること。
    * Docker AreaはDockerによって管理されており、DockerCLI（黒画面のこと）からアクセス可能になる。
    * つまり、「Bindと比べてアクセスしづらいけど、Docker内（ローカルの手元から切り離された空間）で動作するので速い」という特性がある。（推奨）
* `docker exec -it コンテナ名 bash`のコマンドを実行して、Docker Areaにアクセスしている。