Docker使えば初心者でもDB作れる😊

データベースの構築なんて聞いただけだと難しそうー :dizzy_face: 大変そう :cold_sweat: って感じですが
Dockerを使えば、ワタシのような初心者でもデータベースが作れます:v_tone2:

![初心者でも平気だよ.png](https://qiita-image-store.s3.amazonaws.com/0/237418/d2bdd937-f478-71ad-7c11-3c8c9ace11cc.png)

#**使用するサービス**
![今回使うサービス.png](https://qiita-image-store.s3.amazonaws.com/0/237418/065f400a-f25a-9aca-f6d0-950ecaafa592.png)
**VirtualBox** 　 … PC に仮想環境を構築
 **Vagrant**　　　… 仮想マシン環境を管理
 **Docker**　　　 … コンテナ型の仮想環境を作成、実行
**PostgreSQL**　 … データベース管理
#**ワタシのイメージ**
初心者の解釈なので違うかもしれませんが、温かい心で読んで頂けたらと思います。

今、作業しているマシンの中に**仮想マシン(VirtualBox)** を作って、
**操作してくれる人(Vagrant)** に、**超便利なツール(Docker)** をインストールしてもらって
そのツールを使って**データベース(PostgreSQL)**を構築する。　　みたいなことをやります。
![ワタシのイメージ.png](https://qiita-image-store.s3.amazonaws.com/0/237418/9c98794e-87e9-76ce-e67d-7e49999c55ec.png)

#**各ツールをインストール**
#####:one:　まずは、仮想環境を構築するために **VirtualBox** を **[インストール](http://www.oracle.com/technetwork/server-storage/virtualbox/downloads/index.html?ssSourceSiteId=otnjp)**


![1.png](https://qiita-image-store.s3.amazonaws.com/0/237418/fed786dd-e68c-0901-248a-d9f7775dc3e1.png)


---

#####:two:　次に仮想環境を管理してくれる **Vagrant** を **[インストール](https://www.vagrantup.com/downloads.html)**
![2.png](https://qiita-image-store.s3.amazonaws.com/0/237418/fb19d02b-3430-1f49-efeb-465b158d77cf.png)


---
#####:three:　**Vagrantfile** を設定し、仮想マシンを立ち上げる
![3.png](https://qiita-image-store.s3.amazonaws.com/0/237418/360b595b-26e9-fa3d-110c-f2ae706dffd5.png)

仮想マシンに入れるOSは[Vagrant Cloud](https://app.vagrantup.com/boxes/search)の一覧に載っています。
こんな感じで色々ありますが、今回はubuntu/xenial64でマシンを立ち上げます。
![Vagrant cloud.png](https://qiita-image-store.s3.amazonaws.com/0/237418/507e2e2a-69c5-8b6f-515b-5d7e80b5be2b.png)




まずは、任意のディレクトリで
![11.png](https://qiita-image-store.s3.amazonaws.com/0/237418/3127a3a2-607d-96b8-a5e6-7da76acfac63.png)


以下のコマンドを実行

```sh
vagrant init
```
そうするとVagrantfileが出来ます。
![12.png](https://qiita-image-store.s3.amazonaws.com/0/237418/6ce23dbc-0e81-3023-f624-198317512747.png)

今回は任意のIPで仮想マシンを作成するように設定してみます。
ついでに仮想マシンとローカル(ホスト)の任意の場所同士がアクセスできるように
設定したいのでVagrantfileを編集します。


```text:Vagrantfile

Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu/xenial64"
  config.vm.network "private_network", ip: "192.168.11.29"
  config.vm.synced_folder ".", "/srv/", type: "nfs"
end
```

Vagrant.configure("2") do |config|　～　end の間に設定を書きます。

> **config.vm.box = "ubuntu/xenial64"**　　　・・・BOXはubuntu/xenial64で起動してね
> **config.vm.network "private_network"**　 ・・・ホストマシンからしかアクセスしないよ
> **ip: "192.168.11.29"**　　　　　　　　　　・・・IPは  192.168.11.29　に設定してね
> **config.vm.synced_folder ".", "/srv/"**
　　・・・ホストマシンのVagrantfileがある場所(.)を仮想マシンの/srv/の下にマウントしてね
> **type: "nfs"**　・・・ NFS マウントしてね。

synced_folderに指定したホストマシンのディレクトリと仮想マシンのディレクトリを設定
同じディレクトリとして扱えるようにすることをマウントと呼びます。
![マウント.png](https://qiita-image-store.s3.amazonaws.com/0/237418/9347610e-78c7-59d3-f6e3-4aad9692a8b1.png)

仮想マシンが作成されるとき(vagrant upしたとき)に、このマウントをするのですが
そのときのスピードがNFS マウントした方が断然早いらしいです。
それと、Vagrantfileの"　"内は定型じゃないので自分の環境で好きに変えてください。

Vagrantfileの編集が終わったら以下のコマンドを実行します。

```sh
vagrant up
```
これで仮想マシンが作成されて起動しましたー！本当に起動してるか確認してみます。
![13.png](https://qiita-image-store.s3.amazonaws.com/0/237418/41334529-d835-1109-6f84-d26c635561f2.png)

VirtualBoxを起動すると…ちゃんと実行中になってます。
![14.png](https://qiita-image-store.s3.amazonaws.com/0/237418/6e5481a2-0a45-a67c-98c5-a8ef6ca3e98b.png)

このマシンにsshで繋いでみます。以下のコマンドを実行

```sh
vagrant ssh
```
おーっ！繋がりました！本当に仮想マシンにマウントされてるのかな～？
![15.png](https://qiita-image-store.s3.amazonaws.com/0/237418/4de85492-f914-2e57-42f4-62b69a304ff7.png)

では、ホストのtedkumaディレクトリに画像ファイルを入れてみて、仮想マシンで見えるか確認します。
![16.png](https://qiita-image-store.s3.amazonaws.com/0/237418/5019d37b-7d03-98a6-6afb-1909d8632ec1.png)

/srv/の下がVagrantfile置いてる場所と同じになってるはずなので移動してみます。

```sh
cd /srv
```

```sh
ls
```
見えてますー！ちゃんと設定通りマシンが立ち上がってるのが確認できました。
![17.png](https://qiita-image-store.s3.amazonaws.com/0/237418/30d2218f-2fc7-656e-bf78-b08d637747eb.png)

---
#####:four:　**Docker** をインストールする
![4.png](https://qiita-image-store.s3.amazonaws.com/0/237418/dd6761ca-095e-342a-a2cd-df5ccd4c6fbf.png)
上のイラストで色々な環境と言ってますが、dockerではこれをコンテナと呼びます。
pythonの開発環境のコンテナ、ポスグレ環境のコンテナ、nodeの開発環境のコンテナ…
というようにdocker上に色々なコンテナを立ち上げることができます。

**[Dockerを0から勉強する](https://qiita.com/nl0_blu/items/07e5047041ebe009dd06#2docker%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)**からDockerインストールの箇所を引用させて頂きました。

一旦ルートに戻って

```sh
cd /
```
HTTPS経由でリポジトリを使用できるようにパッケージをインストールする

```sh
sudo apt-get install -y
```
Dockerの公式GPGキーを追加

```sh
curl -fsSL https://apt.dockerproject.org/gpg | sudo apt-key add -
```
>OK

key IDが58118E89F3A912897C070ADBF76221572C52609Dであることを確認

```sh
apt-key fingerprint 58118E89F3A912897C070ADBF76221572C52609D
```
>pub　　4096R/2C52609D 2015-07-14
>　　　　Key fingerprint = 5811 8E89 F3A9 1289 7C07  0ADB F762 2157 2C52 609D
>  uid　　　　　　　　　Docker Release Tool (releasedocker) <docker@docker.com>
>

非公式リポジトリ(docker用リポジトリ)の追加

```sh
sudo add-apt-repository "deb https://apt.dockerproject.org/repo/ ubuntu-$(lsb_release -cs) main"
```
Dockerをインストールする
aptパッケージを更新する

```sh
sudo apt-get update
```
Dockerの最新バージョンをインストール

```sh
sudo apt-get -y install docker-engine
```
正しくインストールされているか確認

```sh
docker -v
```
>Docker version 17.05.0-ce, build 89658be　※ちゃんとバージョン出てくればOK

<details><summary>**お試し :relieved:  hello-worldイメージをダウンロードして、コンテナ内で実行。**</summary><div>

```sh
sudo docker run hello-world
```
>Unable to find image 'hello-world:latest' locally
>latest: Pulling from library/hello-world
>9db2ca6ccae0: Pull complete
>Digest: sha256:4b8ff392a12ed9ea17784bd3c9a8b1fa3299cac44aca35a85c90c5e3c7afacdc
>Status: Downloaded newer image for hello-world:latest
>
>Hello from Docker!
>This message shows that your installation appears to be working correctly.
>
>To generate this message, Docker took the following steps:
> 1. The Docker client contacted the Docker daemon.
> 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
>    (amd64)
> 3. The Docker daemon created a new container from that image which runs the
>    executable that produces the output you are currently reading.
> 4. The Docker daemon streamed that output to the Docker client, which sent it
>    to your terminal.
>
>To try something more ambitious, you can run an Ubuntu container with:
> $ docker run -it ubuntu bash
>
>Share images, automate workflows, and more with a free Docker ID:
> https://hub.docker.com/
>
>For more examples and ideas, visit:
> https://docs.docker.com/engine/userguide/
>　
>　※こんなことを言ってます。(Google翻訳さん)
>![18.png](https://qiita-image-store.s3.amazonaws.com/0/237418/78bffb3c-cc1d-d309-c7f7-67ad23299693.png)

</div></details>

[Docker Hub](https://hub.docker.com/)にはオフィシャルなものから個人の方が作成したものまで様々なコンテナのイメージが
公開されています。Gitでいうところのgit clone的な感じでdocker pullして使うことが出来ます。
…で、dockerはそのイメージからコンテナを作成します。

---

#####:five:　**Docker-Compose** をインストールする
![5.png](https://qiita-image-store.s3.amazonaws.com/0/237418/541ab61f-9677-30d2-b64f-d920f60bf84b.png)

**[Install Docker Compose](https://docs.docker.com/compose/install/#install-compose)** のLinuxタブを引用しています。Docker Composeの最新バージョンをダウンロード

```sh
sudo curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
```
実行可能なアクセス許可をバイナリに適用します。

```sh
sudo chmod +x /usr/local/bin/docker-compose
```

ちゃんとインストールされているかバージョンを確認

```sh
docker-compose --version
```
>docker-compose version 1.21.2, build a133471　※ちゃんとバージョン出てくればOK




---
#**ポスグレのコンテナを立ち上げる(DB作る)** 

![6.png](https://qiita-image-store.s3.amazonaws.com/0/237418/8f0ab709-7fe8-6c61-9e49-2269f699095d.png)

さて、大詰めです。ディレクトリの中にdbというディレクトリを作成し、
docker-compose.ymlという名前でヤムルファイルを作成します。
![19.png](https://qiita-image-store.s3.amazonaws.com/0/237418/f78cbd65-71c5-155a-88d5-afef33158dfd.png)


docker-compose.ymlの中身はこんな感じで書きました。

```docker-compose.yml
version: '3'

services:
  db:
    container_name: postgres
    image: postgres:latest
    ports:
      - "5432:5432"
    volumes:
      - ./db:/docker-entrypoint-initdb.d
    environment:
      - POSTGRES_USER=password
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=postgres
    networks:
      - default

volumes:
  yarn_cache:
    driver: 'local'
```
先に動かしてみます。
docker-compose.ymlファイルのあるディレクトリに移動してから

```sh
cd /srv
```
以下のコマンドを実行　(-dはデーモンで起動するというオプション)

```sh
sudo docker-compose up -d db
```
そうするとCreating postgres ...　done！出来ましたー！コンテナが立ち上がりましたー！
![20.png](https://qiita-image-store.s3.amazonaws.com/0/237418/ff9c3c38-a528-ee26-4f46-90513d1c4a74.png)

本当に立ち上がったか確認してみます。

```sh
sudo docker ps
```
この画面見るとdocker-compose.ymlで設定した内容が分かると思います。設定した内容の他に、
作成されたコンテナにCONTAINER ID(ユニークID)が割り振られ、CREATEDで47秒前に作成されたよ
STATUSでUP…起動中だよというのがわかります。
![21.png](https://qiita-image-store.s3.amazonaws.com/0/237418/ed204747-012b-d943-94d3-8fbb6f660876.png)
volumeというのはマウントされる領域を指しているのですが、./dbは先ほど追加したdbディレクトリ
対する/docker-entrypoint-initdb.dという場所は、データ置き場です。
docker-entrypoint-initdb.dにデータを置いておくとDBのデータとして処理してくれます。
だから、ローカルのdb = データ置き場 ってことでマウントしてね　って書いてます。

じゃあ、本当にポスグレ使えるようになってるのか確認してみます。
![24.png](https://qiita-image-store.s3.amazonaws.com/0/237418/a23d4563-e714-a044-7229-c834b7c03a9b.png)
docker-compose.ymlに書いたDB名、ID、パスワードでテスト接続すると...無事繋がりました:v_tone2:
![25.png](https://qiita-image-store.s3.amazonaws.com/0/237418/0a69a6b2-58ff-5ecd-0108-cb52ab1e2b97.png)

Docker使用してDBを作成するに関しては以上です。
コマンドやDockerの特性に関しては全く触れず申し訳ありません。
丁寧に解説して下さっているページがたくさんありますので、そちらでご確認頂くようお願いします。

---
以下はその他参考にさせて頂いたページです。

:slight_smile: Dockerメモ より **[sudo なしでdockerコマンドを叩けるようにする](https://github.com/DQNEO/memo/blob/master/Docker.md#sudo-%E3%81%AA%E3%81%97%E3%81%A7docker%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%82%92%E5%8F%A9%E3%81%91%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E3%81%99%E3%82%8B)**
:slight_smile: Vagrant入門から実践まで より **[仮想マシンのメモリを増やす](
https://qiita.com/daichi87gi/items/d5da33c76295ee32a735#%E3%83%A1%E3%83%A2%E3%83%AA%E3%82%92%E5%A2%97%E3%82%84%E3%81%99
)**