今さら驚きもしない Dockerファミリの利用なのですが、 docker-compose のYAMLを作成して、Wordpress と MySQLの構成を約1分で起動する方法についてのメモです。
実現したい事
docker-compose の yamlファイルを作成して、Dockerコンテナで Wordpress のサーバーとMySQLデータベースを作成します。 MySQLのデータ領域は、コンテナのホストOSの領域と共有することで、コンテナを削除してもWordpressのデータは保存しておき、何度でも続きから再開できる様にするものです。
docker-compose の定義ファイル
docker-compose の yamlファイルには、mysqlサーバー と wordpress の定義を書いておきます。 db:とwordpress: それぞれにある image は、それぞれ、Dockerストアのリポジトリのオフィシャル・イメージです。 もちろん、自分で Dockerイメージをビルドする事もできますが、Dockerストアには、コンテナ環境用最適化された様々なオフィシャル・イメージが登録されているので、適宜利用して効率を高めるのが良いと思います。
version: '3'
services:
db:
image: mysql:5.7
volumes:
- "./mysql-data:/var/lib/mysql"
restart: always
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
ports:
- "8001:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
MySQL公式コンテナ・イメージ
Docker Hub に登録されている オフィシャル MySQL コンテナイメージのウェブページ には、コンテナを利用するにあたり、便利な機能や必要な情報が書かれていますから、利用するにあたっては、確認しておく事をお勧めします。 一例として、このウェブページには、利用可能な環境変数と機能について説明があります。 その具体例として、db: の environment: にある環境変数は、初回起動時にパスワードやデータベースを設定するためのものです。
ここでは、MYSQL_USER と WORDPRESS_DB_USER を一致させ、かつ、MYSQL_PASSWORD と WORDPRESS_DB_PASSWORDを一致させて設定することで、Wordpress サーバーから MySQLサーバーをアクセスできる様になります。
次にvolumesの - ./mysql-data:/var/lib/mysql
では、先頭のハイフン(マイナス)は、その行が配列の1要素であることを表し、volumes の定義の中に、複数の保存場所の定義が設定できることがわかります。 そして、:
を境界に、前半がコンテナのホストになっているLinuxのファイルシステムです。 そして、後半がコンテナ上のファイル・システムの位置になります。 この設定では、mysqlのデータ領域をコンテナのホスト側にマップします。 これによって、コンテナを消去しても、データベースの内容は保存されます。
その他にも、volumes に - ./data/mysql_init:/docker-entrypoint-initdb.d
をマップしておき、拡張子 .sh や .sql のファイルを置くとで、初回起動時に一回だけ実行して、データをロードし、初期化するなどのバッチを実行することができます。
Wordpress公式コンテナ・イメージ
Wordpress オフィシャル・コンテナでは、MySQLサーバーとの接続について、そして、機能拡張についての記述があります。 また、Wordpress のイメージのベースOSは、Alpine であることが解ります。 Apline は、非常にコンパクトなOSイメージで、起動時間の短縮や資源の節約に効果が高く、とても利用者が多い様です。
Wordpress のコンテナは、MySQLのコンテナに依存しているわけですが、それを表す表記が depents_on:
の後に - db
と設定されている部分です。 この設定により、MySQLを先に起動する様になります。 そして、Wordpressのコンテナでは、ホスト名 'db' で MySQLへアクセスできる様になります。
起動過程の様子
前述のyamlファイルのある場所で、docker-compose up -d
を実行することで、Docker Hubからコンテナをダウンロードして、利用できる様になります。
$ docker-compose up -d
Creating network "wordpress_default" with the default driver
Pulling db (mysql:5.7)...
5.7: Pulling from library/mysql
aa18ad1a0d33: Pull complete
1324423d52e9: Pull complete
ee152a81987c: Pull complete
b054cf37bcae: Pull complete
eb0cbad90353: Pull complete
710fc2dae571: Pull complete
5ff098d10285: Pull complete
79f9dfa6f98f: Pull complete
5d033d38431e: Pull complete
bdde10ea566e: Pull complete
1a36bb8deb0e: Pull complete
Digest: sha256:dfaabbd5466dafe04c5af0ccb1a43d8a18a9604ac23a95534bb0626b3321034d
Status: Downloaded newer image for mysql:5.7
Pulling wordpress (wordpress:latest)...
latest: Pulling from library/wordpress
aa18ad1a0d33: Already exists
29d5f85af454: Pull complete
eca642e7826b: Pull complete
3638d91a9039: Pull complete
3646a95ab677: Pull complete
628b8373e193: Pull complete
c24a2b2280ed: Pull complete
f968b84cbbbc: Pull complete
74cc3c21f7f1: Pull complete
27fb12209ba4: Pull complete
18cac49c13da: Pull complete
0eb6cc3dbc7d: Pull complete
c4f8e37f04ae: Pull complete
8f39cfb9a6c6: Pull complete
1f35c5fef428: Pull complete
5a7fa3665466: Pull complete
9d4bb117fcc0: Pull complete
2fc5ef806fe5: Pull complete
Digest: sha256:47803b7a0984a500e902ad42b9809d63283b66d72e4fb7cfd824d2c46ee93d7a
Status: Downloaded newer image for wordpress:latest
Creating wordpress_db_1 ...
Creating wordpress_db_1 ... done
Creating wordpress_wordpress_1 ...
Creating wordpress_wordpress_1 ... done
システムの構築が完了したら、コンテナの稼働を確認します。 次のコマンドで、MySQL と WordPress の二つが起動していることが解りますす。
$ docker-compose ps
Name Command State Ports
-------------------------------------------------------------------------------------
wordpress_db_1 docker-entrypoint.sh mysqld Up 3306/tcp
wordpress_wordpress_1 docker-entrypoint.sh apach ... Up 0.0.0.0:8001->80/tcp
Wordpress のインストールと起動確認
PCのブラウザで http://localhost:80001/
をアクセスすると 次の様な画面が出ますから、画面の指示に従って、設定を進めます。
設定が完了すると、http://localhost:80001/
の美しい画面が表示される様になります。
コンテナ間のネットワーク
Wordpressの実行中のコンテナには、次のコマンドでログインして、dbサーバーに向けて ping を実行してみます。
$ docker exec -it wordpress_wordpress_1 bash
ping の結果から、Dockerコンテナは、172.18 のネットワーク上に存在していることが解ります。
# ping db
PING db (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: icmp_seq=0 ttl=64 time=0.047 ms
64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.065 ms
64 bytes from 172.18.0.2: icmp_seq=2 ttl=64 time=0.062 ms
^C--- db ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.047/0.058/0.065/0.000 ms
コンテナ間のネットワークがどうなっているか、知るために、dockerコマンドを利用しながら、確認していきます。 この中で、wordpress_defaultが、今回、起動したコンテナが接続されている仮想ネットワークです。
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
30219220453c bridge bridge local
3b8dfb6dcc75 host host local
f9912e005a1f none null local
585a21a1115f wordpress_default bridge local
この仮想ネットワークに繋がる WordpressサーバーとMySQLサーバー について、docker network inspect wordpress_default
コマンドを利用して、さらに、確認していきます。 '172.18.0.0/16' という仮想ネットワークが作られており、二つのコンテナのアドレス、及び、デフォルトGWを把握することができます。
$ docker network inspect wordpress_default
[
{
"Name": "wordpress_default",
"Id": "585a21a1115f135328f2aa8cfb6fcb58c38175e417c346f2de0c79574afd231d",
"Created": "2017-09-19T04:21:36.817963302Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
},
"Internal": false,
"Attachable": true,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"0ce550af1dbabc768449d436c6dff57adc448f0a1c6c4f067b17ad71ce64b96f": {
"Name": "wordpress_wordpress_1",
"EndpointID": "bbdd3b5af92e1f7616881d474a8eab057ecce01386b496c3ab07c0bfd88e738e",
"MacAddress": "02:42:ac:12:00:03",
"IPv4Address": "172.18.0.3/16",
"IPv6Address": ""
},
"a43246787bfe5e0773400112f0752146b92ffb08ddec86366d01d279d5cadb54": {
"Name": "wordpress_db_1",
"EndpointID": "e02fa8cd307513d83190485265ceffca40ffa05cbedde193f0926e4f53485dd6",
"MacAddress": "02:42:ac:12:00:02",
"IPv4Address": "172.18.0.2/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {
"com.docker.compose.network": "default",
"com.docker.compose.project": "wordpress"
}
}
]
これを図にすると、次の様になります。 もっと知りたい方は、 Docker container networking や 参考訳:Docker コンテナ・ネットワークの理解 がお勧めです。
Vagrant の構成ファイル
本題ではないのですが、Dockerの動作環境をPCに作ると、PCの乗り換えや、メモリを圧迫したり、定常的に影響を与える様になりますから、僕の場合は、Docker環境は、Vagrant + VirturalBox 上の仮想マシン上に作成しています。 Vagrantはとても便利な、仮想環境とのユーザーインタフェースで、いつも愛用しています。
以下に、Vagrantfile をあげて、ポイントをコメントします。
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/trusty64"
config.vm.network "public_network", ip: "192.168.1.88", bridge: "en0: Ethernet"
config.vm.network :forwarded_port, host: 3000, guest: 3000
config.vm.network :forwarded_port, host: 8001, guest: 8001
config.vm.network :forwarded_port, host: 4040, guest: 4040
config.vm.provider "virtualbox" do |vb|
vb.memory = "1024"
end
config.vm.provision "shell", inline: <<-SHELL
apt-get update
apt-get install -y make build-essential git libssl-dev X11-apps libxml2 libxml2-dev re2c libcurl3 libjpeg-dev icu-devtools libicu-dev libmcrypt-dev libtidy-dev libxslt1-dev libcurl4-openssl-dev zip zlib1g-dev libbz2-dev libpng12-dev g++ libreadline-dev autoconf ksh unzip default-jre libsqlite3-dev emacs24-nox wget curl llvm libncurses5-dev libncursesw5-dev xz-utils tk-dev
#
su -l vagrant -c 'echo "# Program Language switch env" > ~/.bash_profile'
#
# Install phpenv & php-build
#
su -l vagrant -c 'echo "# for PHP" >> ~/.bash_profile'
su -l vagrant -c 'git clone git://github.com/madumlao/phpenv.git ~/.phpenv'
su -l vagrant -c 'git clone git://github.com/CHH/php-build.git $HOME/.phpenv/plugins/php-build'
su -l vagrant -c 'echo export PATH=$HOME/.phpenv/bin:$PATH >> ~/.bash_profile'
su -l vagrant -c 'echo eval "$(phpenv init -)" >> ~/.bash_profile'
#
# Install ndenv & node-build
#
su -l vagrant -c 'echo "# for Node.js" >> ~/.bash_profile'
su -l vagrant -c 'git clone https://github.com/riywo/ndenv ~/.ndenv'
su -l vagrant -c 'git clone https://github.com/riywo/node-build.git ~/.ndenv/plugins/node-build'
su -l vagrant -c 'echo export PATH="$HOME/.ndenv/bin:$PATH" >> ~/.bash_profile'
su -l vagrant -c 'echo eval "$(ndenv init -)" >> ~/.bash_profile'
#
# Install rbenv & ruby-build
#
su -l vagrant -c 'echo "# for Ruby" >> ~/.bash_profile'
su -l vagrant -c 'git clone https://github.com/sstephenson/rbenv.git ~/.rbenv'
su -l vagrant -c 'git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build'
su -l vagrant -c 'echo export PATH="$HOME/.rbenv/bin:$PATH" >> ~/.bash_profile'
su -l vagrant -c 'echo eval "$(rbenv init -)" >> ~/.bash_profile'
#
# Install pyenv
#
su -l vagrant -c 'echo "# for Python" >> ~/.bash_profile'
su -l vagrant -c 'git clone https://github.com/yyuu/pyenv.git ~/.pyenv'
su -l vagrant -c 'echo export PYENV_ROOT="$HOME/.pyenv" >> ~/.bash_profile'
su -l vagrant -c 'echo export PATH="$PYENV_ROOT/bin:$PATH" >> ~/.bash_profile'
su -l vagrant -c 'echo eval "$(pyenv init -)" >> ~/.bash_profile'
#
# for ALL
#
su -l vagrant -c 'exec $SHELL -l'
#
# Install Bluemix CLI
#
su -l vagrant -c 'mkdir download'
su -l vagrant -c 'cd download;curl -s -O https://public.dhe.ibm.com/cloud/bluemix/cli/bluemix-cli/Bluemix_CLI_0.5.5_amd64.tar.gz'
su -l vagrant -c 'cd download;tar xzvf Bluemix_CLI_0.5.5_amd64.tar.gz'
su -l vagrant -c 'sudo ./download/Bluemix_CLI/install_bluemix_cli'
#
# for Docker and Bluemix CLI IC plugin
#
apt-get install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
apt-key fingerprint 0EBFCD88
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
apt-get update
apt-get install -y docker-ce
usermod -aG docker vagrant
#
# for docker-compose
#
curl -s -L -O https://github.com/docker/compose/releases/download/1.16.1/docker-compose-`uname -s`-`uname -m`
mv docker-compose-`uname -s`-`uname -m` /usr/local/bin/docker-compose
chmod a+x /usr/local/bin/docker-compose
#
# for Kubernetes CLI
#
curl -s -O http://storage.googleapis.com/kubernetes-release/release/v1.5.6/bin/linux/amd64/kubectl
mv kubectl /usr/local/bin
chmod a+x /usr/local/bin/kubectl
#
SHELL
end
config.vm.network "public_network", ip: "192.168.1.88", bridge: "en0: Ethernet"
この設定は、仮想マシンへ外部からアクセス可能なIPアドレスを付与します。 野良サーバーを生んでしまうかも知れませんが、MacやPCの仮想サーバー上に、一時的なサーバーを作るには、大変便利な機能です。
config.vm.network :forwarded_port, host: 3000, guest: 3000
仮想マシンのゲストOSのポート番号を ホスト(PC)のポート番号にマップします。 ここで立ち上げた Wordpress のサーバーをLAN上の他のサーバー、または、PCのブラウザからアクセスするために、ポートをマッピングすることで、コンテナが開いているサーバーポートにアクセスができます。
このあと、PHP,Python,Ruby, Node.js のツールの環境が続きます。 そして、Bluemix CLI, Docker, docer-compose, kubectlのインストールが続きます。
このファイルは、https://github.com/takara9/bluemix-dev においてあり、時々修正して、機能を追加していますので、ご注意願います。
停止、削除など
次のコマンドで、ダウンロードしたDockerイメージを全て削除して、消します。 しかし、mysql のデータ部分は、ホスト側のファイルシステムに存在していますから、もう一度 up すると、続きから利用できる様になります。
$ docker-compose down --rmi all
まとめ
k8sを使いこなすためには、やはり、Dockerを良く知って、有効に使える知識が必要なんだと思います。 そして、 Docker Hubには、公式イメージと称されるコンテナが登録される様になっており、いろいろな便利な機能を付け加えて、登録されています。 Docker Hub に登録されているコンテナを有効に活用しながら、ユーザーの満足度を上げる活動だできる様に、少しでも、力になれたら良いなぁと思っています。
参考資料
(1) Quickstart: Docker Compose and WordPress https://docs.docker.com/v1.10/compose/wordpress/