改めてDockerを理解する②[コンテナの中に入ってみよう編]

## はじめに
こんにちは！ITスクールRareTECHでCS（Customer Support）を担当している池村です！
今回の記事はDockerの基本②の解説記事になります。シリーズものですので、まず先に①を見ていただけますと幸いです。

https://qiita.com/ikemura-ren/items/dae9f599254b90167b06

※Dockerを初めて触る人向けの記事になります。

## 前回の復習
前回の記事ではイメージを取得し、コンテナを作成・起動・終了・削除までを一通り行いました。使ったコマンドをおさらいしておきます。

```Bash:おさらい
# 旧記法
docker search   # イメージを検索する
docker pull     # イメージを取得する
docker run      # コンテナを作成して起動する
docker start    # 停止しているコンテナを起動する
docker stop     # 起動しているコンテナを停止する
docker rm       # コンテナを削除する

# 新記法
docker image search       # イメージを検索する
docker image pull         # イメージを取得する
docker container run      # コンテナを作成して起動する
docker container start    # 停止しているコンテナを起動する
docker container stop     # 起動しているコンテナを停止する
docker container rm       # コンテナを削除する
```

上記コマンドを理解している方々は、次のステップに進んでいきましょう。

:::note warn
Dockerのコマンドには、実は旧記法と新記法があります。
前回の記事同様、この記事内ではどちらのコマンドも残しておきます。
:::


## `exec`コマンド（コンテナの中に入る）
起動したコンテナの中にアクセスする方法を見ていきましょう。これは`exec`コマンドを使います。今回はまたUbuntuのコンテナを起動して、中に入ってみます。

:::note info
`exec`コマンドはかなり難しく混乱の原因ですので、今回はこのコマンドを中心に解説していきます。
:::

前回の記事でもコンテナの中に入ったと思いますが、コンテナの起動と同時に入るのとはまた方法が違います。

まずはコンテナを`run`コマンドで起動しましょう。今回は起動と一緒にコンテナに入るのではなく、バックグラウンドで起動してみます。（裏で動いておけと命令する）
```Bash:Ubuntuのコンテナを起動
# 旧記法
docker run -d ubuntu sleep infinity

# 新記法
docker container run -d ubuntu sleep infinity
```
裏で動いておけと命じるときのオプションは`-d`を使います。ただ、UbuntuなどのLinuxディストリビューションのコンテナは起動してもすぐ終了してしまうので、今回は`sleep infinity`のコマンドを起動時に実行することで、そのまま起動を維持させます。
以下の画像のようにCONTAINER IDが表示されて、ubuntuが裏で動き続けていますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3798971/f7129e5b-e60b-1c73-ea63-f61306a640cc.png)

では、この状態でコンテナの中にアクセスしてみましょう。

コンテナの中に入る時は`exec`コマンドを使います。コンテナの中の下地はLinuxです。大体はBashが入っています。なので、今回も起動時にbashを指定してコンテナに入ります。

```Bash:コンテナの中に入るには
# 旧記法
docker exec -it コンテナID or コンテナ名 /bin/bash

# 新記法
docker container exec -it コンテナID or コンテナ名 /bin/bash
```

これもどちらかというとコンテナIDの方が楽ですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3798971/e8d1e86e-eea1-2119-4521-3f22062719c6.png)

ここまでコンテナに入る入ると言ってきましたが、実際の`exec`コマンドの実態は以下です。

:::note info
`exec`はコンテナの中で特定のコマンドを実行するためのオプション！
:::


#### おそらく初学者が浮かべる疑問点
Q. bashを指定しないと入れないの？

A. はい。入れないです。（何かしらのシェルを指定しないとダメ）たとえば以下のような形で実行すると、コンテナの中でコマンドを打つことができません。と言うかエラーになります。
```Bash:間違ったexecコマンドの実行
docker exec -it コンテナID or コンテナ名
```
上記では`exec`を使ってコンテナ内で行うコマンドが指定されていません。
**`bin/bash`はLinuxで作成されたシェルプログラム、立派なコマンドです。**

:::note warn
`exec`はコンテナの中で指定したコマンドを実行するのが役割ですので、`/bin/bash`を指定する必要があります！
:::

