89
107

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Docker Composeで手軽に開発環境を構築 (PHP+MySQL+Elasticsearch+Memcached)

Last updated at Posted at 2016-09-11

やっと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/

ファイル構成

今回作成するファイル群は下記のようになります。

tree
.
|-- db
|   |-- init.d
|   |   `-- setup.sql
|   |-- Dockerfile
|   `-- my.cnf
|-- src
|   `-- yourgreatapp
|       `-- index.php
|-- web
|    |-- Dockerfile
|    `-- httpd.conf
`-- docker-compose.yml

※追記

すいません、この記事は少し古いです。
現在自分が考えるdocker-compose.ymlDockerfile、これらのディレクトリ構成のベストプラクティスは、こちらで紹介しています。

docker-compose.yml

まず、全体の構成を定義するdocker-compose.ymlを書きます。

プロジェクト名はyourgreatappという名前にしていますので、適宜置き換えて下さい。

docker-compose.yml
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は必要か分かりませんが、無いとエラーになる場合があるらしいので付けておきます。
  • buildvolumesdocker-compose.ymlからの相対パスなので気を付けて下さい。

ここからは、各コンテナの作成方法を書きます。

web

ApacheやPHPが乗っているサーバーです。

tree
|-- src
|   `-- yourgreatapp
|       `-- index.php
`-- web
    |-- init.d
    |    `-- setup.sh
    |-- Dockerfile
    `-- httpd.conf

web/Dockerfile

イメージの展開からインストールまで、このファイルがやってくれます。

基本的にコマンドの羅列なので分かりやすいですね。

COPYコマンドは、Dockerfileからの相対パスなので気を付けて下さい。私はdocker-compose.ymlからの相対パスだと思ってはまりました。

web/Dockerfile
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用の環境変数を与えています。

web/httpd.conf
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();で構いません。

src/yourgreatapp/public/index.php
<?php phpinfo();

※Gitのリポジトリ直下にdocker-compose.ymlを置いて、リポジトリ全部をDockerにマウントする方がスマートな気がしてきた

tree(模索中)
hogehoge/fugafuga.git
|-- public/index.php
|-- docker-compose.yml
`-- docker
   |-- web
   |  `-- Dockerfile
...

db

|-- db
   |-- init.d
   |   `-- setup.sql
   |-- Dockerfile
   `-- my.cnf

db/Dockerfile

MySQL用の環境変数をセットすることで、コンテナ作成時に自動的にデータベースやユーザーが作成されます。便利。

db/Dockerfile
FROM mysql:5.6

COPY my.cnf /etc/mysql

※最初、ここでMYSQL_DATABASEなどの設定をしていましたが、見通しを良くするためdocker-compose.ymlの方に移管しました。

db/my.cnf

普通のMySQLの設定です。現在稼働している開発サーバーから取ってくれば良いでしょう。

db/my.cnf
[mysqld]
default-storage-engine=InnoDB
character-set-server=utf8

db/init.d/setup.sql

webの時と同様に、/docker-entrypoint-initdb.dというディレクトリにシェルスクリプトやSQLを置いておくと、コンテナ起動時に実行してくれます。

db/init.d/setup.sql
GRANT ALL PRIVILEGES ON `yourgreatapp`.* TO 'yourgreatapp'@'%';

elasticsearch, memcached

開発用であれば、ElasticsearchとMemcachedは特に設定しなくても動くでしょう。

なので、docker-compose.ymlにイメージ使うよって書いておけば、あとはDockerがよしなにやってくれます。

docker-compose.yml(抜粋)
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を指定することで、分かりやすくコンテナ名を付けることができます。

docker-compose.yml
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

89
107
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
89
107

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?