■ 概要
- Docker Compose は、Dockerのコンテナ管理ツール
- 複数コンテナの構築・管理を、設定ファイルと docker-compose コマンドで一括管理できて便利
- Docker for Mac には同梱されている
今回は、とりあえず最小構成(?)の WEBサーバーコンテナ + MySQLコンテナ で構築してみる
※MySQLのコンテナは、通常は公式のイメージを使用するが、今回は個別にDockerfileを指定する方法を試してみたかったので、あえて別途作成した。
■ 参考URL
■ フォルダ・ファイル構成
以下の構成で、設定ファイルや確認用コンテンツなどを用意する。
それぞれのファイルの記述例については後述。
※フォルダ構成は一例で、こうしなければいけないというわけではない。今回は、DBとWEBでフォルダを分けたほうがわかりやすいと思ったのでそうしている。
~/docker/compose-test
|
|-- docker-compose.yml
|
|-- db01/build/Dockerfile
| /data
|
|-- web01/build/Dockerfile
/conf.d/vhosts.conf
/public_html/index.html
/webapps/mytestapp/public/index.html
■ フォルダ・ファイル作成
前述の、想定するフォルダツリーにしたがって、フォルダ・ファイルを作成する
mkdir -p ~/docker/compose-test/db01/build
mkdir ~/docker/compose-test/db01/data
mkdir -p ~/docker/compose-test/web01/build
mkdir ~/docker/compose-test/web01/conf.d
mkdir ~/docker/compose-test/web01/public_html
mkdir -p ~/docker/compose-test/web01/webapps/mytestapp/public
# HTMLファイルの内容は適当に用意しておく
vi ~/docker/compose-test/web01/public_html/index.html
# 「this is public_html/index.html」とか書いておく
vi ~/docker/compose-test/web01/webapps/mytestapp/public/index.html
# 「this is webapps/mytestapp/public/index.html」とか書いておく
■ vhosts.conf を用意
WEBアプリケーションの設置先をMac側に用意してコンテナからマウントする想定なので、そのマウント先を VirtualHost として動かすためのApache設定ファイルを用意する。
このファイル自体もコンテナからマウントさせて、Apacheから読み込まれるようにする。
※ホスト名の「mytestapp.local」は、Mac の /etc/hosts の 127.0.0.1 の行に追加しておく
vi ~/docker/compose-test/web01/conf.d/vhosts.conf
NameVirtualHost *:80
<VirtualHost *:80>
ServerName localhost
DocumentRoot /var/www/html
ServerAdmin root@localhost
# DocumentRoot
<Directory "/var/www/html">
Options All
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
<VirtualHost *:80>
ServerName mytestapp.local
DocumentRoot /usr/local/webapps/mytestapp/public
ServerAdmin root@mytestapp.local
# DocumentRoot
<Directory "/usr/local/webapps/mytestapp/public">
Options All
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
■ docker-compose.yml
これが肝となる Docker Compose の設定ファイル。各項目の意味については後述。
version: '2'
services:
# db server ( mysql )
db01:
build: ./db01/build
image: miro/centos7db01:1.0
ports:
- "3306:3306"
volumes:
- ./db01/data:/docker-host/db01/data
environment:
MYSQL_ROOT_PASSWORD: root
tty: true
stdin_open: true
privileged: true
command: /sbin/init
# web server 01 ( apache )
web01:
build: ./web01/build
image: miro/centos7web01:1.0
ports:
- "80:80"
- "3000:3000"
links:
- "db01:db01"
volumes:
- ./web01/conf.d/vhosts.conf:/etc/httpd/conf.d/vhosts.conf
- ./web01/public_html:/var/www/html
- ./web01/webapps:/usr/local/webapps
tty: true
stdin_open: true
privileged: true
command: /sbin/init
「version: '2'」
設定の書き方にバージョンがあるらしい。2で良いかと。
「services:」
この配下に、コンテナを定義していく
「db01:」「web01:」
各コンテナの定義名なので、内容が分かるような名称を指定する。
「build:」
Dockerfile が置いてあるディレクトリのパスを記述。
配布されているイメージ(公式イメージなど)を取得する場合は指定不要
「image:」
イメージ名とタグ
「build:」を指定した場合は、この名前でイメージが作成される。
「build:」を指定しなかった場合は、ここに指定されたイメージを取得して構築する。
たとえば MySQL5.7の公式イメージを取得するなら、「image: mysql5.7」と指定し、「build:」は指定しない
「ports:」
ポートマッピングを指定。ホストのMac側からアクセスできるように指定している
「volumes:」
ディレクトリマウント。ホストのMac側からファイルを設置したり編集したりできるようにマウントしている
「environment:」
docker run の「-e」オプションに当たるもの。環境変数を指定できる。
「links:」
コンテナ同士の接続設定。上記の例だと、web01 から db01 というホスト名でMySQL側のコンテナへ接続できる
「tty: true」 と 「stdin_open: true」
docker run の「-it」オプションに当たるもの。これを指定しないと、コンテナを起動してもすぐ終了してしまうので注意
「privileged: true」
docker run の「--privileged」オプションに当たるもの。これを指定しないと、systemctl コマンドが使えないので注意
「command: /sbin/init」
docker run の引数として指定するコマンドに当たる部分。これを指定しないと、systemctl コマンドが使えないので注意
※ビルド後にコンテナにログインして systemctl コマンドを実行したときに以下のようなエラーが出る場合は、たいていは上記の「privileged: true」「command: /sbin/init」あたりが指定されていない。
「Failed to get D-Bus connection: Operation not permitted」
■ Dockerfile( db01 )
※MySQLのサーバーは、通常は公式のイメージを使用する。
その場合は、「image: 〜」に "mysql:5.7" 等の公式イメージを指定し、「build: 〜」は指定しない
今回は、個別にDockerfileを指定する方法を試してみたかったので、以下の通り別途作成した。
(参考) このDockerfile から単体でビルド&起動をテストする場合のコマンドは以下。
# ビルド
docker build -t miro/centos7mysql57:1.0 .
# コンテナ起動
docker run --privileged -it -d --name cent7mysql57 miro/centos7mysql57:1.0 /sbin/init
# 接続
docker exec -it cent7mysql57 bash
「db01/build/Dockerfile」
FROM centos:centos7
# Import the Centos-7 RPM GPG key to prevent warnings
RUN rpm --import http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-7
RUN rpm --import http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-7
# system update
RUN yum -y update && yum clean all
# set locale
RUN yum reinstall -y glibc-common && yum clean all
RUN localedef -f UTF-8 -i ja_JP ja_JP.UTF-8
ENV LANG ja_JP.UTF-8
ENV LANGUAGE ja_JP:ja
ENV LC_ALL ja_JP.UTF-8
RUN unlink /etc/localtime
RUN ln -s /usr/share/zoneinfo/Japan /etc/localtime
# ===============================================================================
# BASE packages
# ===============================================================================
RUN yum --enablerepo=extras clean metadata
RUN yum install -y zlib zlib-devel make gcc gcc-c++ openssl openssl-devel readline-devel pcre pcre-devel
RUN yum install -y openssh openssh-server
RUN yum install -y net-tools wget sudo
RUN yum install -y tar zip unzip bzip2 which tree
RUN yum install -y git
# ===============================================================================
# Install Applications
# ===============================================================================
# MySQL
RUN yum localinstall -y http://dev.mysql.com/get/mysql57-community-release-el7-7.noarch.rpm
RUN yum install -y mysql mysql-devel mysql-server mysql-utilities
# write to my.cnf
#RUN sed -i -e 's~datadir=/var/lib/mysql~datadir=/docker-host/data/mysql~g' /etc/my.cnf
# init mysql
#RUN mysqld --user=mysql --initialize
# enable mysql
RUN systemctl enable mysqld
■ Dockerfile( web01 )
(参考) このDockerfile から単体でビルド&起動をテストする場合のコマンドは以下。
# ビルド
docker build -t miro/centos7apache:1.0 .
# コンテナ起動
docker run --privileged -it -d --name centos7apache miro/centos7apache:1.0 /sbin/init
# 接続
docker exec -it centos7apache bash
「web01/build/Dockerfile」
FROM centos:centos7
# Import the Centos-7 RPM GPG key to prevent warnings
RUN rpm --import http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-7
RUN rpm --import http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-7
# system update
RUN yum -y update && yum clean all
# set locale
RUN yum reinstall -y glibc-common && yum clean all
RUN localedef -f UTF-8 -i ja_JP ja_JP.UTF-8
ENV LANG ja_JP.UTF-8
ENV LANGUAGE ja_JP:ja
ENV LC_ALL ja_JP.UTF-8
RUN unlink /etc/localtime
RUN ln -s /usr/share/zoneinfo/Japan /etc/localtime
# ===============================================================================
# BASE packages
# ===============================================================================
RUN yum --enablerepo=extras clean metadata
RUN yum install -y zlib zlib-devel make gcc gcc-c++ openssl openssl-devel readline-devel pcre pcre-devel
RUN yum install -y openssh openssh-server
RUN yum install -y net-tools wget sudo
RUN yum install -y tar zip unzip bzip2 which tree
RUN yum install -y git
# ===============================================================================
# Install Applications
# ===============================================================================
# Apache
RUN yum install -y httpd
# enable httpd
RUN systemctl enable httpd
■ ビルド&起動してみる
① ビルド&起動
docker-compose up -d
② 起動したか確認する
$ docker-compose ps
Name Command State Ports
-------------------------------------------------------------------------------------
composetest_db01_1 /sbin/init Up 0.0.0.0:3306->3306/tcp
composetest_web01_1 /sbin/init Up 0.0.0.0:3000->3000/tcp, 0.0.0.0:80->80/tcp
③ web01 にログインし、db01に疎通しているか確認する
$ docker exec -it composetest_web01_1 bash
[root@1d9e354ac39c /]# ping db01
PING db01 (172.18.0.2) 56(84) bytes of data.
64 bytes from composetest_db01_1.composetest_default (172.18.0.2): icmp_seq=1 ttl=64 time=0.165 ms
64 bytes from composetest_db01_1.composetest_default (172.18.0.2): icmp_seq=2 ttl=64 time=0.178 ms
# ↑ 通った!
④ Macのブラウザから、WEBサーバーのコンテンツにアクセスできるか確認
http://localhost/
↓
this is public_html/index.html
http://mytestapp.local/
↓
this is webapps/mytestapp/public/index.html
■ Docker Compose の基本操作
● ビルドと起動
docker-compose up -d
・初回起動時にビルドも実行される
・-d で、コンテナをバックグラウンドで実行
● コンテナの起動状態の確認
docker-compose ps
● 接続
docker exec -it コンテナ名
● コンテナの停止
docker-compose stop コンテナ名
※コンテナ名を指定しなければ、yamlに書かれた全コンテナが対象となる
● コンテナの削除
docker-compose rm コンテナ名
※コンテナ名を指定しなければ、yamlに書かれた全コンテナが対象となる
● コンテナの再起動
docker-compose restart コンテナ名
※コンテナ名を指定しなければ、yamlに書かれた全コンテナが対象となる