Docker開発環境の構築(Webサービス向け)

DockerでWebサービスの開発環境を構築する手順は、ソフトウェア・ネットワークの設定が中心となります。
必要なツールのセットアップは各OS用のDockerをインストールするだけでひと通り揃いますが、インストール後はとくにガイドがなく各自で環境を設計する必要があります。

Docker Composeで複数コンテナを構築する

多くのWebサービスは、RDBMS(MySQL・PostgreSQLなど)、Webサーバー(Apache・nginxなど)、アプリサーバー(PHP・ruby・python・Javaなど)の3層構造になっています。
そのため、Webサービス向けのDocker開発環境も、複数のコンテナ間で通信する構成を作ります(図参照)。

複数dockerコンテナの開発環境

図のとおり、基本的な設定は docker-compose.yml に記載します。コンテナ群を一括操作するdocker-composeコマンドは、カレントディレクトリからこのファイルを探して参照します。
複数のプロジェクトを作成する際は、別のディレクトリにdocker-compose.ymlを作成しカレントディレクトリを移動するだけで、環境を手軽に切り替えられます。

docker-compose.ymlの設定例

Webサービス向けのコンテナ設定例は、以下のような記述になります。YAML形式の設定ファイルはインデント幅(スペースの数)も意味を持つので注意してください。

version: '2'

services:
  app:
     image: php:7.0-apache
     ports:
       - "80:80"
       - "443:443"
     depends_on:
      - "mysql"
     environment:
       DB_NAME: somepj_dev
       DB_HOST: somepj_mysql_1
     volumes:
       - $DOCKER_PATH/somepj:/var/www/html/
  mysql:
    image: mysql:5.7
    ports:
      - "3306:3306"
    volumes:
      - $DOCKER_PATH/somepj-data/:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: some-root-password

networks:
  default:
    external:
      name: somepjnet

この作例では、PHP環境の例として、appとmysqlという2つのコンテナを設定しています。PHPの公式イメージにはApache上で動作するPHP環境があるため、Web+AppとDBMSの2層構造をとっています。

複数コンテナの構成で重要なのは、appサーバーからmysqlサーバーに接続する部分を理解することです。

dockerは内部ネットワークを定義することで、コンテナ間をホスト名で接続できます。
内部ネットワークの定義は、先ほどの設定後半networksブロックの部分で指定しています。

指定するネットワーク(この例ではsomepjnet)はコンテナ起動前に一度

$ docker network create somepjnet

といったコマンドで作成しておく必要があります( dockerのネットワーク設定で解説)。

この設定により、各コンテナは somepj_app_1, somepj_mysql_1 といった名前で動作します(コンテナ起動後であれば、docker container lsコマンドで確認できます)。
名称はアンダースコアで区切られており「カレントディレクトリ名_コンテナ名_コンテナ番号」というルールになっています。

ホスト名が決まれば、フレームワークごとのDB設定ファイルに somepj_mysql_1 などを指定すれば接続できるはずです(Dockerの手順ではなく、各Webフレームワークの手順です)。

先ほどの設定例では、environmentディレクティブを利用して、環境変数DB_HOSTにこのホストを指定しています。環境変数を介した設定のメリットは、コンテナの設定で起動時に接続先を切り替えられることです。

その他、各ディレクティブの詳細については、公式ドキュメントを参照してください。

volumeを利用してコードをPC上で編集

今回のケースでは、アプリケーションのソースコードをappホストのvolumesディレクトリで参照しています。
/var/www/html はphp:7.0-apacheイメージのドキュメントルートになっているため、ドキュメントルート以下のファイルを直接編集できるのと同じ効果があります。

PHPの場合はファイルの変更により、そのままアプリの挙動が変わるためPC上のファイルを変更してブラウザを更新すれば新しいコード部分を即時確認できます。
portsディレクティブで80:80と443:443を指定しているため、http://localhost/でアクセスできます。httpsもアクセス可能ですが、証明書設定を完結できないためエラーになるでしょう)

docker-composeの変数指定について

先ほどのdocker-compose.ymlに記載した$DOCKER_PATHは、同じディレクトリにある.envファイルで設定した変数を参照しています。
.envは以下のように、シェルスクリプトと同様の形式で変数を定義できます。

DOCKER_PATH=/home/some_user/docker

dockerの設定では、volumeを通じてPC上のファイルを直接利用したいケースが多々あります。このようにトップディレクトリを変数化しておくことで、複数のユーザー間で開発コンテナ設定を共有するケースでも各自の置き場所を設定するだけで動作する環境を作れます。

なお、docker-composeには env_fileという機能もありますが、これはコンテナ上の環境変数をコンテナ間で共通指定する機能で目的は異なります。

まとめと関連するセットアップ

docker-composeをセットアップすることで、複数コンテナを相互に通信可能な状態で一括起動できます。

ここまでの段階では、まだDBデータが空の状態であるためデータロードする必要があります。論理バックアップからのリストアなど、コンテナ上のDBMS手順については『 Dockerでデータベースを実運用』を参照してください。

また、前提ライブラリのインストールなど実行環境のカスタマイズについては、イメージビルドのうえimageディレクティブで指定します。共有イメージのビルド例は、『 Docker HubのAutomated Build』で解説しています。

中馬崇尋
Chuma Takahiro