【Docker入門】知識0からDockerでフォルダをマウントしてbashを起動するまで

# はじめに
[Dockerの公式チュートリアル](https://docs.docker.com/get-started/)は一度に色々なことをやってしまい、初歩的なことがよく分からないので、なるべく少ない知識でDockerの概要を掴み、簡単なことだけをするための手順をまとめました。この記事を読んでからであれば、Dockerでやりたいことを実現するためには何について調べればいいのかが分かるのではないかと思います。

環境は

* macOS High Sierra
* Docker ver 18

で行いましたが、基本的に他の環境でも変わらないはずです。

# Dockerの基礎知識
Dockerでは"コンテナ"とよばれる、ホストOSから独立した環境でのアプリケーションの実行単位を管理します。コンテナは"イメージ"から作られます。イメージとコンテナの関係は、プログラミング言語でいうところの、クラスとインスタンスのような関係です。イメージはどんな環境(ライブラリなどの指定)でアプリケーションを実行するかという情報になっていて、イメージと、そこで実行するアプリケーション、その他のオプションを指定することで個別の実行単位であるコンテナを作ることができます。また、クラスの設計が書かれたソースコードに対応するのが、イメージの設計を書いたDockerfileです。

以上のことから、Dockerについての作業の具体的な手順は次の流れで行います。カッコ内の英単語は、後で解説しますが、対応するDockerのコマンドを表しています。

1. ほしい実行環境(イメージ)の作成手順を書いたDockerfileを記述する
2. Dockerfileからイメージを作る(build)
3. イメージと実行するアプリケーション、その他オプションを指定してコンテナをつくる(create)
4. コンテナを実行する(start)
5. (アプリケーションが自動で終了しないものの場合)コンテナを終了する(stop)

ただし、すでにイメージがウェブ上ある場合は、1、2をする必要はありません。また、3での様々な指定を設定ファイルとして記述しておくための手段としてdocker-composeというコマンドが提供されています。これから、なるべく簡単な作業から始めて、最終的にホストOSとフォルダを共有してbashを起動するコンテナを実行するところまでいきます。

# イメージからコンテナをつくり、コンテナを実行する
自分でDockerfileを記述する前に、ウェブ上で公開されているイメージと実行するアプリケーションを指定して、コンテナを作成し、そのコンテナを実行してみます。

まずは、ウェブ上からDebianイメージをとってきます。

```
$ docker pull debian
Using default tag: latest
latest: Pulling from library/debian
bc9ab73e5b14: Pull complete
Digest: sha256:802706fa62e75c96fff96ada0e8ca11f570895ae2e9ba4a9d409981750ca544c
Status: Downloaded newer image for debian:latest
```

つぎに`create`[コマンド](https://docs.docker.com/engine/reference/commandline/create/)で、イメージと実行するアプリケーションを指定して、コンテナを作ります。今回はアプリケーションとしては`echo`で標準出力に文字を表示するだけとします。

```
$ docker create debian echo "Sauna Ikitai"
```

作られたコンテナは`ps`[コマンド](https://docs.docker.com/engine/reference/commandline/ps/)で一覧できます。

```
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS                     PORTS               NAMES
893a4674e4fe        debian              "echo 'Sauna Ikitai'"   9 minutes ago       Exited (0) 8 minutes ago                       quizzical_franklin
```

コンテナIDを指定して`start`[コマンド](https://docs.docker.com/engine/reference/commandline/start/)で実行してみます。

```
$ docker start -i 893a4674e4fe
Sauna Ikitai
```

これでコンテナの実行までできました。ただ、コンテナの作成と実行を毎回別々にやるのは面倒です。そんなときは`run`コマンドを使えば、`create`と`start`を両方やってくれます。

```
$ docker run -i debian echo "Sauna Ikitai"
Sauna Ikitai
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                 CREATED             STATUS                     PORTS               NAMES
b5b5829e62d9        debian              "echo 'Sauna Ikitai'"   6 seconds ago       Exited (0) 5 seconds ago                       determined_mcclintock
893a4674e4fe        debian              "echo 'Sauna Ikitai'"   9 minutes ago       Exited (0) 8 minutes ago                       quizzical_franklin
```

# フォルダをマウントしてbashを起動する
Dockerを開発環境として使うには、ホストOSにあるフォルダをコンテナにマウントする必要があると思います。フォルダのマウントは`-v`オプションを使います。フォルダのパスは絶対パスでないといけないことに注意します。またbashでコンテナにログインするには`-i`と`-t`をつけます。ついでに、`--name`でコンテナの名前を指定します。

```
$ docker create -it -v /Users/owner/for_docker:/for_docker --name tyler_durden debian
83fc7b68a7d5257b9cac43569526e05fabeea4357b5feff07cc2d0a0cc39a9dd
$ docker start -i tyler_durden
root@d56c0a008ea4:/# ls
bin  boot  dev	etc  for_docker  home  lib  lib64  media  mnt  opt  proc  root	run  sbin  srv	sys  tmp  usr  var
```

たしかにマウントされています。

# docker-composeを使う
毎回色々なオプションを打つのは面倒です。そこで様々なオプションをまとめて設定ファイルとして記述して管理できるのが`docker-compose`です。先ほどのオプションを設定ファイルとして書くには次のようにします。

```docker-compose.yml
version: '3'
services:
  tyler_durden:
    image: 'debian'
    # -v option
    volumes:
      - .:/for_docker
    # -i option
    stdin_open: true
    # -t option
    tty: true
```

適当なフォルダに`docker-compose.yml`をおいて次のようにコマンドを実行すれば`docker run`で色々なオプションを指定したときと同じ結果が得られます。

```
$ ls
docker-compose.yml
$ docker-compose run tyler_durden
root@052e1ed5a153:/# ls
bin  boot  dev	etc  for_docker  home  lib  lib64  media  mnt  opt  proc  root	run  sbin  srv	sys  tmp  usr  var
```

# おわりに
Dockerfileの書き方までいこうと思ったのですが、面倒になったので気が向いたら追記します。