Edited at

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

More than 3 years have passed since last update.


概要

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のところ)。そのうちもっと簡単になるでしょうね。


参考