Windows7環境なのにdocker入れて開発することになった話【①環境設定編】

改訂情報

- 2019/3/18
    - docker-ceのバージョンUP（18.XX）に伴い、「/etc/systemd/system/docker.service.d/http-proxy.conf」の一番最後を変更

```
（修正前）
ExecStart=/usr/bin/dockerd -H fd:// \$DOCKER_NETWORK_OPTIONS
（修正後）
ExecStart=/usr/bin/dockerd $DOCKER_NETWORK_OPTIONS\
```
（[参考：docker18.09.0にあげたらdocker.serviceが起動しなくなった](https://qiita.com/aoi1/items/7602ec6530eaab29aeee)）

# はじめに
システム開発において、「手順書」という内部成果物をよく見かけます。
（開発環境構築手順書、デプロイ手順書、etc...）
こういったトラディショナルな開発手法が、dockerというソフトウェアによりぶち壊されようとしています。

この記事は、まだまだ発展途中のdockerと、それを取り巻くモダンな技術に立ち向かう、Sierの苦悩の物語です。この記事に辿り着いたということは、dockerを触りたいけどwindows7環境しか無く、中々うまくいかなかった人も多いと思います。そういった方々や、また違う角度から同じような苦悩を抱えてる方々も含め、是非こういった人に読んでいただきたいです。

- windows7環境でdockerツールボックス使ってみたけどうまくいかなかった
- そもそもdockerってなんぞや
- IT企業に入ったのに、ソースコードではなくエクセルをメンテナンスしている
- 最新の技術を学びたいのに、誰も教えてくれない
- ざっくりと開発したい意欲はあるものの、何すればいいか分からない

私自身もまだまだ未熟ですので、間違ったことが多々あるかもしれません。また実際に開発中のアプリケーションなので、2章以降整合性が取れなくなる可能性も有ります。そういった場合、指摘・要望・質問、どしどしコメントいただきたく思います。

長くなりましたが、しばらくの間お付き合いください。

# 辞書整理
本文章（第1章）を読む上で頭に入れておいたほうが良い文言をピックアップ。文中分からない文言が出たら見返してください。（不足あれば、コメントいただけたら追記していきます）

[参考：dockerについて詳しくは３章へ](https://qiita.com/Shunichirou/items/331845b20f37f6c875a2)

- VirtualBox
    - 現在利用しているOS上にで、別のOSを実行できる仮想化ソフトウェア。
    - 現在利用しているOSをホストOS、VirtualBox上に構築したOSをゲストOSと呼ぶ。
    - よく使われるシーンとしては、ホストOSでは導入できないソフトウェア（本記事の場合dockerCE）を利用したい場合や、開発チーム全体で開発環境を統一したい場合、もしくは単にホストOSを汚したく無い場合にも利用する。
    - [参考：【Laravel超入門】開発環境の構築（VirtualBox + Vagrant + Homestead + Composer）](https://qiita.com/7968/items/97dd634608f37892b18a#%E7%AC%AC2%E7%AB%A0-virtualbox-%E3%81%A8%E3%81%AF)

- docker
    - 軽量な仮想マシン（のようなもの）を簡単に構築することができるが、仮想マシンとはそもそもの思想が異なっているため、docckerを利用して構築した環境については明確に「コンテナ」という別の呼び方をする。
    - これまではサーバを仮想化し、１台のサーバに複数の仮想サーバを入れて（と見せかけ）サーバを構築していた。しかし１仮想サーバにつき１OSであるため、増やせば増やすほど動作は重くなっていた。
    - dockerは、１コンテナがホストOSとリソース共有をするため、OSとしては１つでよい。そのためこれまでの仮想マシンに比べて非常に軽量。
    - コンテナ上に作られたアプリケーションは、dockerがインストールされている環境であれば、どんなOS上でも動作する。（ただしdockerはwindows7にはインストール不可）
    - 仮想マシンは電源のONからOFFまでを丸ごと動作させるが、コンテナはあくまで起動後の１つ１つのコマンドのみを動作させる。（起動部分はホストOSとリソース共有してる）
    - コマンドの羅列であるため、デプロイやロールバックも容易。
    - アプリケーションの構成（どんなサーバがあるのか、どんなコマンドをインストールする必要が有るのか）についても一目で分かる。
    - コマンドを羅列しているファイルのことを、Dockerfileと呼ぶ。

    - [参考：Docker導入のための、コンテナの利点を解説した説得資料](https://qiita.com/niisan-tokyo/items/88a53a1b4aa7ad60723e)
- docker-compose
    - dockerにより、ひとつのコンテナ（今までで言うところの仮想サーバ）を立ち上げるのが容易になったが、docker-composeはさらに複数のコンテナを管理することができる。
    - コンテナごとにDockerfileが存在し、そのDockerfileからコンテナを立ち上げる動作をファイルに記載することができる。
    - 各コンテナを起動する際にどういったオプションを引数として渡していたか、一元管理することができる。
    - 各コンテナの起動情報を記載するファイルのことを、docker-compose.ymlと呼ぶ。
    - [参考：Docker compose ことはじめハンズオン](https://qiita.com/TsutomuNakamura/items/7e90e5efb36601c5bc8a)
- sysVinit, Upstart, Systemd
    - Linuxを起動した際に立ち上がったデーモン（メモリに常駐してさまざまな機能を提供する）プロセスを、実際に処理するための機能。
    - sysVnit⇒Upstart⇒Systemdと、発展してきた。今はSystemdが主流（といわれている）
    - とはいえ意図的に使い分けるためにインストールが必要だったりすることは無く、通常Ubuntuをインストールすると全ての機能が入っている。
    - 問題が生じる例としては、sysVnit, Upstartが導入された環境にて、とあるソフトウェアのプロキシ設定をどこかに書いており、アプリケーションが動作していたとする。そこでUbuntuのアップデートを行うなどしてSystemdが導入されると、SystemdとsysVinit, Upstartはプロキシ設定を読みに行く先が異なるため、別のソフトウェア構成ファイルにプロキシ設定を書く必要が有る。本記事のdockerにおけるプロキシ設定についても、２箇所に記載しているのはそのためである。
    - [参考：いまだにsysvinitの手癖が抜けない人のためのsystemd](https://qiita.com/n-i-e/items/9beffea6e0bc5f08036b)
- Proxy
    - コンピュータからWebサーバにアクセスする際に、中継してくれるサーバ。
    - Webサーバにアクセスする際に、コンピュータの「代理」でWebサーバにアクセスし、Webサーバの「代理」でコンピュータにデータを送信する。
    - データのフィルタリングや、キャッシュ、アクセス記録などの機能を持つ場合もある。
    - 上記機能によりセキュリティ機能が向上するため、企業内で外部ネットワークにアクセスする際には基本的にはProxyサーバを介するようなネットワーク構成になっている。
    - [参考：プロキシサーバ(Proxy Server)とは](http://www.geolocation.co.jp/learn/inv/09.html)
- Node.js
    - サーバサイドでJavaScriptを実行できるようにしてくれるプラットフォーム。`node xxx.js`コマンドでxxx.jsのJavaScriptコマンドを実行してくれる。
    - よくそのNode.jsという名前もあいまって「サーバサイドJavaScriptのことだ！」と言われていますが、あくまでサーバサイドでJavaScriptを動かすことを可能にしたプラットフォームのこと。（大事なので二回目）
    - プログラム実行で一番時間のかかる「入出力待ち」の時間を効率的に利用し、入出力待ちが起きている間もプログラムをブロックしない仕組み、「ノンブロッキングI/O」という仕組みを適応。
    - 難しい場合、JavaScriptに似た書き方をできる一種の言語だと思ってしまえば楽かもしれない。
    - [参考：Node.jsとは何か](https://qiita.com/kobalab/items/e0c2a3d5a9f4c172bad0)
- npm
    - モジュール管理ツール。Node.jsで利用するモジュールをインストール/アンインストールできる。
    - 自分が作成したモジュールをNode.jsモジュールとして公開することも可能。（他人がnpmを利用して自分の作成したモジュールをインストール）
    - [参考：npmでnode.jsのpackageを管理する](https://qiita.com/sinmetal/items/395edf1d195382cfd8bc)





# 環境設定
第1章では環境構築をしていきます。
そもそもdockerは現在（2018年3月）Linux環境かWindows10環境でしかサポートしていないので、タイトルどおりwindows7で開発する必要のある今回は、VirtualBoxにUbuntuを入れるところからはじめる。

```
参考
OS：Windows7
メモリ：8.00GB
SSD：256GB
種類：64bit
備考：プロキシ環境下

docker：17.12.0-ce
docker-compose：1.18.0
node.js：v6.12.3
npm：3.10.10
git：version 2.7.4
```

手順としては以下の通り。今回のメインはdocker以降なので、1,2はさっくりと説明する。
1. VirtualBoxのインストール
2. Ubuntuのインストール
3. docker,git、その他コマンドのインストール
## 1.VirtualBoxのインストール
- 公式ページへアクセス[VirtualBox公式](https://www.virtualbox.org/)
- 真ん中の大きなボタン「Download VirtualBox X.X」をクリック
- 自分のOS環境に応じて、「Windows hosts」や「Linux distributions」等をクリックするとダウンロードが始まる
    - 大体の人はWindows環境から別のOSを触りたいことが多いはずなので、その場合は「Windows hosts」を選択することになる
- ダウンロードされた場所にあるexeファイルをたたき、何も考えずにNextを押し続ければインストール完了

## 2.Ubuntuのインストール

### Ubuntu本体のダウンロード
- 公式ページへアクセス[Ubuntu公式](http://releases.ubuntu.com/18.04/)
- Name「ubuntu-18.04.4-desktop-amd64.iso」をクリック
- ダウンロードに時間がかかり、失敗した際に再度ダウンロードするのは手間なので、作業フォルダに退避させておく。

### Ubuntuイメージのマウント
- Oracle VM VirtualBoxを起動する。
- 「新規(N)」をクリック
- 名前に「ubuntu」っぽい名前を入れるとバージョンが勝手にubuntuになり、次へ
- メモリーサイズを任意の値で設定（4G以上あるとさくさく）し、次へ
- ハードディスクの設定で「仮想ハードディスクを作成する」を選択し、任意のサイズで作成する
- 仮想ハードディスクの作成では、全てデフォルトのまま次へ（可変サイズ/固定サイズはどちらでも良い）

### Ubuntuのインストール/起動
- 作成した仮想マシンをダブルクリックし、起動する。
- 起動ハードディスクの選択画面が開くので、ダウンロードしておいた「ubuntu-16.04.3-desktop-amd64.iso」を選択する。
- 起動するとインストール画面が開くため、日本語を選択してインストールを開始する。
- インストールが終わったら、プロキシ環境下である場合はNetWorkの設定をする必要がある。
    - 設定アイコンからSystemSettingsを開き、Networkをダブルクリックする。
    - Network Proxyタブを開きMethodを「Manual」に、HTTP Proxy以下に必要なプロキシ情報を入力し、Apply System wideをクリックする。

![network.png](https://qiita-image-store.s3.amazonaws.com/0/206021/6243f2d0-a78d-abcc-28c4-8bffb8154b56.png)
![proxy.png](https://qiita-image-store.s3.amazonaws.com/0/206021/64a2b670-c021-3a14-1d57-22c30f4a2c31.png)



##　3. 必要なコマンドやソフトウェアをインストール
インストールするコマンド（ソフトウェア）は、次の通り。

- Docker Community Edition
- Docker-Compose
- node.js, npm
- git

### Docker Community Editionのインストール及び設定
Docker Community Editionとは、個人向けの無償のdockerである。これまでdockerと呼んでいたものが、個人向け無償のバージョンをdockerCE、企業向け有償のバージョンをdockerEEと呼び名を変えた。今回インストールするバージョンは、dockerCEである。

インストール手順は、以下の通りであるが、[公式](https://docs.docker.com/install/linux/docker-ce/ubuntu/)に公開されている方法と同じである。またインストール後の設定についても公式のドキュメントが[こちら](http://docs.docker.jp/engine/articles/systemd.html)に存在する。

- インストール
    - $ `curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add`
    - $ `sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"`
    - $ `sudo apt-get update`
    - $ `sudo apt-get -y install docker-ce`
- インストールされていることの確認
    - `docker --version`の結果、Docker version xx.xx.~~であれば正常にインストールされている。
- HTTP Proxy（Upstart, SysVinit）設定
    - $ `sudoedit /etc/default/docker`の一番下に追記

```
export http_proxy="http://proxyserver.co.jp:8080/"
export https_proxy="http://proxyserver.co.jp:8080/"
export no_proxy="127.0.0.1,localhost"
```

- HTTP Proxy（systemd）設定＋Dockerデーモン設定
    - $ `sudo mkdir -p /etc/systemd/system/docker.service.d/`
    - $ `sudoedit /etc/systemd/system/docker.service.d/http-proxy.conf`に新規記載

```
[Service]
Environment="HTTP_PROXY=http://proxyserver.co.jp:8080/" "HTTPS_PROXY=http://proxyserver.co.jp:8080/" "NO_PROXY=127.0.0.1,localhost" "DOCKER_NETWORK_OPTIONS=--dns 999.999.999.999"
ExecStart=
ExecStart=/usr/bin/dockerd $DOCKER_NETWORK_OPTIONS
```

- リロード
    - $ `sudo systemctl daemon-reload`
    - $ `sudo systemctl restart docker`
- OS再起動

### Docker Composeのインストール
インストール手順は以下の通りであるが、Docker同様に[公式](https://docs.docker.com/compose/install/#install-compose)ドキュメントと同じである。

- インストール
    - $ ``sudo curl -L https://github.com/docker/compose/releases/download/1.19.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose``
- 実行権限の追加
    - $ `sudo chmod +x /usr/local/bin/docker-compose`
- インストールされていることの確認
    - `docker-compose -v`の結果、docker-compose version x.xx.x~~であれば正常にインストールされている。

### node.js及びnpmのインストール
node.js及びnpmについては、インストールエラーが良く起きる。実際私自身も複数の方法を試した結果、[公式](https://nodejs.org/en/download/package-manager/)の方法からバージョンを下げてインストールしてうまくいった。（執筆時の最新バージョンは9であるが、今回は6をインストールしている）うまくいかない場合は、一度インストールをしたキャッシュを含めて削除した上でいろいろな方法を試して欲しい。

- node.jsのインストール
    - $ `curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -`
    - $ `sudo apt-get install -y nodejs`
- インストールされていることの確認
    - `node -v`の結果、vx.x.xであれば正常にインストールされている。
- npmのインストール
    - $ `sudo npm install npm@latest -g`
- インストールされていることの確認
    - `npm -v`の結果、x.x.xであれば正常にインストールされている。
- (参考)失敗した場合のクリア方法
    - node.js
        - $ `sudo apt-get remove --purge nodejs`
    - npm
        - $ `sudo npm uninstall npm -g`
        - $ `rm -rf .npm`


### gitのインストール
gitについてはインストールは容易であるが、2段階認証を設定している場合などインストール後に苦労することがあるが、気が向いたら別途記載する。

- gitのインストール
    - `sudo apt-get install git`
- インストールされていることの確認
    - `git --version`の結果、git version x.x.xであれば正常にインストールされている。


[第二章:②システム構成編]
(https://qiita.com/Shunichirou/items/dca96dd027674feea835)へ続く
[第三章:③docker開発環境編](https://qiita.com/Shunichirou/items/331845b20f37f6c875a2)へ続く