概要
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ファイルなどの置き場所
Docker環境の準備
Docker Toolboxのインストール
DockerのオフィシャルサイトのDocker ToolboxからDocker Toolboxのインストーラを入手します。このインストーラにはVirtualBoxやGit for Windowsが同梱されてます。
次に、Docker Toolboxのインストーラを起動してDocker関連のコンポーネントをインストールします。
重要!
一番下のチェックボックス「Install VirtualBox with NDIS5 driver[default NDIS6]」にチェック入れるのを忘れずに!
理由などこちらが参考になるかと。
Failed to open/create the internal network Vagrant on Windows10
Docker用の仮想マシンを構築
__Docker Quickstart Terminal__を起動します。初回のみVirtualBox上にDocker用の仮想マシンを作成してくれます。その後、仮想マシンのコンソールにログインしてくれます。
しばらくすると...Dockerエンジンが動作しているDockerホストの仮想マシンに接続する。
VirtualBoxには__default__インスタンスができてる。
WindowsマシンからDcokerの動作確認
Dockerのオフィシャルサイトの例を試す。
$ docker run hello-world
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
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コンテナにあるユーザデータが残っているかを確認してみます。
手順はこんな感じです。
- JenkinsのPluginを更新する
- JenkinsのDockerコンテナを作り直す
- Pluginが更新済みであるかを確認する
1. JenkinsのPluginを更新する
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画面を見てみる。__(アップデートあり)__がない。
意図通りに動作しました。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 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。
#!/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
起動は次のようにやります。
- mysqlのみを起動してsonarqube用のDatabaseを作成する
- 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番ポートにアクセスしてみましょう。
管理者アカウントでログインして、メニューよりAdministration→System→System Infoを参照すると、DatabaseがMySQLとなっているはずです。なお、デフォルトの管理者アカウント/パスワードは、admin/adminです。
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番ポートです。
UltraVNCViewerなどでDockerホストの5900に接続するとChrome用のSeleniumNodeに接続できます。
GlassFishを動かす
docker-compose.ymlに以下の内容を追記します。
# glassfish
glassfish:
image: glassfish
ports:
- "14848:4848"
- "18080:8080"
- "18181:8181"
起動する。
$ docker-compose up -d glassfish
ブラウザで接続する。Dockerホストの14848番ポート。
リモートからログインできるようにしておく。
※そのうちスクリプト化しよう。
- asadmin change-admin-password
- asadmin login
- 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の管理コンソールに接続する。セキュリティの警告を無視してログイン画面に進む。
先ほど設定したユーザ/パスワードでログインする。
いつもの画面です。
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のところ)。そのうちもっと簡単になるでしょうね。