Dockerで環境構築するための最低限の概念理解

# はじめに

この記事は、Docker入門シリーズ記事3本の1本目です。
[Dockerで環境構築するための最低限の概念理解](https://qiita.com/minato-naka/items/e9cd026747693759800c)
[Dockerで環境構築するための最低限のコマンドを一通り実践する](https://qiita.com/minato-naka/items/e1f91e1df2c4fe7411dc)
[【Docker Compose】設定内容を1行ずつ理解しながらLaravel環境構築（PHP-FPM、Nginx、MySQL、Redis）](https://qiita.com/minato-naka/items/8b31d28823cabaa9487a)

また、WindowsでDockerを利用する際の重要な設定に関する記事もありますのでこちらもご確認ください。
[WindowsでDockerを使う時、正しくファイル配置しないと激重になるので注意](https://qiita.com/minato-naka/items/84508472c04f628e576e)

# 概要
この記事では、
Docker未経験者、初心者向けに
Dockerでアプリケーションの開発環境を構築するために必要な
最低限の概念を解説します。

詳細な解説はかなり省いています。


# Dockerとは何をするためのものか
Dockerは、アプリケーションの実行環境を構築するためのツールです。

例えば、PHPでウェブアプリケーションを作りたいと思った時、
アプリケーションを実際に動作させるためには
1. Linuxのサーバを用意する
2. そのサーバにApacheをインストールする
3. そのサーバにPHPをインストールする
4. そのサーバに自分で書いたプログラムソースコードを乗せる
というような作業が必要になります。

この1～3までのインフラ環境構築を
簡単にしてくれるツールがDockerです。

# Dockerを利用するメリット
開発環境を構築する方法として、
・各自PCでXAMPPを利用する
・各自PCでVMwareを利用して仮想サーバを作成する
・AWSでクラウド上に仮想サーバを作成して共有する
などいろいろ考えられます。

これらの方法と比べてDockerを利用することで得られるメリットは、
ざっくりと下記のような点です。
1. 環境構築が簡単
2. 環境の共有が簡単
3. 環境が軽い

>1. 環境構築が簡単
>2. 環境の共有が簡単

これに関しては、
この後の実践記事で実際にDocker環境構築を経験すれば感じられると思います。

>3.環境が軽い


これに関しては、
このような記事でよく解説されています。
https://qiita.com/kotaro-dr/items/b1024c7d200a75b992fc#%E4%BB%AE%E6%83%B3%E5%8C%96

ゲストOSを起動する必要がなくなる分、
従来のホスト型仮想化と比べてかなり軽量になります。

# メインコンポーネント紹介
Dockerで環境構築を進めるうえで、
最低限理解する必要のあるメインコンポーネント
・コンテナ
・イメージ
・Docker Hub
・Dockerfile
について簡単に解説します。

この4つさえ押さえておけば、
とりあえず簡単な環境構築は進められると思います。

この4つのコンポーネント全体の関係図はこのようになっています。
![docker.png](https://qiita-image-store.s3.amazonaws.com/0/297693/e8730f45-a41c-115f-78e3-79f6f8a38af9.png)

この先の１つ１つの解説では、
この全体図をイメージしながら読んでもらえれば理解がしやすいと思います。

## コンテナ
コンテナとは、
アプリケーションを実行できる環境のことで、
あまり難しく考えず
コンテナ≒サーバ
というイメージでもいいと思います。


Apacheの環境が欲しければ
Apacheコンテナを作成し、
MySQLの環境が欲しければ
MySQLのコンテナを作成することになります。

## イメージ
イメージは、コンテナの元になる設定ファイルです。
イメージにはOSやミドルウェアなどの情報が入っていて、
そのイメージからコンテナを作成することで
実際にアプリケーションを実行できる環境が作成されます。

AWSを利用したことのある人は、
EC2サーバを作る元になるAMIのようなものだとイメージしてもらえればいいです。

## Docker Hub
Docker Hubは、Dockerのイメージを共有することのできるサービスです。

プログラムソースを共有するためのサービスとしてGit Hubがありますが、
そのDocker版だと思ってください。

様々なイメージが共有されているので、
実際にいろいろ探してみると面白いです。
https://hub.docker.com/

Apacheのコンテナを作りたい場合は、
ここからApacheのイメージを探して取得し、
そのイメージからコンテナを作成します。

公式で用意されているイメージもあれば、
一般ユーザが作成して共有されているイメージもあります。

自分でイメージを作成してDocker Hubで公開することも可能です。

## Dockerfile
Dockerfileは、Dockerイメージを作成するための設定を記述したテキストファイルです。

先ほどは、
・コンテナはイメージを元に作成する
・イメージはDocker Hubから取得する
と書きましたが、
イメージはDocker Hubから取得するだけでなく、
自分で作成することも可能です。

コンテナはイメージを元に作るのに、さらにその元になる設定ファイルを作るの？？
と思ってしまいますが、
Javaのソースファイルとビルド後の実行可能ファイルの関係と同じです。

我々はDockerfileにコンテナの環境設定を記述し、
それをビルドするとイメージが作成されます。

### Dockerfileの中身
Dockerfileは、
まず初めにベースとなるイメージを指定し、
そこに追加で必要な設定を記述していきます。

実際にDockerfileの中を少し見てみます。
これを見ればDockerの重要な概念である、
`イメージのレイヤー構造`が少しわかると思います。

#### WordPressのDockerfile
例として、まずは[WordPressのDockerfile](https://github.com/docker-library/wordpress/blob/4e108fd7f80ca167ea0f38531e2ae26b3f19783e/php7.1/apache/Dockerfile)を見てみます。

一番上のFROMに`php:7.1-apache`と書いてあります。
その下に色々と書いてあるのはWordPressのインストールとか必要な設定をしているコマンドです。

つまり、
`php:7.1-apache`というPHPとApacheが入った状態の既存のイメージがあり、
それを流用してさらにWordPressのインストール・設定もろもろを加えたものが
WordPressのイメージになっているということです。

#### PHPのDockerfile
次にその[php:7.1-apacheのDockerfile](https://github.com/docker-library/php/blob/ea377551f7527c4e5602bea716c4ba0011dbaee9/7.1/stretch/apache/Dockerfile)を見てみます。

一番上のFROMに`debian:stretch-slim`と書いてあります。
その下に色々と書いてあるのはPHPのインストールとか必要な設定をしているコマンドです。

つまり、
`debian:stretch-slim`というDebianのOSが入った既存のイメージがあり、
それを流用してさらにPHPのインストール・設定もろもろを加えたものが
PHPのイメージになっているということです。

#### DebianのDockerfile
最後に、その[DebianのDockerfile](https://github.com/debuerreotype/docker-debian-artifacts/blob/a5e61a4c40a4b366d614715c51f883e0b153afb5/stretch/slim/Dockerfile)を見てみます。

FROMにはscratchと書いてあります。
これは、既存イメージを流用せず、何もない状態からイメージが作られているということです。

この各Dockerfile、イメージの関係性を図にするとこのような感じです。
![docker-ページ2.png](https://qiita-image-store.s3.amazonaws.com/0/297693/0687f7f6-291f-a189-e623-50b1ea5387ab.png)

# Docker環境構築のフロー
先ほどの全体図をもう一度見て、
Dockerによる環境構築のフローを確認します。

![docker.png](https://qiita-image-store.s3.amazonaws.com/0/297693/e8730f45-a41c-115f-78e3-79f6f8a38af9.png)

まず、コンテナの元になるイメージを取得する方法は2つあります。
図の左上にあるDockerfileをbuildする方法と、
図の右上にあるDocker Hubからpullしてくる方法です。

そして、イメージが取得できたらcreateコマンドを実行すると、
そのイメージを元にコンテナが作成されます。

コンテナができたらstartコマンドを実行すると、
コンテナが起動します。

これでアプリケーション実行環境が完成です。

図には載せていませんが、
runコマンドを実行すると
pull + create + start
の動作をします。

つまり、イメージをまだ取得していない状態でも、
runコマンドを実行すると
イメージをpullして、
そのイメージからコンテナをcreateして、
そのコンテナをstartする
まで一気に実行してくれるということです。

Dockerで環境構築作業をする際は、
常にこの全体図を意識しておけば迷わず進めると思います。

# 次回
次回は、先ほどの図にあるbuildやpull、create、startなどを一通り実際に操作し、
簡単なApacheコンテナを作成してみます。
（次に進む前に、LGTMしてもらえるとうれしいです）
[Dockerで環境構築するための最低限のコマンドを一通り実践する](https://qiita.com/minato-naka/items/e1f91e1df2c4fe7411dc)