作成背景
複数のサービスを取り扱う職場で横断的に開発に参加しており、「〇〇システムの改修が終わったら△△システムの開発を進めてね〜〜」という感じでのオーダーが多い職場でした。サービスによっては複数のシステムが同一言語で複数のメジャーバージョンを使用しており、XAMPP をその度にインストールするなど、ローカルPCの開発環境が重くなったり、環境がPC上で散らかっちゃったりしている状況でした。
さらには複数のシステムを跨いだ動きを考えて開発をするものについては、AWSなどに頼ってインフラを構築しなければならないなと思う状況でした。
~~AWSを個々の開発環境として使っていたらお金もかかりすぎてしまうため、~~自分のクライアントPC内で環境が作れないかなといろいろ探していたところ、1年前にDockerと出会い、DockerでWebサービス環境をいい感じに作れるようでしたので、汎用的で職場でも使用しはじめている環境構成を公開したいと思います。
LEMP環境とは
LEMP環境とは、Webアプリケーションを開発するために使用するOS、Webサーバ、データベースサーバ、プログラミング言語を著した言語です。よく使われるWebサーバとして「Apache」が有名で、その頭文字をとって「LAMP」環境と呼ぶことが多く、聞いたことがある方もいるのではないでしょうか? 今回のLEMP環境も同じような考え方で、「E」は「Nginx(読み方:エンジンエックス)」の読みの頭文字の「E」をとっています。 - Linux(OS) - Nginx(Webサーバ) - MySQL / MariaDB(データベースサーバ) - PHP(アプリケーションサーバ(プログラミング言語))コンテナイメージの選定で必要なイメージなど
jwilder/nginx-proxy
複数のコンテナで同一のポートで通信したいときに入れておくと良いリバースプロキシサーバのコンテナイメージです。
1つのサービスで複数のドメインを同時に利用する場合があることから、上記のコンテナを立てておきます。
Alpine Linux
軽量なLinux OSで、よく使用しているUbuntuの1/7、CentOSでは1/40の容量で構成されているようです。
参考:@ryuichi1208さん「超軽量なAlpine Linuxについて調べた」
CentOS 約4GB
Ubuntu 約700MB
Alpine 約100MB
この汎用LEMP開発キットでは、コンテナ生成の際に時間のロスを減らすために、シンプルで軽量なOSであるAlpine Linuxのイメージをふんだんに採用しています。
ディレクトリ構成
Dockerを存在を布教するまで知らないエンジニアが多かったこともあり、新米エンジニアなどには「プログラムの改修だけなら、このディレクトリの中身だけをいじれば良い」といえるような、シンプルなディレクトリ構成にするように心がけました。
昨今トレンドになってきている「マイクロサービスアーキテクチャー」の考えを参考にしてNginx、MySQL/MariaDB、PHPをコンテナごとに分割しました。1
全体的なディレクトリ構成は下記のようになります。
project_root/
┣ data/
┃ ┣ html
┃ ┃ ┗ web-app/
┃ ┗ logs
┃ ┗ nginx/
┣ php-fpm/
┃ ┣ conf/
┃ ┃ ┗ php.ini
┃ ┗ Dockerfile
┣ nginx/
┃ ┣ conf.d/
┃ ┃ ┗ default.conf
┃ ┗ Dockerfile
┣ mariadb/
┃ ┗ docker-entrypoint-initdb.d/
┃ ┗ initial.sql
┣ phpmyadmin/
┃ ┗ config/
┃ ┗ config.inc.php
┣ env/
┃ ┣ .env
┃ ┗ その他環境変数のテンプレートファイル
┣ docker-compose.yml
┗ .gitignore
基本的に、インフラを整える必要のない方には原則「data」ディレクトリ直下のソースコードをいじっていただければ良いようにしています。
ディレクトリパス | 説明 |
---|---|
data/html | 各コンテナに設置するプログラムソースを格納( |
data/logs | 各コンテナのログファイルを出力 |
nginx | Nginxコンテナで使用する設定ファイルなどを格納しています |
mariadb | データベースコンテナで使用する設定ファイルなどを格納しています |
phpmyadmin | Webベースでデータベースを操作するためのツールで、独自の設定をする際に設定ファイルを格納します |
env | すべてのコンテナに共通する環境変数と各コンテナごとに挿入する環境変数のファイルを格納します。あくまでもこれは「テンプレート」のため、実際に環境変数を使用する場合は「.env」というディレクトリ名で複製して使うようにします(DockerキットをGitHubに登録するためにわざとしてます) |
Docker Compose
LEMP環境のコンテナを同時に生成できるように設定情報をdocker-compose.yml
に記載をしていきます。
version: '3'
services:
nginx-proxy:
image: jwilder/nginx-proxy:alpine
privileged: true
ports:
- 80:80
- 443:443
volumes:
- ./data/logs/nginx/nginx-proxy:/var/log/nginx
- /etc/nginx/vhost.d
- /usr/share/nginx/html
- /var/run/docker.sock:/tmp/docker.sock:ro
web:
image: nginx:alpine
env_file:
- ./.env/.env
environment:
- VIRTUAL_HOST=www.app.local
depends_on:
- app
volumes:
- ./data/html/app:/var/www/html
- ./nginx/web.conf:/etc/nginx/conf.d/default.conf
- ./data/logs/nginx/api:/var/log/nginx
app:
build:
context: .
dockerfile: ./php-fpm/Dockerfile
ports:
- 9000:9000
env_file:
- ./.env/.env
volumes:
- ./data/html/app:/var/www/html
- .env/app.env:/var/www/html/.env # 例えば、app.envという名前でアプリケーションの.envファイルとして、アプリケーション内のライブラリphpdotenvを用いて環境変数を読み取らせるようにする
db:
image: mariadb:latest
ports:
- 3306:3306
env_file:
- ./.env/.env
volumes:
- db-data:/var/lib/mysql
- ./mariadb/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
phpmyadmin:
image: phpmyadmin/phpmyadmin:latest
ports:
- 8080:80
env_file: ./.env/.env
environment:
- PMA_HOST=db
- PMA_USER=root
- PMA_PASSWORD=password
- PMA_BLOWFISH_SECRET=
depends_on:
- db
volumes:
- ./phpmyadmin/config/config.inc.php:/var/www/html/config.inc.php
volumes:
db-data:
Dockerfileについて
データベースコンテナ(MariaDB/MySQL)
基本的にチューニングを考えた作りにしていなかったので、データベースコンテナのDockerfileは存在しません。
コマンドベースでチューニングを行う場合は、Dockerfileを作成してやりましょう。
Webサーバコンテナ
基本的にチューニングを考えた作りにしていなかったので、データベースコンテナのDockerfileは存在しません。
コマンドベースでチューニングを行う場合は、Dockerfileを作成してやりましょう。
また、nginx/conf.d
ディレクトリ内には、コンテナ名ごとにnginxのconfファイルを格納しておくと、修正時にわかりやすくなります。
複数のWebサーバを動かす必要が出てきたときは、そのコンテナごとにconfファイルを/docker-compose.yml
のvolumes:
内に設定すれば、コンテナを切り分けて入れることも可能です。
アプリケーションコンテナ
PHP7.4以降では「oniguruma」という正規表現のモジュールがPHPに標準ライブラリとして搭載していないようです。(※ ドツボにはまる重要ポイントです!)
composerは、開発時は基本的に「ホスト側のcomposer」を利用してライブラリをインストールしていたので、コンテナ内では気持ち程度に入れております。
FROM php:fpm-alpine
RUN apk upgrade && \
apk update && \
apk add --update --no-cache \
oniguruma-dev \ # PHPバージョンが`<7.4`であれば、この行は不要です!
icu-dev && \
apk add \
vim \
git \
composer && \
docker-php-ext-install -j$(nproc) \
intl \
pdo_mysql \
mysqli \
mbstring
WORKDIR /var/www/html
使用コマンド
使用コマンドは下記の2つだけです。
docker-compose up -d
docker-compose down
また、コンテナがうまく立ち上がっているかの確認をするときのために、下記の2つのコマンドも覚えておくと便利です。
docker-compose ps
docker-compose logs | grep <CONTAINER_NAME>
最後に
今回は、Dockerを使った簡単で汎用的な開発環境構築キットの作り方を公開させていただきました。
実際のソースコードも公開させていただきますので、よかったら使用してみてください。
yusuke-shina/apache-httpd-docker-kit
*詳しいセットアップの仕方などをREADME.mdに記載できていませんが、記載できる隙が作れたら、更新していきます!
今回は、簡単で汎用的な開発環境構築キットという名目だったので(Dockerでのネットワーク構築については勉強中の身)ネットワーク周りの設定をDocker Composeを使って反映できていませんので、その辺とかも出来次第更新できたらと考えております。
具体的な説明があまりできていない雑な記事ではありますが、Dockerにこれから挑戦される方、開発環境をDocker化したいという方々のさわりとして、参考にしていただければ幸いです。
また、お詳しい方はコメント欄に認識が異なる部分がありましたらご指摘いただけると幸いです。
-
本当にこのやり方がマイクロサービスアーキテクチャの考え方に則しているかが怖いですが…… ↩