Docker入門

# Dockerとは
Dockerはアプリケーションをコンテナ化して管理や実行をするプラットフォームである

# Dockerのメリット
・開発環境の共有や破棄が楽
・ノートパソコンの固有の問題やOSの影響を受けない
・開発者のローカル環境、テスト環境、本番環境の違いによる問題を最小限に抑えることができる

# Dockerイメージとは
コンテナを作るための設計書

### イメージを扱うコマンド
イメージを削除するコマンド
```
docker image rm <イメージ名>
```
イメージの一覧を表示するコマンド
```
docker image ls
```
イメージの詳細情報を表示するコマンド
```
docker image inspect <イメージ名>
```
### イメージの容量を小さくするには

イメージの容量を小さくするにはレイヤー構造を意識してかくべきである

`レイヤー`とはソフトウェアやシステムを階層構造で分割したものである
`レイヤー構造`とはレイヤーが複数連なったもののことである

イメージのレイヤー構造を知るコマンド
```
docker image history <イメージ名>
```

`Dockerfile1`はレイヤーを意識せずに書いている
```dockerfile:Dockerfile1
FROM ubuntu
RUN apt update
RUN apt install -y curl
CMD ["/bin/bash"]
```
レイヤー構造を意識して`Dockerfile1`を書き直すと
```dockerfile:Dockerfile2
FROM ubuntu
RUN apt update && apt install -y curl
CMD ["/bin/bash"]
```
`&&`を使うことでレイヤーが少なくなり`Dockerfile1`で作ったイメージよりも`Dockerfile2`で作ったイメージの方が容量が小さくなる
# Dockerコンテナとは
イメージをもとに作られる開発環境

### コンテナのライフサイクル
コンテナを作成したときは`Create`の状態になる
コンテナを起動すると`Up`の状態になる
コンテナが終了すると`Exited`の状態になる

### コンテナを扱うコマンド
コンテナの作成はここでは説明しない(コンテナを作る方法で詳しく書いている)

コンテナが`Exited`から`Up`にするコマンド
```
docker container restart <コンテナ名>
```
コンテナが`Up`から`Exited`にするコマンド
```
docker container stop <コンテナ名>
```
コンテナを削除するコマンド
```
docker container rm <コンテナ名>
```
`Exited`になっているコンテナを一括で削除するコマンド
```
docker container prune
```
`Up`になっているコンテナを削除するコマンド
```
docker container container rm -f <コンテナ名>
```
コンテナを起動して任意のコマンドを実行させるコマンド
```
docker container run -it <イメージ名> <実行したいコマンド>
```
`Up`の状態のコンテナに対して任意のコマンドを実行させるコマンド
```
docker container exec -it <コンテナ名> <実行したいコマンド>
```
コンテナに好きな名前を付けるコマンド
```
docker container run --name <好きな名前> <イメージ名>
```
`Up`の状態のコンテナだけを一覧で見るコマンド
```
docker container ls
```
`Up`の状態のコンテナだけを一覧で見るコマンド
```
docker ps
```
すべてのコンテナを一覧で見るコマンド
```
docker container ls -a
```
すべてのコンテナを一覧で見るコマンド
```
docker ps -a
```

### コンテナオプショ
`-i`:標準入力を受け付ける
`-t`:見た目をターミナルぽくする
`-d`：コンテナをデタッチモード（バックグラウンド）で実行する
`--rm`:コンテナを終了したら`Exited`状態にならずコンテナを削除するコマンド
`--name <コンテナ名>`：コンテナに好きな名前を付けるコマンド

# コンテナを作る方法
●1つ目は自分でDockerfileを作って実行する方法(一般的)
●2つ目はDockerhubからイメージを持ってくる方法


## Dockerfileを作ってコンテナを作るやり方
①Dockerfileを作成
②イメージを作成
③イメージを確認
④コンテナ作成
⑤コンテナを確認


### ①Dockerfileを作成
`Dockerfile`とはイメージを作るための設定ファイルのこと

まず、プロジェクトディレクトリにDockerfileを作成する。
以下は、シンプルなPythonアプリケーションのDockerfileの例である。

```dockerfile:Dockerfile
# ベースイメージを指定
FROM python:3.9-slim

# 作業ディレクトリを設定
WORKDIR /app

# 必要なパッケージをインストール
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# アプリケーションコードをコピー
COPY . .

# コンテナ起動時のデフォルトのコマンド
CMD ["python", "app.py"]
```

### ②イメージを作成
ターミナルを開き、Dockerfileがあるディレクトリに移動する。
そして、以下のコマンドを実行してイメージを作成する。

```
docker image build -t <イメージ名> .
```

