Dockerの基本的な使い方




この記事ではDockerの基本的な概念と使い方を初学者向けに解説します。
基本的に情報は全てdocumentに書いてあるのですが、分量が多いのでミニマムで大雑把にDockerの仕組みを知りたい人向けの記事になります。初めての方がこれを読んだ後に必要なところをdocumentからつまみ食いできることを目標にします。

---

## 目次

- Dockerの概要
- Dockerコンテナに関するコマンド
- Dockerイメージに関するコマンド
- Dockerfileの基本的な書き方


## 環境


- MacBook Air (Retina, 13-inch, 2020)
- Docker version 20.10.7
- docker-compose version 1.29.2

---

## Dockerを使うメリット

---

Dockerを使うメリットはたくさんあると思うのですが、自分が思うDockerのメリットは

- 環境構築で手間取らない
- localのPCの環境を汚さない
- 他の人にすぐにコードを共有することができる

といったことではないでしょうか。

---


## Dockerの概略

---

Dockerを理解するポイントはDockerイメージとDockerコンテナの概念だと思います。
まず、**Dockerコンテナとは実際にアプリケーションなどが動作する仮想環境**です。例えば、Ruby on RailsでサーバーをDockerを使って仮想環境上で動かす時にはこのDockerコンテナの中でサーバーを起動することになります。

---
次に**DockerイメージとはDockerコンテナを作るための設定などが書いてあるテンプレート**だと考えてください。Dockerイメージを一つ作るとそこからたくさんのDockerコンテナを作ることができます。

---

 Dockerイメージは基本的に二つの方法で入手することになります。一つ目はDocker HubというDockerイメージのライブラリ的なところから`docker pull`コマンドで取得する方法。二つ目はDockerfileというDockerイメージの設計図を作成して、`docker image build`コマンドで実際に自分が作りたいDockerイメージをつくる方法になります。

---


基本的にDockerを使うときの流れは

1. Dockerfile(Dockerイメージの設計図)から`docker build`でDocker imageを作る or Docker Hubから`docker pull`でDockerイメージを持ってくる
2. Dockerイメージから`docker container run`でDockerコンテナを作る



---
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305234/2beb5c48-1712-935e-e747-a9b58a0643d2.png)

## Dockerイメージを操作するコマンド

次に、Dockerイメージを操作するときの基本的なコマンドについて紹介します。

---

### `docker image build`:イメージのビルド

DockerfileからDockerイメージを作成する時にはこのコマンドを使います。

```
$ docker image build [オプション] パス | URL | -
```


- githubのリポジトリ内のから実行するときはURLを指定する
- Dockerfileからイメージを作る時にはDockerfileが書いてあるパスを指定する
- imageは省略可能
- -fオプションでDockerfileの名前を指定する
    - デフォルトだとパス/Dockerfile

---

### `docker search`:イメージの検索

- Docker Hub内のDockerイメージを探す時にはこのコマンドを使います。

```
$ docker search 単語
```
- Docker Hub内の単語が入っているDockerイメージの検索

---

### `docker pull`:イメージの取得

Docker HubからDockerイメージを取得する時にはこのコマンドを使います。

```
$ docker pull [オプション] 名前[:タグ]|[レジストリ・ホスト[:レジストリ・ポート]/]名前[:タグ]
```
レジストリからイメージやリポジトリを取得

---

###`docker image ls/docker images`:イメージの一覧

Dockerイメージの一覧を取得するコマンドです。shellコマンドのlsのDockerバージョンになります。

```
$ docker images [オプション] [リポジトリ[:タグ]]
```
- -a, --all-false 全てのイメージを表示
- --help 使い方の表示
- -f, --filter
    - dangling=(true|false)  trueでタグ付けされていないイメージの一覧
    - label=<キー> or label=<キー>=<値>　label付けされたイメージの一覧
    - before=(<イメージ名>[:タグ]|<image-id>|<image@digest>) 指定したIDまたはまたはリファレンスより前に作成したイメージの一覧
    - since=(<イメージ名>[:タグ]|<image-id>|<image@digest>) 指定したIDまたはまたはリファレンスより後に作成したイメージの一覧



