Windows10マシンにDocker Toolbox を入れて個人用の開発環境を作る

  • 213
    いいね
  • 3
    コメント
この記事は最終更新日から1年以上が経過しています。

概要

Windowsマシン上にDocker Toolboxをインストールして個人用のアプリ開発環境を作ってみます。Windowsマシンそのものへのインストールツールは最小限にして、Docker Toolboxに含まれる仮想マシン上にDockerを使ってSonarQubeなどをセットアップしてみます。

2016.3.29 新しいインストーラ(DockerToolbox-1.10.3.exe)でやり直してみました。

前提としている環境

  • Windows 10 (7以上だったらいけるはず)
  • Intel VT対応 (それ相当の仮想化テクノロジが使えればよい。最近のPCはほとんど対応しているはず。 )

目指すこと

JavaでのWebアプリ開発で使うだろう開発環境を構築します。構築するミドルウェア、ツールは以下のようなイメージです。

導入するDockerコンテナ

  • Jenkins
  • MySQL
  • SonarQube
  • Selenium
  • Glassfish

ymlファイルなどの置き場所

https://github.com/osuo/DevelopEnvironment

Docker環境の準備

Docker Toolboxのインストール

DockerのオフィシャルサイトのDocker ToolboxからDocker Toolboxのインストーラを入手します。このインストーラにはVirtualBoxやGit for Windowsが同梱されてます。

次に、Docker Toolboxのインストーラを起動してDocker関連のコンポーネントをインストールします。

WS000038.JPG

重要!
一番下のチェックボックス「Install VirtualBox with NDIS5 driver[default NDIS6]」にチェック入れるのを忘れずに!
WS000042.JPG

理由などこちらが参考になるかと。
Failed to open/create the internal network Vagrant on Windows10

Docker用の仮想マシンを構築

Docker Quickstart Terminalを起動します。初回のみVirtualBox上にDocker用の仮想マシンを作成してくれます。その後、仮想マシンのコンソールにログインしてくれます。

WS000015.JPG

しばらくすると...Dockerエンジンが動作しているDockerホストの仮想マシンに接続する。
WS000016.JPG

VirtualBoxにはdefaultインスタンスができてる。
WS000017.JPG

WindowsマシンからDcokerの動作確認

Dockerのオフィシャルサイトの例を試す。

$ docker run hello-world

こんな感じになればOK。
WS000018.JPG

docker-machineでも確認してみる。

$ docker-machine ls
NAME      ACTIVE   DRIVER       STATE     URL                         SWARM   ERRORS
default   *        virtualbox   Running   tcp://192.168.99.101:2376

defaultという名前のDockerホストが起動状態にあることが分かる。

docker-machine stop defaultでdefaultを止めたり、docker-machine start defaultで開始したりできる。

Dockerコンテナの起動と利用

Dockerコンテナの制御にdocker-compoiseを使う。素のdockerだと起動時に指定するパラメータを毎回コマンドラインに指定することになるのですが、docker-composeだとymlファイルに記述できすっきりするから、です。

適当なフォルダを作り、その中にdocker-compose.ymlなどを置いて試します。
とりあえず、workディレクトリを作っておきましょう。

$ mkdir work
$ cd work

Jenkinsを動かす

docker-compose.ymlを作成します。

jenkins:
  image: jenkins
  ports:
    - "8080:8080"

docker-compose.ymlを作成したディレクトリでdocker-composeを実行します。初回はjenkinsのDockerイメージをDockerHubから入手してから起動します。

$ docker-compose up -d
...
Status: Downloaded newer image for jenkins:latest
Creating work_jenkins_1

Dockerコンテナの状態を確認してみます。

$ docker-compose ls
     Name                   Command               State                 Ports 
-------------------------------------------------------------------------------------------
work_jenkins_1   /bin/tini -- /usr/local/bi ...   Up      50000/tcp, 0.0.0.0:8080->8080/tcp

Ports欄の0.0.0.0:8080->8080/tcpというのは、Dockerホストの8080ポートをDockerコンテナの8080ポートにポートフォワードしますよ、ってことです。
なのでブラウザでDockerホストの8080ポートにアクセスすればjenkinsのコンソールが開きます。DockerホストのIPアドレスはdocker-machineでわかります。

$ docker-machine ls
NAME      ACTIVE   DRIVER       STATE     URL                         SWARM   ERRORS
default   *        virtualbox   Running   tcp://192.168.99.101:2376

こんな画面がでるはず。
WS000021.JPG

Jenkinsを動かす(Data Volumes コンテナとともに)

