初学者向けdocker基礎

<h2>初めに</h2>
かなり簡略化した内容になっています。詳しく知りたい人は一番下の参考文献を見てください。そっちの方が100倍ためになります。この記事は、簡単な入りになればいいなと思ってます。

<h2>目次</h2>

1. dockerの基礎概念
2. dockerの基本コマンド
3. Dockerfileの書き方
4. yamlファイルについて
5. docker composeについて

<h2>1. dockerの基礎概念</h2>
なんとびっくり、3つだけ

- イメージ
- コンテナ
- Dockerfile

<h2>イメージとは</h2>

**複数または、一つのレイヤからなるもの**

イメージには、レイヤによって次の情報が入っています。

- ベースイメージはなにか
- 何がインストールしてあるか
- 環境変数はどうなっているのか
- どういうファイルを配置しているか

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625910/5483d763-0f05-6af2-1a6d-af0c1bb48113.png)

ベースイメージとは、最小限のオペレーティングシステムやランタイムが含まれています。(DockerfileでFROMから始まる部分に該当します。)
イメージはDocker Hubで公開されいます。
[使い方参考サイト](https://www.kagoya.jp/howto/cloud/container/dockerhub/)
(Docker Hubに公開されているのはDockerfileではありません)
簡単に言ったらGitHubみたいなものです。
Dockerイメージは、以下で検索可能です。
```docker search [option] 検索対象```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625910/2965b2c6-323b-b480-8e40-b2d4358ab3b0.png)
・stars
星のいいね数

・offical
公式イメージか否かを教えてくれる

<h2>コンテナとは</h2>

簡単に言うと、pcです。
厳密に言うと、**ホストマシン上の隔離された領域**のことです。

コンテナの特徴

- **コンテナはイメージを元に作られます。**
- dockerのCLIやAPIを使って、コンテナの生成、起動、停止が行えます。
- 複数のコンテナは独立していてお互いに影響を及ぼさなず、個別に動かすことができます。
- Docker Engine上なら、ローカル、仮想マシン、クラウド環境でも動きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625910/6d2966dc-bbe4-d8fe-1caf-40bdbe0e85c5.png)

<h2>Dockerfileについて</h2>

簡単に言うと、環境設定ファイルです。
厳密に言うと、**既存のイメージにレイヤを積み重ねるためのファイル**です。

DockerHubに上がっているイメージだけで問題があり、自分に都合の良いイメージを作るためにDockerfileを作成します

<h2>2. dockerの基本コマンド</h2>
これも、3つだけ

1. イメージを作る(docker image build)
2. コンテナ起動(docker container run)
3. コンテナ内で何か操作をする(docker exec)

<h2>イメージを作る</h2>

```docker image build``` は**Dockerfileからイメージを作成するコマンド**です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625910/bca738b5-a173-eb21-ebff-d9cf1baca5bf.png)

DockerHubに上がっているイメージをそのままbuildしてもいいですし、Dockerfileから独自のイメージをbuildしてもいい

<h2>コンテナ起動</h2>

```docker container run```は、**イメージからコンテナを起動する**コマンド

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625910/fb4d93c5-d821-7bbb-8c9f-5f1096909d2a.png)

