[WordPress] KUSANAGI Runs on DockerでLet's EncryptのSSL付きマルチサイトを立ち上げる
高速動作のWordPressサイトをDockerで楽々構築ができる「KUSANAGI Runs on Docker」。今回は、無料SSL・Let's Encryptを使ったHTTPSサイト化と、マルチサイト運用に対応させてみたいみたいと思います。
更新日: 2018.7.17公開日: 2017.8.29
テスト環境
まずは、サーバー環境です。
- サーバー: Google Compute Engine (fi-micro)
- OS: Container-Optimized OS
- Docker: version 1.13.1, build 092cba3
- docker-compose: version 1.13.0, build 1719ceb
Google Compute Engine (fi-micro)は、無料で使えるサーバーなので、「KUSANAGI Runs on Docker + Let’s EncryptのSSL + マルチサイト」を単純に試してみたいという方にもぴったりです。
また、Dockerで構築するので、既存の環境を極力汚さないでテストできます。ただし、比較的負荷がかかる作業なので、マシンスペックが低いとマシン全体が遅くなるので注意してください。
今回は、
- docker + docker-composeがインストールされている
- 443番ポートが解放されている
- 独自ドメインを持っている
- SSL登録用のメールアドレスを持っている
という前提で進めていきます。
構成
まずは、今回の構成です。
KUSANAGI Runs on Dockerの公式チュートリアルでは、一つのdocker-compose.ymlで管理していますが、今回は機能ごとにdocker-compose.yml分けました。
コンテナ構成
- nginx-proxy: Let’s EncryptのSSLを利用するためのプロキシサーバー
- mariadb: マルチサイトで共有するDBサーバー
- kusanagi-1: KUSANAGIサイト1の本体
- kusanagi-2: KUSANAGIサイト2の本体
ディレクトリ構成
-- nginx-proxy
- docker-compose.d/
- docker-compose.yml
-- mariadb
- docker-compose.yml
-- kusanagi-1
- data/
- docker-compose.yml
-- kusanagi-2
- data/
- docker-compose.yml
公開しているdocker-compose.ymlの記載について
{}で囲われた部分をそれぞれの環境に合わせて修正してください。
例えば、{ユーザーディレクトリ}であれば、ユーザー名のホームディレクトリを、{ドメイン名}であれば、登録するドメインを記入して使ってください。その際、{}は不要ですので、消してください。
dockerネットワークを作成する
docker-composeでは、個々の内部ネットワークを構築するので、別々のコンテナ群をリンクする場合には、共有ネットワークに参加させる必要があります。
今回は、common_linkというブリッジネットワークを構築します。(名前はなんでもOKです)
docker network create --driver bridge common_link
プロキシサーバー(nginx-proxy)コンテナを立ち上げる
次に、KUSANAGIの前でHTTP or HTTPSのアクセスをさばいて、さらにSSLの証明書設定までしてくれる便利なコンテナがあるのでそちらを立ち上げます。
KUSANAGIにはnginx & httpd機能が備わっているのですが、公開されているDockerコンテナは複数サイトをさばいたり、Let’s Ecryptの証明書を発行したりする機能がないので、別途立ち上げます。また、このコンテナだと、HTTPSサイトがある場合、自動でHTTPからHTTPSにリダイレクトしてくれる機能もあるので便利です。
なお、このコンテナにVMの80番、443番ポートをリンクします。そのため、後述のKUSANAGI用コンテナでのポート設定が公式のものと違ってくるのでコピペする際などに注意してください。
nginx-proxyディレクトリとdocker-compose.ymlを用意
mkdir nginx-proxy
cd nginx-proxy
//当サイトのファイルを使う場合 (自分で書いてもOKです)
wget https://repos.revdev.work/docker/kusanagi-ssl-multi/v1/nginx-proxy/docker-compose.yml
docker-compose.ymlを修正
vi docker-compose.yml
version: '2'
services:
nginx-proxy:
image: jwilder/nginx-proxy
container_name: nginx-proxy
privileged: true
ports:
- 80:80
- 443:443
volumes:
- /{ユーザーディレクトリ}/nginx-proxy/docker-compose.d/certs:/etc/nginx/certs:ro //修正してください
- /{ユーザーディレクトリ}/nginx-proxy/docker-compose.d/htpasswd:/etc/nginx/htpasswd //修正してください
- /etc/nginx/vhost.d
- /usr/share/nginx/html
- /var/run/docker.sock:/tmp/docker.sock:ro
restart: always
networks:
- common_link
letsencrypt-nginx:
image: jrcs/letsencrypt-nginx-proxy-companion
container_name: letsencrypt-nginx
privileged: true
volumes:
- /{ユーザーディレクトリ}/nginx-proxy/docker-compose.d/certs:/etc/nginx/certs:rw //修正してください
- /var/run/docker.sock:/var/run/docker.sock:ro
volumes_from:
- nginx-proxy
restart: always
networks:
- common_link
networks:
common_link:
external: true
用意ができたら、docker compose up -dで立ち上げます。
データベースサーバー(mariadb)を立ち上げる
さて、次はDBサーバーを立ち上げます。
本来は、KUSANAGIコンテナ群と一緒に立ち上げて、1サイトに1DBを用意したほうがいいのですが、データベースはリソースを食うので、今回は複数サイトで同じDBを使いまわします。
mariadbディレクトリとdocker-compose.ymlを用意
mkdir mariadb
cd mariadb
//当サイトのファイルを使う場合 (自分で書いてもOKです)
wget https://repos.revdev.work/docker/kusanagi-ssl-multi/v1/mariadb/docker-compose.yml
docker-compose.ymlを修正
vi docker-compose.yml
version: '2'
services:
mariadb:
container_name: mariadb
image: mariadb:10.0.24
environment:
MYSQL_ROOT_PASSWORD: {root用のパスワード(自由に決めてください。)} //修正してください
MYSQL_USER: {WordPress用のユーザーID(自由に決めてください。)} //修正してください
MYSQL_PASSWORD: {WordPress用のパスワード(自由に決めてください。)} //修正してください
MYSQL_DATABASE: wordpress
volumes_from:
- db-data
ports:
- "3306"
restart: always
networks:
- common_link
db-data:
container_name: db-data
image: busybox
restart: always
stdin_open: true
tty: true
volumes:
- /var/lib/mysql
command: /bin/sh
networks:
common_link:
external: true
docker-compose.ymlの修正が終わったら、docker-compose up -dで立ち上げます。
これでDBの設定ができました。
KUSANAGI WordPressサイト1(kusanagi-1)を立ち上げる
さて、いよいよKUSANAGIコンテナを立ち上げます。
ようやく作業の半分くらいまで来たところですが、ここからが作業も多く、重要な部分なので、あと少し落ち着いてがんばりましょう。
kusanagi-1ディレクトリとdocker-compose.ymlを用意
mkdir kusanagi-1
cd kusanagi-1
mkdir data
//当サイトのファイルを使う場合 (自分で書いてもOKです)
wget https://repos.revdev.work/docker/kusanagi-ssl-multi/v1/kusanagi-1/docker-compose.yml
docker-compose.ymlを修正
vi docker-compose.yml
version: '2'
services:
kusanagi-data:
container_name: {コンテナ名} //修正してください
image: busybox
restart: always
stdin_open: true
tty: true
volumes:
- /etc/nginx/conf.d
- /etc/httpd/conf.d
- /etc/kusanagi.d
- /{ユーザーディレクトリ}/kusanagi-1/data:/home/kusanagi
command: /bin/sh
kusanagi-nginx:
image: primestrategy/kusanagi-nginx:1.10.0-1
environment:
VIRTUAL_HOST: {ドメイン名} //修正してください
VIRTUAL_PORT: 443
VIRTUAL_PROTO: https
LETSENCRYPT_HOST: {ドメイン名} //修正してください
LETSENCRYPT_EMAIL: {管理者のメールアドレス名} //修正してください
LETSENCRYPT_TEST: "false"
PROFILE: {ドメイン名} //修正してください
FQDN: {ドメイン名} //修正してください
WPLANG: ja
BCACHE: "off" //自由に設定してください
FCACHE: "off" //自由に設定してください
volumes_from:
- kusanagi-data
links:
- kusanagi-php7:php
external_links:
- mariadb:mysql
ports:
- "443" //公式と違います
restart: always
networks:
- common_link
kusanagi-php7:
image: primestrategy/kusanagi-php7:7.0.6-1
external_links:
- mariadb:mysql
volumes_from:
- kusanagi-data
restart: always
networks:
- common_link
networks:
common_link:
external: true
修正ができたら、docker-compose up -dで立ち上げます。初回は、nginxのセキュリティ設定があるため時間がかかります。
マシンスペックにもよりますが、CPU負荷などが見れる環境であれば、CPU負荷が80%以上だったら、まだ立ち上げ途中の可能性があります。だいたい5分から10分で立ち上がりますので、負荷が落ち着くのを待ちましょう。
また、docker logsで経過を見ることもできます。
CPU負荷が落ち着いたあたりでhttps://ドメイン名にアクセスしてみると、ERROR画面(CONNECTION REFUSE)になるはずです。
これは、KUSANAGIの初期設定では、Let’s Encryptの認証に必要な.well-knowmnディレクトリにアクセスできないようになっているためで、「ドメインの所有者のサーバーか確認ができないから、証明書あげないよ」というエラーになっているのです。
実際、エラーログを見てみると、
docker logs letsencrypt-nginx
2017-08-29 05:31:25,197:ERROR:acme.challenges:311: Unable to reach http://example.com/.well-known/acme-challenge/AzaMHB_fLxEymOtE8a0aXNZ45wwBvlAiR9HDdaLLwSE: HTTPSConnectionPool(host='example.com', port=443): Max retries exceeded with url: /.well-known/acme-challenge/AzaMHB_fLxEymOtE8a0aXNZ45wwBvlAiR9HDdaLLwSE (Caused by SSLError(CertificateError("hostname 'example.com' doesn't match 'example.com'",),))
やはり、.well-known以下が見えてないのが原因でした。
では、今回は、DocumentRootファイルをすべてkusanagi-1/dataディレクトリにマウントしているので、.htaccessに下記を直接追記します。
vi kusanagi-1/data/ドメイン名/DocumentRoot/.htaccess
...
...
<IfModule mod_rewrite.c>
...
...
RewriteCond %{REQUEST_URI} !^/.well-known/acme-challenge/[0-9a-zA-Z_-]+$ //ここを追記
...
...
設定が終わったら、一度docker-compose stopでコンテナを停止して、再度docker-compose up -dでコンテナを起動します。
今度は、https://ドメイン名にアクセスすると、WordPressのDB設定画面になるはずです。
2017.9.9 追記
nginx-proxyの設定をみたところ、.well-knownディレクトリは別途nginx-proxy表示が出来るように対処されていました。ひょっとしたら、上記の処理をしないでもサーバー処理できていればSSL認証がされるのかもしれません。
ちなみに、Let’s Enctypt用の記述で、メアドなどは本物を使わないと下記のエラーが出てきます。
ACME server returned an error: urn:acme:error:invalidEmail :: The provided email for a registration was invalid :: Error creating new registration :: empty DNS response validating email domain - no MX/A records
きちんと正しいものを入れましょう。
KUSANAGI WordPressサイト2(kusanagi-2)を立ち上げる
基本的にサイト1を立ちあげた時と同じです。
ただし、docker-compose.ymlのファイル内で、下記のところは重複しないようにしましょう。
kusanagi-nginx:
image: primestrategy/kusanagi-nginx:1.10.0-1
environment:
VIRTUAL_HOST: ドメイン名
LETSENCRYPT_HOST: ドメイン名
PROFILE: ドメイン名
FQDN: ドメイン名
また、コンテナ名が重複するとエラーになるので、「kusanagi-data」のコンテナ名は個別につけてください。(kusanagi-1と同じデータコンテナを使う場合は別)
修正が終わったら、docker-compose up -dで立ち上げます。
相変わらず.well-knowmnでエラーになるので、一度docker-compose stopで停止して、.htaccessを修正して再度docker-compose up -dします。
<注意>
一つのデータベースを共有しているので、ブラウザでアクセスしてWordPressの設定画面が出たら、データベースの接頭文字をサイトごとに別々のものにするのも忘れずに。
実際に使ってみて
本サイトは、上記の設定でKUSANAGI Runs on Dockerで動いています。サーバースペックはf1-microというGCEの中でも最弱のサーバーですが(記事執筆時)、2000円くらいのVPSでノーマルWordPressを動かすのと同じくらいキビキビと動いてくれます。
DockerとKUSANAGI、GCPを使えばSSL付きマルチサイトでサクサクつくれますので、ぜひチャレンジしてみてください。