Q. `-it`は結局何をやっているの？

A. `-i`を指定すると、我々のPCのキーボードからの入力を受け付けることができるようになります。一応これだけも`/bin/bash`を指定して入力を受け付けることができるようになりますが、`-t`による仮想端末がないとコマンドの出力結果などを綺麗に整形できません。

:::note warn
`-i`は入力受付を担当。
`-t`は画面を担当。出力の整形もする。
Bashは入力されたコマンドを解釈して、実行を担当する。
:::

ちなみに、今回Ubuntuを使っているから`/bin/bash`を指定しないとダメと言っているわけではありません。基本的にコンテナの下地はLinuxです。どのコンテナ内に入る時もシェルを指定する必要があります。（Alpineが下地とかのコンテナは`sh`を指定する必要がある。もしくは起動時にインストールするか）

これもせっかくなのでしっかり見ていきましょう。

### Alpine Linux（アルパイン）
AlpineはLinuxのディストリビューションの一つです。（Linuxの種類の一つ）
これはLinuxディストリビューションの中でもかなり軽量なものです。Ubuntuのイメージの容量が100MBくらいなんですが、このAlpineは8~9MBでした。かなりの差ですね。もちろん、このイメージで作るコンテナも軽量になります。

:::note info
軽量ということは起動もはやい！
:::

今回はこれを起動してコンテナの中に入ってみましょう。
```Bash:Alpine実行
# 旧記法
docker run -it alpine

# 新記法
docker container run -it alpine
```

上記のコマンドを叩くと、コンテナの中でシェルを使うことができます。ただ、BashではなくBourne Shell（sh）が起動します。
以下の画像を見てみてください。シェルの表示の見た目が違いますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3798971/0eaaf3e1-4147-69a9-0da5-261dca7d2533.png)

Alpine Linuxはデフォルトのシェルがより軽量でシンプルなBourne Shell（sh）を使っています。ですので、一度`exit`でコンテナから出ていただき、再度入る時を見てみましょう。

```Bash:コンテナ再起動
# 旧記法
docker start コンテナID or コンテナ名
docker exec -it コンテナID or コンテナ名 /bin/sh

# 新記法
docker container start コンテナID or コンテナ名
docker container exec -it コンテナID or コンテナ名 /bin/sh
```

これで再度入ることができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3798971/6a1f0067-d995-ec35-4a59-5bb0a20c1e15.png)

Bashが使いたいよ〜って方がいるかもなので、それも少し解説いたします。
コンテナが起動されていて、かつその中に入った状態と仮定します。
```Bash:Alpineのコンテナの中
apk update && apk add --no-cache bash
```
私の環境での実行結果です。無事Bashがインストールされたようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3798971/6411f740-6530-b351-1c24-f44efbc9eb2f.png)


Alpineのパッケージ管理システムは`apk`なので、アップデート後にBashをインストールします。
`--no-cache`のオプションを今覚える必要はありません。簡単に言うと、コンテナの容量を軽量にする一つの手段です。

では一度`exit`でコンテナから出てもらい、再度Bashで入り直しましょう。

```Bash:Bashでアクセス
# 旧記法
docker exec -it コンテナID /bin/bash 

# 新記法
docker container exec -it コンテナID /bin/bash 
```

私は無事Bashでのアクセスに成功しました。微妙に見た目が違いますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3798971/fae4f5d0-6653-f102-1a3b-2e8b32c1de4b.png)

## 余談
ちなみに毎回`/bin/bash`とか毎回書くのだるいですよね。
シェルのPATHは通っているので、絶対パスで書く必要は実はなかったりします。
```Bash:絶対パスではないシェルの指定方法
docker exec -it コンテナID bash 
docker container exec -it コンテナID sh 
```




## おわりに
今回はDockerの基本の中でも難しい（であろう）コマンドである`exec`について解説しました。他のコマンドのことも書きたかったですが、まずはここをしっかり押さえてほしかったので、今回はこれで終わりにします。

次回はその他のコマンドをまとめてご紹介します👇

https://qiita.com/ikemura-ren/items/8bad27179b09cd507e2c

まとめ記事に戻るにはこちら👇

https://qiita.com/ikemura-ren/items/b961642d55e4e6515203