## Docker containerを操作するコマンド

基本的なDocker containerの操作に関するコマンドを紹介します。まず初めにDockerコンテナの基本的なライフサイクルとstatusについて説明します。

Dockerコンテナにはstatusと呼ばれる状態が存在します。`running`の時には起動中、`exited`の場合には停止中になっています。この他にも`created`など他の状態もありますがここでは初めの二つのみを扱います。statusについては`docker container ls`(または`docker ps`)を用いて確認することができます。


次にDockerコンテナがどのようなライフサイクルになっているかを見てみます。

まず初めに`docker run`コマンドによってDockerイメージからDockerコンテナが作られます。このとき、できたコンテナは自動的に起動中(`running`)になります。
起動中(`running`)であるコンテナに`docker stop`コマンドを使うとstatusは停止中(`exited`)になります。
ただし、バックグラウンド実行などのオプションがついてないときは起動中(`running`)になってすぐに停止(`exited`)することがあります。停止中(`exited`)中のコンテナに`docker restart`を使うと起動中(`running`)にすることができます。

最後に停止中のDockerコンテナに対して`docker rm`コマンドを使うとDockerコンテナを削除することができます。




![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305234/7fcc98be-93b8-6541-1185-8be5b9302124.png)


###`docker container run`:DockerイメージからDockerコンテナを作成と実行

DockerイメージからDockerコンテナを作成するコマンドになります。また、Dockerコンテナの実行も行います。

```
$ docker run [オプション] イメージ[:タグ|@ダイジェスト値] [コマンド] [引数...]
```