jenkinsのユーザデータはDockerコンテナ内の/var/jenkins_homeに格納されます(ワークスペース、各種設定やPluginなど)。これをData Volumesコンテナとして独立させることができます。Jenkins本体のDockerコンテナとそのユーザデータのDockerコンテナを分けることで、Jenkins本体をアップグレードすることが楽にできるようになります。より実践的な使い方です。

1. JenkinsのDockerコンテナの内容を確認する

念のため。中身がどうなっているかを調べておきます。docker execで確認します。Jenkinsのコンテナを削除してもユーザデータが影響を受けないか(残っているか)の確認のためです。

docker inspectで確認。

$ docker inspect -f "{{ .HostConfig.VolumesFrom }} " work_jenkins_1
[]

DataVolumeコンテナーの有り無しをdfで確認できるかと思ったけどできず。なんでだろう?また調べよう。(/proc/mounts でも違いがわからず。)

$ docker exec -it work_jenkins_1 df -h
Filesystem      Size  Used Avail Use% Mounted on
none             19G 1007M   17G   6% /
tmpfs           499M     0  499M   0% /dev
tmpfs           499M     0  499M   0% /sys/fs/cgroup
/dev/sda1        19G 1007M   17G   6% /etc/hosts
shm              64M     0   64M   0% /dev/shm

2. 先ほど作成したJenkinsのDockerコンテナを削除する

docker-compose stop jenkinsでJenkinsを停止して、docker-compose rm jenkinsでJenkinsのコンテナを削除します。後は、Dockerコンテナの状態をdocker-compose psで確認します。

