というわけでVagrant上で動かしている開発環境をDockerに載せ替える方法……を書こうかなとも思ったんですけど、それほどやることはないのでメモ書き程度で。
目次
大雑把な流れ
- 移行したい環境の主なプログラムのバージョンを調べます。今回の場合PHPとMySQLのバージョンさえあってればあとは何とかなります。フレームワークに関してはソースを流用する関係上別にインストールするわけではないので問題ありません。
- 用意したいインスタンスごとにDockerfile用意します。今回は「公開用サイト」「管理用サーバ」「バッチサーバ」と3つのインスタンス用にDockerfileを用意しました。中身は「DOCUMENT_ROOT」が変わっているだけで他は同じです。Dockerfileで何をインストールしたら良いのかは環境によって変わるので、動かしながら調整していきます。
- docker-compose.ymlを用意します。今回は3つのインスタンスの他に「proxy」「DB」「redis」の3つのコンテナを設定しています。
$ docker-compose up --build -d
で正常に起動するようになれば完了です。
ハマりポイント
ドキュメントルートにアクセスすると「403 Forbidden」
ドキュメントルートの設定は、環境変数「APACHE_DOCUMENT_ROOT」にドキュメントルートを設定して、confファイルの該当部分を${APACHE_DOCUMENT_ROOT}
に書き換えるというのが常套手段です。ENV APACHE_DOCUMENT_ROOT /path_to_document_root/public
RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
でもこれだけだと足りない部分があるらしくPermission deninedになってしまいました。最終的に3行目を追加したら上手く動きました。
ENV APACHE_DOCUMENT_ROOT /path_to_document_root/public
RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf
最初よく解らなくてしばらく悩み、パーミッションのせいかなとかファイル所有者の問題かなとか色々試しましたが、今まで構築してきた環境では問題にならなかったので違うかなと。違いました。
シンボリックリンクが壊れる
インスタンス間で共通して使用しているライブラリをシンボリックリンクで設定していたんですが、Dockerではホスト側のシンボリックリンクが正常に読めないらしくライブラリが読み込めませんでした。困った。色んな対策を考えましたが、最終的に共通ライブラリをdocker-compose.ymlのvolumesに追加するように設定して解決しました。それならコピーする必要がないし簡単です。
環境変数HTTPSがonにならない
「proxy」サーバを立てているのは次の2つの理由からです。- ドメインでアクセス出来るようにする
- https://でアクセス出来るようにする
適切に設定してやると例えば以下のようなドメインでローカル開発環境にアクセス出来るようになります。
https://local.nplll.com
このとき何が起きているかというと、ブラウザからproxyサーバへはhttps(443ポート)で、proxyサーバから「公開用サイト」サーバにはhttp(80ポート)で接続しています。そのせいか「公開用サイト」のフレームワークはhttp://でアクセスしていると判断してしまうんですね。で、リダイレクトしてループするって言う。ダメじゃん。
環境変数HTTPSは上書きできるので、次の2つのファイルに「SetEnv HTTPS on」を追加すれば解決出来ます。
- /etc/apache2/sites-available/000-default.conf
- /etc/apache2/sites-available/default-ssl.conf
本番環境でそんなことしたらダメですが、どうせオレオレ証明書を使ってSSL通信してるローカル環境なので良しとします。動いたからヨシ!
docker-compose.yml(イメージ)
色々あるので細かい設定は変えていますが、イメージとしてはだいたいこんな感じです。version: '3'
services:
proxy:
image: jwilder/nginx-proxy
container_name: proxy
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./app/ssl:/etc/nginx/certs
restart: always
ports:
- 80:80
- 443:443
local_www:
image: local/www
container_name: www
build: ./www
restart: always
volumes:
- ../project/local:/home/webuser/local/
- ../project/model:/home/webuser/local/fuel/app/classes/model/
environment:
- VIRTUAL_HOST=local.hoge.com
- FUEL_ENV=local
- CERT_NAME=shared
local_admin:
image: local/local-admin
container_name: local-admin
build: ./local-admin
restart: always
volumes:
- ../project/local-admin:/home/webuser/local-admin/
- ../project/model:/home/webuser/local-admin/fuel/app/classes/model/
environment:
- VIRTUAL_HOST=adminlocal.hoge.com
- FUEL_ENV=local
- CERT_NAME=shared
local_batch:
image: local/batch
container_name: local-batch
build: ./local-batch
restart: always
volumes:
- ../project/local-batch:/home/webuser/local-batch/
- ../project/model:/home/webuser/local-batch/fuel/app/classes/model/
environment:
- FUEL_ENV=local
- CERT_NAME=shared
db:
image: mysql:5.6.51
container_name: local-db
volumes:
- ./db/data:/var/lib/mysql
restart: always
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=local
- MYSQL_USER=user
- MYSQL_PASSWORD=pass
ports:
- 13306:3306
redis:
image: redis:latest
container_name: local-redis
ports:
- 6379:6379
volumes:
- ./redis/data:/data
restart: always
まとめ
そんなの大変すぎて出来ないだろうと昔は諦めてたんですけど、人間慣れればいろいろ出来るようになるもので出来ちゃいました。掛かった時間は5時間ぐらいかな。休日の暇つぶしにはちょうどよかったです。考えてみれば今参画しているプロジェクトの開発環境もなんかスゲー雑に振られてなんのアドバイスもなかったんですけど、ソースコード読んで環境予想してDockerで開発環境作れちゃいましたし、やればできるもんです。というか僕がすごいんじゃなくてDockerがすごいです。間違いなく。ほとんど設定するところなんかないんですからね。ダメだったときに対処すれば良いだけで。
素晴らしい時代です。最高。