Mac OS XにDocker開発環境を構築し、Dockerイメージの取得とコンテナの起動・停止、イメージの作成方法およびレジストリへのアップなどdockerを利用し始めるにあたって、これだけは抑えておくべきという基本的な内容についてまとめてみました。
Dockerは「Build, Ship, and Run Any App, Anywhere」と謳っているように、Dockerの仕組みでビルドされたアプリケーションは、Docker対応のプラットフォームであればどこでも簡単にデプロイできるようになります。
PHPのWebアプリの場合を例にすると、gitによるソース・サブモジュールの管理、Composeによるパッケージ管理、さらにフロントまわりのパッケージはnpmで管理していたりとビルド、デプロイのプロセスはかなり複雑になっています。そこに、Dockerを利用すると、Java EEの世界でアプリをWarファイルに固めてアプリケーション・サーバーにデプロイするような感覚で、開発環境でビルドしたものをテストし本番へデプロイすることが可能になります。
さらに、デプロイのプロセスが簡単になると、PaaSを利用する際に、PaaSごとの違いをDockerが吸収してくれるので、新しいPaaSを試す時などは、固有の仕組みを覚えるコストが小さく済みそうです。
Dockerそのものの概要については、公式には「What is Docker」に説明があります。
またアーキテクチャと各種用語については「Understand the architecture」にまとまっています。
周辺ツールも増えてきて、なかなか全体像を説明するのも大変なので、ここではDockerそのものの説明は飛ばし、dockerコマンドを打つとDockerイメージを作ったり、自分で作ったイメージや公開されているイメージをコンテナとして起動して簡単にアプリが起動できるものだくらいにまずは抑えておいて、DockerHubに公開されている公式イメージを利用したDockerの使い方についてまとめました。
Docker Toolboxを利用した開発環境の準備
Mac OS Xで、簡単にDocker環境を用意するには公式のDocker Toolboxを利用できます。
Docker Toolboxは、開発に必要な以下のDocker関連ツールが含まれています。
- Docker Client: Docker Enginseと対話するコマンド
- Docker Machine: Docker Engineがインストールされたホストをセットアップするコマンド
- Docker Compose (Mac only): 複数のコンテナを組み合わせたアプリケーションを管理するツール
- Docker Kitematic: Docker管理GUIツール
- VirtualBox: ローカルで開発する場合には、Dockerホストの動作環境としてデフォルトでVirtual Boxを使う
公式ドキュメントのインストール手順は、Installation on Mac OS Xにあります。
Docker ToolboxよりインストーラDockerToolbox-1.8.2c.pkgをダウンロードして実行して、ウィザードに従ってインストールできます。
(boot2dockerは2015.10現在は非推奨になっています。また、boot2dockerをすでに利用している場合は、インストーラが移行してくれます。)
インストール後、Launchpadから”Docker Quickstart Terminal”アイコンをクリックするとTerminalが起動してDockerホストのVMが起動します。
## . ## ## ## == ## ## ## ## ## === /"""""""""""""""""\___/ === ~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ / ===- ~~~ \______ o __/ \ \ __/ \____\_______/ docker is configured to use the default machine with IP 192.168.99.100 For help getting started, check out the docs at https://docs.docker.com
補足ですが、Docker Quickstart Terminalは、VirtualBox上に作成されたdocker-machine defaultを利用するための環境変数がセットされた状態のTerminalを起動してくれるショートカットです。
hello-workdイメージで動作を確認
Docker Quickstart Terminalを起動したらまずは、hello-worldイメージを起動してdockerコンテナの動作を確認してみます
$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
535020c3e8ad: Pull complete
af340544ed62: Pull complete
Digest: sha256:a68868bfe696c00866942e8f5ca39e3e31b79c1e50feaee4ce5e28df2f051d5c
Status: Downloaded newer image for hello-world:latest
Hello from Docker.
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker Hub account:
https://hub.docker.com
For more examples and ideas, visit:
https://docs.docker.com/userguide/
hello-worldイメージは、実行するとメッセージを表示するだけのイメージです。
上記のように表示されれば正しくコンテナを起動できています。
Terminalに出力されたメッセージからも確認できますが、初めて起動するイメージはDockerホストVM内に無いので、pull(Download)してからDockerコンテナが起動されています。
つまり、以下のように、pullしてからrunを実行しても同じです
$ docker pull hello-world
$ docker run hello-world
ここまでの流れを図にすると以下のようになります
hello-worldイメージは、起動してコマンドを実行したらすぐに停止されるイメージなので、docker stop
コマンドを実行しなくても処理が終わるとコンテナは停止します。
(DockerfileのCMDに指定されたコマンドが終了するとDockerコンテナも終了する)
docker ps
コマンドを実行すると起動しているコンテナが無くなっていることが確認できます。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
-a
オプションをつけてdocker ps
すると、hello-worldイメージのコンテナが停止していることを確認できます
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
37a87e518b25 hello-world "/hello" 11 minutes ago Exited (0) 11 minutes ago sharp_poincare
また、Dockerホストにダウンロードされたdockerイメージはdocker images
コマンドで確認できます
$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
hello-world latest af340544ed62 8 weeks ago 960 B
以上で、dockerイメージをリポジトリよりイメージをpullして、イメージからコンテナを起動し、停止するところまでつかめたかと思います。
補足
コマンドを実行するだけのdockerイメージの作成については以下のページが参考になります。
hello-worldイメージが何をしているのか気になる方は参照すると良いと思います。
Create a base imageのCreating a simple base image using scratch
DockerのscratchイメージでHello Worldする
WordPressイメージを起動してみる
デーモンとして起動するアプリケーションの例として、オフィシャルイメージのwordpress(Github: docker-library/wordpress
)を動かしてみます。
wordpressのDockerイメージは、Apache + mod_php環境とfpm環境の2つが用意されていますが、fpmの場合はnginxコンテナも起動する必要があるので、ここではよりシンプルなApache + mod_phpのイメージを試してみます。
また、このイメージは、WebサーバーとPHP実行環境のみが用意されているため、データベースを別途用意する必要があります
データベースは、オフィシャルイメージのmysql(Github: docker-library/mysql)を起動して、それをwordpressコンテナからアクセスするように指定します。
また、MySQLのデータはコンテナの中に保存しておくとコンテナ停止と主に無くなってしまうので、Dockerホスト側に永続化します。
動作環境の構成を図にすると以下のようになります。
VirtualBox上で動いているdocker-machineのホストにログインして、MySQLのデータ用ディレクトリを作成します。
docker-machine ssh
コマンドにdocker-machine名(default)を指定するとsshログインできます。
$ docker-machine ssh default
docker@default:~$ sudo mkdir -p /my/own/datadir
mysqlイメージを起動します。
$ docker run --name mydb -v /my/own/datadir:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=password -d mysql
コマンドのオプションについて
- –name: コンテナ名を明示的に指定しています。Wordpressコンテナからリンクする際にコンテナ名を指定します。
- -v: MySQLコンテナのディレクトリ
/var/lib/mysql
をDockerホストの/my/own/datadir
にマウントします。詳しくは「Managing data in containers」を参照。 - -e: 環境変数MYSQL_ROOT_PASSWORDにMySQLのrootユーザのパスワードを指定しています
- -d: バックグラウンド(デーモン)としてコンテナを起動します
wordpressイメージのインポートして実行します
$ docker run --name mywp --link mydb:mysql -p 8080:80 -d wordpress
コマンドのオプションについて
- –name: コンテナ名を明示的に指定しています。
- –link: MySQLのコンテナmydbをWordpressのデータベースとしてするようにコンテナ名を指定します。詳しくは「Linking containers together」を参照。
- -e: 環境変数MYSQL_ROOT_PASSWORDにMySQLのrootユーザのパスワードを指定しています
- -d: バックグラウンド(デーモン)としてコンテナを起動します
DockerホストのVirtualBox VMのIPアドレスをdocker-machine env
コマンドで確認
$ docker-machine env default | grep DOCKER_HOST
export DOCKER_HOST="tcp://192.168.99.101:2376"
http://192.168.99.101:8080にアクセスするとWordpressのインストール画面が表示されます
MySQLのデータはDockerホスト側のディスクに保存するようにしました。
実際にMySQLのデータがホスト側のディレクトリに保存されているか確認してみます。
$ docker-machine ssh default
docker@default:~$ ls /my/own/datadir/
auto.cnf ib_logfile1 mysql/ wordpress/
ib_logfile0 ibdata1 performance_schema/
確かにMySQLのデータファイルが書き込まれています。
MySQLとWordpressのコンテナは、MySQL、Apacheのプロセスが停止しなければ起動したままになります。
このようなコンテナを停止するには明示的にdocker stop
コマンドを使ってコンテナを停止します。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
50e710229b4a wordpress "/entrypoint.sh apach" 4 minutes ago Up 4 minutes 0.0.0.0:8080-dd>80/tcp mywp
02081c109a94 mysql "/entrypoint.sh mysql" 4 minutes ago Up 4 minutes 3306/tcp mydb
$ docker stop 50e710229b4a 02081c109a94
50e710229b4a
02081c109a9
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
docker-machineコマンドまとめ
ところで、ここまでは、Docker Toolboxインストール時に作成されるdocker-machine defaultを利用して動作を確認してきましたが、docker-machineは新たに作成したり、VirtualBoxだけでなくAWSやDigitalOceanなどクラウド上に作成したりすることができます。
docker-machineのコマンドについて、使い方についてメモしておきます。
新しいdocker-machineの作成して利用をする手順
default以外に新しくdocker-machineを作成、起動して、dockerコマンドの実行先を変更する手順をまとめてみました。
docker-machineの作成
$ docker-machine create <docker-machine名dd>
docker-machineの起動
$ docker-machine start <docker-machine名dd>
docker-machine環境変数の確認
$ docker-machine env <docker-machine名dd>
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.101:2376"
export DOCKER_CERT_PATH="/Users/hrendoh/.docker/machine/machines/<docker-machine名dd>"
export DOCKER_MACHINE_NAME="<docker-machine名dd>"
# Run this command to configure your shell:
# eval "$(docker-machine env <docker-machine名dd>)"
docker-machine環境変数を適用
$ eval "$(docker-machine env <docker-machine名dd>)"
以上で、新しく作成したdocker-machineを利用可能になります。
全てのコマンドについては「Supported Docker Machine subcommands」を参照ください。
Digital Oceanプロバイダーを利用する
docker-machineは、特に指定しなければデフォルトプロバイダはVirtual Machineが選択されますが、Virtual Machine以外に、AWSやAzure、DigitalOceanなどのクラウド環境やVMWare関連ツールなど、Supported Driversにリストされている様々なプラットフォームのプロバイダーをサポートしています。
ここでは、DigitalOcaenプロバイダの動作を確認してみます。
Digital Oceanの手順を参考に、Digital Ocearnのシンガポールリージョンにdocker-machineを作成してみます。
$ docker-machine create --driver digitalocean --digitalocean-access-token=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX --digitalocean-size=1gb --digitalocean-region sgp1 docker-machine
Creating SSH key...
Creating Digital Ocean droplet...
To see how to connect Docker to this machine, run: docker-machine env docker-machine
DigitalOceanのDropletが追加されていることを確認できます
コマンド実行先を作成したdocker-machineに変更しまます
$ eval "$(docker-machine env docker-machine)"
以上で、dockerコマンドがDigitalOceanに作成したdocker-machine上で実行されるようになります。