`docker image build`：Dockerイメージを作成するコマンド
`-t <イメージ名>`：イメージに好きなイメージ名を付けることのできるコマンド
`.`:現在のディレクトリにDockerfileがあることを示すコマンド


### ③Dockerイメージを確認

イメージが作成できたら、以下のコマンドを実行してイメージが作成されたことを確認する。
```
docker image ls
```
### ④コンテナ作成
以下のコマンドで先ほどのイメージをもとにコンテナを作成する。
```
docker container run -itd --name <コンテナ名> <イメージ名>
```

### ⑤コンテナ作成されたか確認
コンテナが作成できたら、以下のコマンドを実行してコンテナが作成されたことを確認する。
```
docker container ls
```

# Dockerhubからイメージを取ってきてコンテナを作成する方法
`Dockerhub`とはDockerイメージをホストし、共有できる公式のリポジトリサービスである。

https://hub.docker.com/

①Dockerhubからイメージを取得する
②イメージを確認
③コンテナ作成
④コンテナを確認

### ①Dockerhubからイメージを取得する
Dockerhubで使いたいイメージを見つけて、以下のコマンドでイメージを取得する
```
docker image pull <イメージ名>
```

### ②イメージを確認
イメージが取得できたら、以下のコマンドを実行してイメージが作成されたことを確認する。


```
docker image ls
```

### ④コンテナ作成
以下のコマンドでイメージからコンテナを作成する。
```
docker container run --name <アプリ名> -itd <イメージ名>
```

### ⑤コンテナを確認
コンテナが作成できたら、以下のコマンドを実行してコンテナが作成されたことを確認する。

```
docker container ls
```

# Dockerfileでの環境変数の設定方法
ENVやARGで設定できる。
```dockerfile:Dockerfile
FROM ubuntu:20.04

ENV password="sakura"

ARG message

#messageの変数の中身をmessage.txtに入れる
RUN echo $message > message.txt

#catコマンドでmessage.txtの中身を出力する
CMD ["cat", "message.txt"]
```
### ENVの実行方法
コンテナを作成してコンテナの中に入り`bash`で以下のコマンドを実行する
```
echo $password
```
これで`sakura`が出力される
### ARGの実行方法
イメージを作成するときにARGの`message`の中に文字を入れる
```
docker image build --build-arg message="Hello" .
```
そしてコンテナを作成する
```
docker container run -it <イメージ名>
```
これを実行するとmessageの内容の`Hello`が表示される

### `ENV`と`ARG`の違い

`ENV`はコンテナの中でも実行することができる
`ARG`はイメージをビルドするときしか使用できない

# ビルドコンテキストの理解
```
docker image build .
```
の`.`はビルドコンテキストとしてdockerデーモンに送られている
もしDokerfileでCOPYコマンドを書いたがコピーしたいファイルがDokerfileと同じディレクトリに存在しないとき、コピーしたいファイルのあるディレクトリにいき以下のコマンドを実行する.
```
docker image build -f <Dockerfileがあるディレクトリの場所を指定> .
```
例 tmpファイルのしたにDockerfileがある場合
```
docker image build -f tmp/Dockerfile .
```
これによりイメージを作成することができる
# COPYしたくないファイルがあったときの対処法
DockerfileでCOPYを使ってファイルをコピーしたいときにコピーしたくないファイルだけ除外するには`.dockerignore`ファイルを作成してその中にコピーしたくないファイル名を書く.

例　hello.txtをコピーしたくないとする

まず`.dockerignore`ファイルを作成する
```
touch .dockerignore
```
そして.dockerignoreの中にコピーしたくないファイルの名前を書く
```.dockerignore
hello.txt
```
そして、ターミナルで以下のコマンドでイメージを実行する
``` 
docker image build .
docker container run -it <イメージ名>
```
これにより、COPYしたくないファイルを除外することができる

# マルチステージビルドの使い方
`開発環境`と`本番環境`で環境を変えたい
しかし、Dockerfileを`開発環境`と`本番環境`で2つ用意するのは管理がめんどくさい
そんなときに`マルチステージビルド`なら1つのDockerfileで開発環境と本番環境を書くことができる。
```dockerfile:Dockerfile
FROM ubuntu:20.04 AS base #共通部分
RUN apt update  #共通部分
CMD ["sh", "-c", "echo Hello $my_name"]  #共通部分

FROM base AS dev #開発環境部分
ENV my_name=TEST

FROM base AS prod #本番環境部分
ENV my_name=Bob
```
イメージを作成するときにどの環境を使うのかを指定する
```
docker image build --target <環境名> .
```
例　本番環境を作りたいときは以下のコマンドを打つ
```
docker image build --target prod .
```

# まとめ
これによりdockerでコンテナを作成することができる