c0d3man52

Webサイト制作

[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付きマルチサイトでサクサクつくれますので、ぜひチャレンジしてみてください。