- containerは省略可能
- -pでポート番号を指定する(e.g. -p 9000:8080でDockerコンテナ内で9000番のポート番号とコンテナ外の環境でのポート番号8080を同期している。
- -dでデタッチドモード(バックグラウンド)で実行。デフォルトだとフォアグラウンドで実行
- --rmで終了したコンテナの削除を自動で行う


###`docker container ls`:Dockerコンテナの一覧の取得

Dockerコンテナの一覧を取得するコマンドです。

```
$ docker container ls [オプション]
```

- -aで停止しているコンテナも表示する


表示されるコンテナの絞り込みや情報については多くのオプションがあるのでドキュメントで確認してください。

###`docker container stop`:コンテナの停止

Dockerコンテナの停止を行うコマンドです。コンテナの削除を行うときは一度停止する必要があるので注意は必要です。

```
$ docker stop [オプション] コンテナ [コンテナ...]
```

###`docker container restart`:コンテナの再起動

Dockerコンテナの再起動を行うコマンドです。一度停止したコンテナの再起動を行います。

```
$ docker restart [オプション] コンテナ [コンテナ...]
```


###`docker container rm`:コンテナの破棄

停止中のDockerコンテナの削除を行います。停止中でないとできないことに注意が必要です。

```
$ docker rm [オプション] コンテナ [コンテナ...]
```

###`docker container exec`:実行中のコンテナでのコマンド実行

実行中のコンテナ内で、新しいコマンドを実行します。

```
docker exec [オプション] コンテナ コマンド [引数...]
```

- -d コマンドをデタッチドモード(バックグラウンド)で実行
- -itでコンソールに結果を出力する。基本的につけておいたほうがいい。

以下のコマンドで実際に起動中のコンテナに直接入る(入ったかのような作業を行う)ことができます。

```
$ docker exec -d -it コンテナ bash
```

## Dockerfileの書き方

Dockerイメージを作成するための設計図となるDockerfileの書き方を簡単に紹介します。


### `FROM`

基本的に一番初めに書くべきコードでベースとなるDockerイメージを選択します。ここで選んだimage上でこれ以降の操作は動いて行きます。

以下のコマンドでbaseイメージをDocker Hubから取得します。

```
FROM baseイメージ
```

具体例としては

```
FROM ubuntu:18.04
```
でubuntuの18.04versionが取得します。


### `RUN`

ここにはイメージ上で環境構築のために実行したいコマンドを書いていきます。例えば、ライブラリのインストールやgithubからのファイルの取得などができます。

baseの環境内で自動的に実行するコマンドを書いていきます。ライブラリのインストールなどの環境構築に関連するコマンドをここで書いていきます。

```
RUN コマンド
```

例えば、pipを使ってqutipというライブラリをDocker環境内にインストールする時には

```
RUN pip install qutip
```

とします。

### `COPY`

ここにはDockerコンテナの外部のファイルをDockerコンテナ内にコピーすることができます。これによってDocker外部で作ったファイルを仮想環境の内部に持っていくことができます。

以下のように書くことで今いるディレクトリにあるsample.pyをDocker内のPATHにコピーします。

```
COPY sample.py PATH
```

### `CMD`

Docker環境を作成したのちに、Dockerコンテナ内でプログラムを実行するときに使います。具体的にはDockerコンテナ内のsample.pyというpythonコードを実行する時には次のように書くことができます。

```
CMD ["python", "sample.py"]
```
コマンドの一つ一つを""で囲って、カンマで区切って[ ]内に書くだけで大丈夫です。

ここであげた以外にもコマンドはあるので調べてみてください。



## 基本的なDockerの使用例

ここではDockerfileを使ってイメージを作る方法で簡単にPythonが使えるLinux環境を作ってみたいと思います。基本的に今やったことの復習になると思います。
具体的にはpythonが使用できる環境をコンテナ内に作成してpythonのスクリプトを実行します。

### Dockerコンテナを作成したときに実行されるpythonコードを作成

Dockerfileがあるディレクトリに以下のsample.pyという名前で以下のファイルを作成します。

```python
print("Hello World")
```

### Dockerfileを作成

ここではDockerfileを作成します。基本的にやることは今まで書いてきたことになります。
具体的には以下のように作成します。
- FROMからbaseimageを作成
- apt-getのアップデート/python,curlコマンドをapt-getコマンドでインストール
- python3コマンドのリンクを作る
- pipのインストール
- workdirをrootにする
- pipでライブラリをインストール
- sample.pyを仮想環境のrootにコピーする
- sample.pyを実行する
 




```Dockerfile
# baseimageの作成
FROM ubuntu:18.04

# apt-getのアップデートとpython,curlコマンドをapt-getコマンドでインストール
RUN apt-get update && apt-get install -y \
    build-essential \
    python3.7 \
    python3.7-dev \
    python3-distutils \
    curl

# python3コマンド作成する
RUN ln -sf /usr/bin/python3.7 /usr/bin/python3

# pipのインストール
RUN curl https://bootstrap.pypa.io/get-pip.py -o /tmp/get-pip.py && \
    python3 /tmp/get-pip.py && \
    rm /tmp/get-pip.py

# workdirをrootにする
WORKDIR /root

# pipでライブラリをインストール
RUN pip3 install numpy \
    pandas \
    matplotlib \
    seaborn

# sample.pyをrootにコピーする
COPY ./sample.py sample.py

# sample.pyを実行する
CMD ["python3", "sample.py"]
```

### イメージのbuildとコンテナの作成

まずは、イメージの作成をします。

```terminal
$ docker build .
```

次にImage IDを以下のコマンドで取得します。

```terminal
docker images
```

最後に取得したImage IDを用いて以下のようにコンテナの作成をします。

```terminal
docker container run <Image ID>
```

こうすると、仮想環境内で`sample.py`が実行されて

```terminal
Hello world
```

が出力されます。


### 参考文献

Docker公式document
- https://docs.docker.jp/index.html

### 最後に

Dockerを使いこなすにはDocker自体の知識だけではなくLinuxやshell、ネットワークなどの環境構築に関する様々な知識が必要になってくると思います。
みなさんの知識の復習や学習も兼ねて触っていくと楽しめると思います。
余裕がありましたら続編を書いてみたいと思っています。

間違っているところや、質問などがありましたらコメントよろしくお願いします。