やっとDockerに入門しました。
社内のシステムは古典的なLAMP環境で動いているので、その開発環境をDocker Composeで作りなおしたメモ。
作成したファイルは、下記に置いてあります。
設定ファイルを作ってしまえば、下記のコマンドですぐに開発を開始することができ、楽です。
git clone https://github.com/acro5piano/docker-lamp-elasticsearch.git
cd docker-lamp-elasticsearch
docker-compose up
[追記]
今だったらこうする。DockerHubフル活用して、できるだけ楽に構築する。
[/追記]
Dockerについて
Dockerは、開発環境を手軽に構築するツールです。
ApacheやMySQLなどのミドルウェアをコンテナと呼ばれる仮想環境上に構築し、それらを連携させて動作させます。
VagrantやXenなどの仮想化ツールと異なるのは、このコンテナそれぞれが一つのミドルウェアとして機能することです。
Vagrantだと、1つのOSの上に各ミドルウェアインストールしておき、それをBoxとしてイメージ化しますよね。
Dockerの場合、例えば
コンテナ | ミドルウェア |
---|---|
Webコンテナ | Apache2.2、 PHP5.5 |
DBコンテナ | MySQL5.6 |
Elasticsearchコンテナ | Elasticsearch1.3 |
Memcachedコンテナ | Memcached |
といった具合に、各コンテナを別々に構築していき、それらをリンクさせるという形で開発環境を作ります。
今回はこの古典的なLAMP+Elasticsearchという構成を作っていきます。
Docker Composeについて
従来はDockerのコンテナはそれぞれ別々に起動・管理する必要があったのですが、Docker Composeというツールによってコンテナ群をひとまとめにして管理する手法ができました。
Docker Composeの公式ドキュメントはこちらです。インストールなどはこちらで。
https://docs.docker.com/compose/
ファイル構成
今回作成するファイル群は下記のようになります。
.
|-- db
| |-- init.d
| | `-- setup.sql
| |-- Dockerfile
| `-- my.cnf
|-- src
| `-- yourgreatapp
| `-- index.php
|-- web
| |-- Dockerfile
| `-- httpd.conf
`-- docker-compose.yml
※追記
すいません、この記事は少し古いです。
現在自分が考えるdocker-compose.yml
、Dockerfile
、これらのディレクトリ構成のベストプラクティスは、こちらで紹介しています。
docker-compose.yml
まず、全体の構成を定義するdocker-compose.yml
を書きます。
プロジェクト名はyourgreatapp
という名前にしていますので、適宜置き換えて下さい。
version: '2'
services:
web:
build: ./web
ports:
- "8000:80"
- "3000:3000"
links:
- db
- memcached
- elasticsearch
volumes:
- ./src/yourgreatapp/public:/var/www/yourgreatapp/public
db:
build: ./db
environment:
MYSQL_ROOT_PASSWORD: ROOT_PASSWORD
MYSQL_DATABASE: yourgreatapp
MYSQL_USER: yourgreatapp
MYSQL_PASSWORD: yourgreatapp
MYSQL_HOST: ""
mem_limit: 1000000000
volumes:
- ./db/init.d:/docker-entrypoint-initdb.d
ports:
- "33333:3306"
elasticsearch:
image: "elasticsearch:1.3"
memcached:
image: memcached
各項目の説明
ポートやディレクトリをマッピングする際は、「ホスト側:ゲスト側」という書き方をします。
項目 | 説明 |
---|---|
build | コンテナの作成をするワークスペースの指定。Dockerfileがある場所 |
ports | ホスト側のポートとコンテナ側のポートのマッピング |
links | コンテナ間の通信を定義。実際は/etc/hostsにコンテナ名とIPアドレスの名前解決が書かれる |
volumes | ホストとコンテナで共有するディレクトリ |
environment | 環境変数 |
注
- DBのMYSQL_HOSTは必要か分かりませんが、無いとエラーになる場合があるらしいので付けておきます。
-
build
やvolumes
はdocker-compose.yml
からの相対パスなので気を付けて下さい。
ここからは、各コンテナの作成方法を書きます。
web
ApacheやPHPが乗っているサーバーです。
|-- src
| `-- yourgreatapp
| `-- index.php
`-- web
|-- init.d
| `-- setup.sh
|-- Dockerfile
`-- httpd.conf
web/Dockerfile
イメージの展開からインストールまで、このファイルがやってくれます。
基本的にコマンドの羅列なので分かりやすいですね。
COPYコマンドは、Dockerfile
からの相対パスなので気を付けて下さい。私はdocker-compose.yml
からの相対パスだと思ってはまりました。
FROM centos:6
RUN rpm -ivh http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm
RUN rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm
RUN yum install -y httpd
RUN yum install --enablerepo=epel,remi-php55,remi -y \
php \
php-cli \
php-gd \
php-mbstring \
php-mcrypt \
php-mysqlnd \
php-pdo \
php-xml \
php-xdebug \
php-memcached
RUN sed -i -e "s|^;date.timezone =.*$|date.timezone = Asia/Tokyo|" /etc/php.ini
COPY httpd.conf /etc/httpd/conf.d/yourgreatapp.conf
EXPOSE 80
CMD ["/usr/sbin/apachectl", "-D", "FOREGROUND"]
web/httpd.conf
普通のApacheの設定です。会社でFuelPHPというフレームワークを使っているので、SetEnvでDocker用の環境変数を与えています。
NameVirtualHost *:80
<VirtualHost *:80>
ServerName docker-compose-lamp.dev
DocumentRoot /var/www/yourgreatapp/public
<Directory /var/www/yourgreatapp/public>
Options Indexes FollowSymLinks MultiViews
AllowOverride all
Order allow,deny
allow from all
</Directory>
SetEnv FUEL_ENV development_docker
</VirtualHost>
src/yourgreatapp
開発対象のプログラムを置く場所です。index.phpの中身は<?php phpinfo();
で構いません。
<?php phpinfo();
※Gitのリポジトリ直下にdocker-compose.yml
を置いて、リポジトリ全部をDockerにマウントする方がスマートな気がしてきた
hogehoge/fugafuga.git
|-- public/index.php
|-- docker-compose.yml
`-- docker
|-- web
| `-- Dockerfile
...
db
|-- db
|-- init.d
| `-- setup.sql
|-- Dockerfile
`-- my.cnf
db/Dockerfile
MySQL用の環境変数をセットすることで、コンテナ作成時に自動的にデータベースやユーザーが作成されます。便利。
FROM mysql:5.6
COPY my.cnf /etc/mysql
※最初、ここでMYSQL_DATABASEなどの設定をしていましたが、見通しを良くするためdocker-compose.yml
の方に移管しました。
db/my.cnf
普通のMySQLの設定です。現在稼働している開発サーバーから取ってくれば良いでしょう。
[mysqld]
default-storage-engine=InnoDB
character-set-server=utf8
db/init.d/setup.sql
webの時と同様に、/docker-entrypoint-initdb.d
というディレクトリにシェルスクリプトやSQLを置いておくと、コンテナ起動時に実行してくれます。
GRANT ALL PRIVILEGES ON `yourgreatapp`.* TO 'yourgreatapp'@'%';
elasticsearch, memcached
開発用であれば、ElasticsearchとMemcachedは特に設定しなくても動くでしょう。
なので、docker-compose.ymlにイメージ使うよって書いておけば、あとはDockerがよしなにやってくれます。
elasticsearch:
image: "elasticsearch:1.3"
memcached:
image: memcached
起動
ここまできたら、あとは起動するだけです。
docker-compose.ymlがあるディレクトリで
docker-compose up
というコマンドを入力して下さい。
各コンテナのビルドが始まり、数分後には環境が立ち上がっているはずです。
うまくいけば、localhost:8000をブラウザで開けば、Docker内部で動いているPHPにアクセスできるはずです。
何か設定ファイルが間違っていて、やり直したい場合は
docker-compose build
でコンテナが再度作りなおされます。
コンテナ内のデータは基本的にコンテナを終了させると消えますが、mysqlのコンテナは予め永続化の処理がされているので消えません。
データを一から作り直したい場合は、
docker-compose down
とすれば消えます(多分)。
便利コマンド
コンテナの稼働状況を確認
こんな感じで、各コンテナの状態が分かります。
docker-compose ps
Name Command State Ports
--------------------------------------------------------------------------------------------------------------
docker_db_1 docker-entrypoint.sh mysqld Up 0.0.0.0:33333->3306/tcp
docker_elasticsearch_1 /docker-entrypoint.sh elas ... Up 9200/tcp, 9300/tcp
docker_memcached_1 docker-entrypoint.sh memcached Up 11211/tcp
docker_web_1 /usr/sbin/apachectl -D FOR ... Up 0.0.0.0:3000->3000/tcp, 0.0.0.0:8000->80/tcp
コンテナの稼働状況を確認(全部)
複数サービスをdocker-compose
で動かしている場合、docker ps
で全サービスのコンテナを確認できます。
コンテナの内部でコマンドを実行
docker exec -it docker_web_1 bash
ここで指定しているdocker_web_1というのは、docker-compose ps
で調べた名前(コンテナ名)と同一です。
bashを実行すると、SSHのようにシェルに入ることができます。
docker_web_1という名前が分かりにくければ、docker-compose.yml
の中に、container_name
を指定することで、分かりやすくコンテナ名を付けることができます。
web:
container_name: some-web
こうすると、docker exec -it some-web bash
として実行できます。
※下記の記事で、docker-compose exec web <command>
という方法が紹介されていました。Docker Composeに限ってはこっちの方がいいですね。
MySQLのコンソールに接続
mysql -u yourgreatapp -p yourgreatapp -D yourgreatapp -h 127.0.0.1
ホストに127.0.0.1を指定するのがポイントで、指定しないとlocalhostにUnixソケット経由で接続しに行ってしまいます。これも少しはまりました。
※MySQLコンテナから接続する方が良いですね。ホスト側にMySQLクライアントを入れる必要が無いですし、ポートも塞ぎません。
`docker-compose run db mysql -u root -pROOT_PASSWORD -D yourgreatapp
エイリアス
docker-compose
は頻繁に叩くので、
alias dc='docker-compose'
とすると幸せになれます。これにより、
dc run web php /var/www/app/composer.phar update
と、ホスト環境で実行するのと同じような感覚でコマンドを実行できます。Dockerはデータが永続化せず、Historyが残らないので、できるだけホスト側でコマンドを実行したほうが良いです。
まとめ
なんだか長くなってしまいましたが、これらのファイルを作っておけば
- 一瞬で開発環境作れる
- 起動早い、動作軽い
- 開発環境を変更したら、それをGitにコミットするだけでチーム全員に共有できる
-
どうせ誰にも読まれない導入手順書を書く手間が無い
などのメリットがあります。
PHPのビルトインサーバーとか使えば、docker-compose.yml
単体で全部構築できそうな気がしてきました。今度それ記事にします。
参考
PHPのコンテナを構築する部分は、下記の記事をほとんど丸パクリです。ありがとうございましたm(_ _)m