$ docker-compose stop jenkins
Stopping work_jenkins_1 ...
[1Bping work_jenkins_1 ... done
$ docker-compose ps
     Name                   Command                State     Ports
------------------------------------------------------------------
work_jenkins_1   /bin/tini -- /usr/local/bi ...   Exit 143
$ docker-compose rm jenkins
Going to remove work_jenkins_1
Are you sure? [yN] y
Removing work_jenkins_1 ...
[1Bving work_jenkins_1 ... done
$ docker-compose ps
Name   Command   State   Ports
------------------------------

JenkinsのDockerコンテナを削除できました。

3. docker-compose.ymlを修正してユーザデータ格納用のDataVolumesコンテナを追記する

docker-compose.ymlを次のように修正します。

# jenkins container
jenkins:
  image: jenkins
  ports:
    - "8080:8080"
  volumes_from:
    - jenkins_data

# jenkins data volume container
jenkins_data:
  image: jenkins
  command: echo "jenkins data volume container."

4. コンテナを起動する

docker-compose up -dで起動します。

$ docker-compose up -d
...
Status: Downloaded newer image for busybox:latest
Creating work_jenkins_data_1
Creating work_jenkins_1
$ docker-compose ps
       Name                      Command               State
Ports
-------------------------------------------------------------------------------------------------
work_jenkins_1        /bin/tini -- /usr/local/bi ...   Up       50000/tcp, 0.0.0.0:8080->8080/tcp
work_jenkins_data_1   /bin/tini -- /usr/local/bi ...   Exit 0

5. 確認する

$ docker inspect -f "{{ .HostConfig.VolumesFrom }} " work_jenkins_1
[6f65fc53675392163fc090be8ceeaa0e7ced5f757a17ec59cf92258fc1d66a3f:rw]

お!この6f65fc536753...というのがDataVolumeコンテナであるwork_jenkins_data_1 のことです。docker ps -aで確認します。

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS                               NAMES
452d31f1400d        jenkins             "/bin/tini -- /usr/lo"   7 minutes ago       Up 7 minutes               0.0.0.0:8080->8080/tcp, 50000/tcp   work_jenkins_1
6f65fc536753        jenkins             "/bin/tini -- /usr/lo"   About an hour ago   Exited (0) 7 minutes ago                                       work_jenkins_data_1

次に、JenkinsのDockerコンテナを削除しても、DataVolumeコンテナにあるユーザデータが残っているかを確認してみます。
手順はこんな感じです。

  1. JenkinsのPluginを更新する
  2. JenkinsのDockerコンテナを作り直す
  3. Pluginが更新済みであるかを確認する

1. JenkinsのPluginを更新する

更新前:
(アップデートあり)となっています。
WS000023.JPG

更新:
こんな感じで。
WS000026.JPG

2. JenkinsのDockerコンテナを作り直す

止めて、

$ docker-compose stop jenkins
Stopping work_jenkins_1 ...
[1Bping work_jenkins_1 ... done

削除して、

$ docker-compose rm jenkins
Going to remove work_jenkins_1
Are you sure? [yN] y
Removing work_jenkins_1 ...
[1Bving work_jenkins_1 ... done

確認します。DataVolumeコンテナのみ残ってます。

$ docker-compose ps
       Name                      Command               State    Ports
---------------------------------------------------------------------
work_jenkins_data_1   /bin/tini -- /usr/local/bi ...   Exit 0

起動する。

$ docker-compose up -d
Starting work_jenkins_data_1
Creating work_jenkins_1

3. Pluginが更新済みであるかを確認する

先ほどのPlugin画面を見てみる。(アップデートあり)がない。
WS000025.JPG

意図通りに動作しました。DataVolumeコンテナを通常のコンテナと別にすることで、ユーザデータなどの保持がしやすくなります。

MySQLをバックエンドにしてSonarQubeを動かす

docker-compose.ymlに次の内容を追記する。

# mysql container
mysql:
  image: mysql
  environment:
    - MYSQL_ROOT_PASSWORD=hogehoge
  ports:
    - "3306:3306"
  volumes_from:
    - mysql_data

# mysql container
mysql_data:
  image: mysql
  command: echo "sonarqube data volume container."

# sonarqube container
sonarqube:
  image: sonarqube
  environment:
    - SONARQUBE_JDBC_USERNAME=sonar
    - SONARQUBE_JDBC_PASSWORD=sonar
    - SONARQUBE_JDBC_URL=jdbc:mysql://mysql/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true
  links:
    - mysql:mysql
  ports:
    - "9000:9000"
  volumes_from:
    - sonarqube_data

# sonarqube data volume container
sonarqube_data:
  image: sonarqube
  command: echo "sonarqube data volume container."

sonarqube用のDatabase作成スクリプトを用意する。
まず、create_sonar_db.sql。

create_sonar_db.sql
CREATE DATABASE sonar CHARACTER SET utf8;

CREATE USER 'sonar' IDENTIFIED BY 'sonar';
GRANT ALL ON sonar.* TO 'sonar'@'%' IDENTIFIED BY 'sonar';
GRANT ALL ON sonar.* TO 'sonar'@'localhost' IDENTIFIED BY 'sonar';
FLUSH PRIVILEGES;

次に、create_sonar_db.sh。

create_sonar_db.sh
#!/bin/bash

#
DIRNAME=${0%/*}
MYSQL_CONTAINER=work_mysql_1
MYSQL_PASSWORD=hogehoge

# dockerコンテナを起動してデータをロードする
docker run -i --link $MYSQL_CONTAINER:mysql --rm mysql mysql -h mysql -uroot -p$MYSQL_PASSWORD < ./$DIRNAME/create_sonar_db.sql

起動は次のようにやります。
1. mysqlのみを起動してsonarqube用のDatabaseを作成する
2. sonarqubeを起動する

1. mysqlのみを起動する

$ docker-compose up -d mysql
Starting work_mysql_data_1
Creating work_mysql_1
$ docker-compose ps
        Name                       Command               State                  Ports
---------------------------------------------------------------------------------------------------
work_jenkins_1          /bin/tini -- /usr/local/bi ...   Up       50000/tcp, 0.0.0.0:8080->8080/tcp
work_jenkins_data_1     /bin/tini -- /usr/local/bi ...   Exit 0                 
work_mysql_1            /entrypoint.sh mysqld            Up       0.0.0.0:3306->3306/tcp
work_mysql_data_1       /entrypoint.sh echo sonarq ...   Exit 0

2. sonarqube用のDatabaseを作成する

$ bash ./create_sonar_db.sh
mysql: [Warning] Using a password on the command line interface can be insecure.

確認します。

$ docker run --rm -it --link work_mysql_1:mysql mysql mysql -h mysql -uroot -
phogehoge
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.9 MySQL Community Server (GPL)

Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show tables;
ERROR 1046 (3D000): No database selected
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sonar              |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

3. sonarqubeを起動する

$ docker-compose up -d sonarqube
Starting work_sonarqube_data_1
Starting work_mysql_data_1
work_mysql_1 is up-to-date
Creating work_sonarqube_1
$ docker-compose ps
        Name                       Command               State                  Ports
---------------------------------------------------------------------------------------------------
work_jenkins_1          /bin/tini -- /usr/local/bi ...   Up       50000/tcp, 0.0.0.0:8080->8080/tcp
work_jenkins_data_1     /bin/tini -- /usr/local/bi ...   Exit 0                 
work_mysql_1            /entrypoint.sh mysqld            Up       0.0.0.0:3306->3306/tcp
work_mysql_data_1       /entrypoint.sh echo sonarq ...   Exit 0                 
work_sonarqube_1        ./bin/run.sh                     Up       0.0.0.0:9000->9000/tcp
work_sonarqube_data_1   ./bin/run.sh echo sonarqub ...   Exit 0

ブラウザでDockerホストの9000番ポートにアクセスしてみましょう。
WS000028.JPG

管理者アカウントでログインして、メニューよりAdministration→System→System Infoを参照すると、DatabaseがMySQLとなっているはずです。なお、デフォルトの管理者アカウント/パスワードは、admin/adminです。

WS000028.JPG

WS000029.JPG

WS000030.JPG

Seleniumを動かす

docker-compose.ymlに以下の内容を追記します。

# sonarqube data volume container
sonarqube_data:
  image: sonarqube
  command: echo "sonarqube data volume container."

# selenium hub container
selenium-hub:
  image: selenium/hub
  ports:
    - "4444:4444"

# selenium node chrome container
chrome:
  image: selenium/node-chrome-debug
  ports:
    - "5900:5900"
  links:
    - selenium-hub:hub

# selenium node firefox container
firefox:
  image: selenium/node-firefox-debug
  ports:
    - "5901:5900"
  links:
    - selenium-hub:hub

起動します。

$ docker-compose up -d
$ docker-compose ps
        Name                       Command               State                  Ports
---------------------------------------------------------------------------------------------------
work_chrome_1           /opt/bin/entry_point.sh          Up       0.0.0.0:5900->5900/tcp
work_firefox_1          /opt/bin/entry_point.sh          Up       0.0.0.0:5901->5900/tcp
・・・
work_selenium-hub_1     /opt/bin/entry_point.sh          Up       0.0.0.0:4444->4444/tcp
・・・

hubのコンソールを覗いてみます。Dockerホストの4444番ポートです。

WS000031.JPG

UltraVNCViewerなどでDockerホストの5900に接続するとChrome用のSeleniumNodeに接続できます。
WS000032.JPG

GlassFishを動かす

docker-compose.ymlに以下の内容を追記します。

# glassfish
glassfish:
  image: glassfish
  ports:
    - "14848:4848"
    - "18080:8080"
    - "18181:8181"

起動する。

$ docker-compose up -d glassfish

ブラウザで接続する。Dockerホストの14848番ポート。

WS000033.JPG

リモートからログインできるようにしておく。
※そのうちスクリプト化しよう。
1. asadmin change-admin-password
2. asadmin login
3. asadmin enable-secure-admin

作成したアカウントは、admin/12345678です。

$ docker exec -it work_glassfish_1 bash
root@0512d1444d81:/usr/local/glassfish4# asadmin change-admin-password
Enter admin user name [default: admin]>
Enter the admin password>
Enter the new admin password>
Enter the new admin password again>
Command change-admin-password executed successfully.
root@0512d1444d81:/usr/local/glassfish4#
root@0512d1444d81:/usr/local/glassfish4# asadmin login
Enter admin user name [Enter to accept default]> admin
Enter admin password>
Login information relevant to admin user name [admin] for host [localhost] and admin port [4848] stored at [/root/.gfclient/pass] successfully.
Make sure that this file remains protected. Information stored in this file will be used by administration commands to manage associated domain.
Command login executed successfully.
root@0512d1444d81:/usr/local/glassfish4#
root@0512d1444d81:/usr/local/glassfish4# asadmin enable-secure-admin
You must restart all running servers for the change in secure admin to take effect.
Command enable-secure-admin executed successfully.
root@0512d1444d81:/usr/local/glassfish4# exit
exit

glassfishのDockerコンテナを再起動する。

$ docker-compose restart glassfish

改めてGlassfishの管理コンソールに接続する。セキュリティの警告を無視してログイン画面に進む。

WS000034.JPG

先ほど設定したユーザ/パスワードでログインする。

WS000035.JPG

いつもの画面です。

Dockerのバックアップ

DockerコンテナでData Volumes コンテナをバックアップする仕掛けを用意してみました。参考になればうれしいです。
docker-backup

Data Volumesコンテナのバックアップについては ここが参考になりそうです。

Windowsでの注意点

windows10でdockerを操作していて気付いたことをメモしておきます。

execでls /とするとWindows側のパスを見ちゃう

$ docker exec -it work_jenkins_1 ls /var/jenkins_home
ls: cannot access D:/Apps/Git/var/jenkins_home: No such file or directory

Dockerコンテナの/var/jenkins_homeを見たいのだけど、変になる。相対パスにしてやればとりあえず見える。

$ docker exec -it work_jenkins_1 ls var/jenkins_home
Download metadata.log          jobs                      secrets
Workspace clean-up.log         nodeMonitors.xml          updates
copy_reference_file.log        nodes                     userContent
hudson.model.UpdateCenter.xml  plugins                   war
identity.key.enc               secret.key
init.groovy.d                  secret.key.not-so-secret

最後に

Dockerを使った開発環境づくりのメモを書きました。Windows10のはまりどころを知れて良かったです(VirtualBoxのところ)。そのうちもっと簡単になるでしょうね。

参考