AWS EC2上でDockerを使って複数のWordPressを動かす
AWSにWordPressを移行する 計画編の続きです。今回はEC2上でDockerを使ってWordPressを構築します。
Dockerについて
Dockerのコンテナは起動している間は変更したデータは残りますが、コンテナを消去すると失われますし、外部に持ち出すことができません。永続化したい変更はホスト内のディレクトリやファイルをbind mountするか、Dockerfileを使ってbuild時に適用する必要があります。
EC2にDockerをインストール
インスタンスにSSH接続し、以下のコマンドでDockerをセットアップします。ec2-userでdockerが実行できるようにdockerグループに追加しています。
sudo amazon-linux-extras install docker
sudo service docker start
sudo usermod -a -G docker ec2-user
docker-composeをインストールします。docker-composeを使うことで、dockerコンテナのビルドや起動が簡単になります。
sudo curl -L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
よく使うコマンド
docker-compose up -d
docker-compose.yamlのコンテナをまとめて起動するコマンドです。-dでバックグラウンドで起動します。
docker-compose stop
コンテナを停止するコマンドです。
docker-compose down
コンテナを停止して、消去します。
docker ps
実行中のコンテナを表示
docker-compose logs(docker logs コンテナ名)
コンテナのログを表示
docker system prune
使用していないコンテナやイメージの消去
サービスの構成
2つのWordPressで1つのMySQLを共有します。リバースプロキシで各WordPressへの接続を振り分けます。dockerにはjwilder/nginx-proxyというほぼ設定なしでnginxでリバースプロキシを建てれるイメージがあります。データベース管理用にphpMyAdminも入れておきます。VPSにdockerで複数サイトをホスティングするには?を参考に、共有サービス、2つのWordPressをそれぞれ別のディレクトリに作成していきます。
EC2のセキュリティグループの設定からポート80、443、8000(phpMyAdmin用)を解放しておきます。80、443はソースを任意の場所、8000はマイIPにするか、必要なくなったら閉じておきましょう。
共有サービス(nginx-proxy,MySQL,phpMyAdmin)のセットアップ
sharedディレクトリに以下のdocker-compose.ymlを設置し、docker-compose up -d
で起動します。
version: '3'
services:
nginx:
container_name: nginx_proxy
image: jwilder/nginx-proxy
ports:
- 80:80
- 443:443
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
# - ../lego/lego/certificates:/etc/nginx/certs
restart: always
logging:
options:
max-size: 5m
max-file: "10"
db:
image: mysql:5.7
volumes:
- ./mysql/data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: root_pass
MYSQL_DATABASE: wordpress_1
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress_pass
phpmyadmin:
image: phpmyadmin/phpmyadmin:latest
restart: always
ports:
- 8000:80
nginx-proxy
docker.sockをbind mountしておくことで、VIRTUAL_HOSTが設定されたコンテナの起動を感知して、自動で設定を追加、再起動してくれます。
/etc/nginx/certsに証明書のあるディレクトリをbind mountしておけば、SSL接続もできますが、CloudFrontを使う予定なのでコメントアウトしています。
MySQL
XSERVERのバージョンに合わせて5.7を使用していますが、新しいバージョンでも問題ないと思います。
データベースのデータはbind mountして、永続化しています。
MYSQL_DATABASE, MYSQL_USER, MYSQL_PASSWORDをしてすることで、root以外のユーザーも作成されます。このユーザーはMYSQL_DATABASEに対してのみフルアクセスがあるので、あとでphpMyAdminからrootでログインして、2つ目のWordPress用にdatabase 作成及び、権限付与が必要です。
CREATE DATABASE wordpress_2;
GRANT ALL PRIVILEGES ON wordpress_2.* TO wordpres@'%';
WordPressのセットアップ
どちらのWordPressもほぼ設定は同じです。WORDPRESS_DB_NAMEとVIRTUAL_HOSTが違うだけです。
version: '3'
services:
wordpress:
volumes:
- ./wordpress/wp-content:/var/www/html/wp-content
image: wordpress:latest
restart: always
environment:
WORDPRESS_DB_NAME: wordpress_1
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress_pass
VIRTUAL_HOST: example1.com
networks:
- front
networks:
front:
external:
name: shared_default
Networks
共有サービスと通信するため、networkに共有サービス(sharedディレクトリに作成)のdefaultネットワークを指定しています。docker-compose.ymlが別でも共通のネットワークを使うことでmysqlへはdbという名前で接続できます。
VIRTUAL_HOST
nginx-proxyでルーティングするためのhost名です。DNSの設定を変更するまではドメインではアクセスできないので、当面はAWSのパブリックDNSかIPを使ってテストします。
Volumes
インストールしたプラグインやテーマを保存するため、wp-contentをbind mountします。
ただし、そのままではパーミッションがうまく設定されず以下の問題が出ます。
- WordPressにはbind mountしたwp-contentには書き込み権限がない。
bind mountしたディレクトリはオーナーが元々ディレクトリを作成したユーザー(ec2-user)もしくはroot(コンテナ実行時にディレクトリが存在していなかった場合)です。コンテナ内のapacheの実行ユーザーはwww-dataで、両者とも異なるためディレクトリに書き込みができません。 - wp-content以下のファイルはec2-userから変更できない。
ファイルのオーナーはwww-data:www-dataなので、ec2-userからは直接変更できない。(sudoすれば可能。)
どちらかというと1の問題の方が困りますが、2もテーマの編集等をホストマシンから直接やろうとすると不便です。
解決方法1 ホストマシーンにグループ作成
ホストマシンにwww-dataグループ(GID:33)を作成し、ec2-userを追加。wp-content以下はオーナーをec2-user:www-dataに変更し、groupに書き込み権限を与える。
sudo groupadd -g 33 www-data
sudo usermod -aG www-data eu2-user
chown -R ec2-user:www-data wp-content
chmod -R 775 wp-content
解決方法2 コンテナにユーザー作成
コンテナ内にec2-userと同じ、UID=1000のユーザーを作成し、apacheの実行ユーザーに指定すします。buildディレクトリを作成し、以下のDockerfileをおきます。
FROM wordpress:latest
RUN groupadd -g 1000 docker
RUN useradd -m -u 1000 -g 1000 docker
RUN chown -R docker:docker /var/www/html
docker-compose.yamlをDockerfileからbuildするよう変更し、apacheの実行ユーザー指定のための環境変数を変数を追加します。
version: '3'
services:
wordpress:
volumes:
- ./wordpress/wp-content:/var/www/html/wp-content
build: ./build
restart: always
environment:
APACHE_RUN_USER: docker
APACHE_RUN_GROUP: docker
WORDPRESS_DB_NAME: wordpress_1
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress_pass
VIRTUAL_HOST: example1.com
networks:
- front
networks:
front:
external:
name: shared_default
上記のいずれかでアクセス権の問題は解消します。コンテナ内にユーザーを作成する方が、少し手間ですが、ポータブルで綺麗な解決方法でしょうか。
以上でWordPressのセットアップができました。次回はブログコンテンツの移行、ドメイン割当を行います。