Help us understand the problem. What is going on with this article?

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

参考

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away