ここで大切なことは、このコマンドは**イメージからコンテナを1つだけ作る**ということです。
このコマンドは、大量にオプションがあるので[公式リファレンス](https://docs.docker.jp/engine/reference/commandline/container.html)でオプションを調べてその都度使い方を調べて覚えていくと良いと思います。



補足説明
```docker container run```は、複数のコマンドを同時に実行しています。
```
- image pull(git pullとやってることは同じでDockerHubからimageをpullしています)
- container create
- container start
```
<h2>コンテナ内で何か操作をする</h2>

```container exec```は**起動したコンテナにだけ命令を送る**コマンドです。
**起動したコンテナにだけ送る**コマンドなので```docker container run```**した後でないと使えません**。

このコマンドも、[公式リファレンス](https://docs.docker.jp/engine/reference/commandline/exec.html)でオプションを調べてその都度使い方を調べて覚えていくと良いと思います。



補足説明
コマンドを学習するときは、形に注目しましょう
```
docker image build(イメージをビルドする)
docker container run(コンテナを起動する)
docker container exec(コンテナ内で操作をする)
```
これらすべてに共通することは、**AをBする**ということです

<h2>3. Dockerfileの書き方</h2>

```
FROM ruby:3.1.2
# ライブラリのインストール
RUN apt-get update -qq 
#git activestarage sqlite3
RUN apt-get install -y git imagemagick libmagick++-dev sqlite3

#nodejs 16のインストール
#nodejs ver.16だとwebpackerと相性相が悪い
RUN curl -sL https://deb.nodesource.com/setup_16.x | bash -
RUN apt install -y nodejs

#yarnのインストール
RUN npm install n -g 
RUN npm install -g yarn 
RUN gem install rails -v 6.1.4

#workingディデクトリの作成
RUN mkdir /app
WORKDIR /app

COPY Gemfile Gemfile.lock /app

#Gemfileのコピーとインストール
RUN bundle install

ENTRYPOINT ["/app/entrypoint.sh"]

CMD ["rails", "server", "-b", "0.0.0.0"]
```

FROM : ベースイメージを指定する
RUN : 任意のコマンドを実行する
COPY : ホストマシンのファイルをイメージに追加する
CMD : デフォルト命令を指定する(.yamlファイルに記述できるから不要)

ここの説明をすると時間が足りないので以下参照お願いします。
[公式リファレンス](https://docs.docker.jp/engine/reference/builder.html#from)

<h2>4. yamlファイルについて</h2>

<table>
    <thead>
        <tr>
            <th>\</th>
            <th>やりたいこと</th>
            <th>docker コマンド</th>
            <th>yamlファイル</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>app</td>
            <td>コンテナの定義</td>
            <td>-</td>
            <td>app:</td>
        </tr>
        <tr>
            <td>app</td>
            <td>コンテナ名の指定</td>
            <td>container run --name</td>
            <td>container_name:</td>
        </tr>
        <tr>
            <td>app</td>
            <td>イメージのビルド</td>
            <td>image build</td>
            <td>build:</td>
        </tr>
        <tr>
            <td>app</td>
            <td>バインドマウント</td>
            <td>container run --mount</td>
            <td>volumes:</td>
        </tr>
        <tr>
            <td>app</td>
            <td>デフォルト命令の指定</td>
            <td>container run <command></td>
            <td>command:</td>
        </tr>
    </tbody>
</table>

これが何を意味しているのか？(用語は[公式リファレンス](https://docs.docker.jp/storage/volumes.html#v-mount)で調べてください)
docker コマンドの後ろのoptionやパラメータをyamlファイルで指定することができます。

具体例
```.yaml
 app:
　container_name: docker-rails-app
  build: .
   dockerfile: docker/app/Dockerfile
  volumes:
   - .:/app
  command:bash -c "bundle exec rails s -p 3000 -b '0.0.0.0'"
  ports:
   - "3000:3000"
```

container run **--name**
太文字の部分を、**.yamlファイルで指定したdocker-rails-nameで置き換えてくれます**。

container run **[command]**
太文字の部分を、**.yamlファイルで指定したbash -c "bundle exec rails s -p 3000 -b '0.0.0.0'"で置き換えてくれます**。

補足:
上記のDockerfileと.yamlに関連は無いです。あくまでも、例の一つとして提示してます。

<h2>5. docker composeについて</h2>

- Dockerfile
- docker image build
- docker container run

docker composeは上記のdocker image buildとdocker container runを置き換えてくれています。
つまり、.yamlファイルとDockerfileが正しく設定できていれば毎回コンテナ毎にdocker image buildやdocker container runを行わずにdocker composeを行ってくれれば両方勝手に.yamlに記述した内容でやってくれます。

したがって、実際にdockerを扱う場合にはコンテナ起動をするのに
```shell
docker compose up
```
たったの**これだけ**です

起動したコンテナを停止するには、
```shell
docker compose down
```

**これだけ**です。
dockerの説明はこれで以上です！！

追記
docker compose up / downの説明がわからない人は、
upはpcの電源を付ける
downはpcの電源を消す
こんな感じで覚えて貰って大丈夫です!（ほんとは良くない……）

ここまでを目茶目茶簡単にまとめると
1. Dockerfile（環境設定ファイル）を作成する。
2. .yaml(複数コマンドを同時実行するファイル)を作成する
3. docker compose up(pcの電源を付ける)を行います
4. docker compose down(pcの電源を消す)を行います

<h2>終わりに</h2>
今回は、かなり省略して書きました。もっと詳しく知りたい人は以下の参考文献をみてください
機会があれば、これの続きでDockerfileの書き方の詳しい点にフォーカスして記事を書こうと思います

参考文献
[docker公式リファレン](https://docs.docker.jp/)
[僕が勉強した教材](https://zenn.dev/suzuki_hoge/books/2022-03-docker-practice-8ae36c33424b59/viewer/3-8-docker-compose)←この記事と被ってる内容かなり多いです。僕の勉強元なので…