当ブログもそうですが、私はWordPressでブログを建てることがあります。ブログを作っては破壊する事が多くて、なんでかというと長続きしないからなんですが一々構築するのがいい加減面倒になってきました。 はてなブログとか使えばいいじゃんという話はあるのですが、あのブログどこのサービスで書いたっけ…忘れた、もういいや。みたいな経験を既に学生の頃しきっているのでもう良いです。
本題ですが、たくさんのブログを作ろうと思った時にWordPressをインストールしたりnginxの設定を変えるのはまあまだ出来るとしても、HTTPS化したりするのは面倒です。Let’s Encryptという素晴らしいプロダクトがあるのでよっぽど楽になったのですが、もっと簡単にやれる方法がありそうなので考えてみたのがこの記事です。
dockerでSSL証明書を取得する
さっきも出ましたが、Let’s Encryptという無料でSSL証明書を発行してもらえるサービスが有ります。これを使って今までもSSL証明書を取得していました。 docker化する知見を探し始めてすぐに、もう既にdocker化されていることを知りました。
SteveLTN/https-portal: A fully automated HTTPS server powered by Nginx, Let’s Encrypt and Docker.
便利。まずはQuickStartをやってみると
https-portal:
image: steveltn/https-portal:1
ports:
- '80:80'
- '443:443'
links:
- wordpress
restart: always
environment:
DOMAINS: 'wordpress.example.com -> http://wordpress'
STAGE: 'production'
# FORCE_RENEW: 'true'
wordpress:
image: wordpress
links:
- db:mysql
db:
image: mariadb
environment:
MYSQL_ROOT_PASSWORD: '<a secure password>'
こんなdocker-compose.ymlを書きます。 wordpress.example.com
をこのdocker-compose.ymlを設置するサーバのIPを引けるように別途設定したりする必要はありますが、たったこれだけでHTTPS化済みのWordPressが手に入ります。便利すぎる。
FORCE_RENEWは場合によってはtrueにしておく必要がありますが上記例ではコメントアウトしておきます。なんでかというとLet’s Encrypyでは証明書の更新は週5回までなのでガンガン docker-compose down
docker-compose up -d
とかするとあっという間に上限まで行きます。僕は目的のものを手に入れる過程で1回やらかしました()
複数ブログを運営することを考える
この構造だと、1つしかブログを運営できません。 wordpress
セクションをコピペして増やしても良いんですが、1ファイルで複数のブログを管理するのがどうも僕には気持ち悪く思えたのでファイル構造をこのようにしました。
+-----------------+
| |
| https-portal |
| |
| |
++---------------++
| |
| |
| |
| |
+----+----+ +----+----+
| | | |
| Blog1 | | Blog2 |
| | | |
+---------+ +---------+
こんな感じ。各枠ごとに docker-compose.yml
を分けます。こうすることで、BlogだけじゃなくていろんなサービスをHTTPS化できるんじゃないかな。
実際に構築する
実際にじゃあどう構築するんだっていう話をしていきます。
https-portal
version: '3'
services:
https-portal:
image: steveltn/https-portal:1.0.0
ports:
- '80:80'
- '443:443'
restart: always
environment:
DOMAINS: 'www.blog1.com -> http://blog1_wordpress, www.blog2.com -> http://blog2_wordpress'
STAGE: 'production'
FORCE_RENEW: 'true'
networks:
- default
- blog1_default
- blog2_default
networks:
blog1_default:
external: true
blog2_default:
external: true
DOMAINSには複数指定することができます。 networksで他のdocker-composeで作ったdockerのネットワークに接続します。試してないんですが、こうしておくと接続先のネットワークを先に作っておく必要があるんですかね。そんな気がします。構造は雑な図ですがこんなかんじ。
-- root
|
|---docker-compose.yml
----blog1---wordpress
| |
| --docker-compose.yml
|
----blog2---wordpress
|
--docker-compose.yml
blog1を作る
version: '3'
services:
blog1_wordpress:
image: wordpress
container_name: blog1_wordpress
depends_on:
- db
volumes:
- ./wordpress:/var/www/html
links:
- db:mysql
env_file: .env
db:
image: mariadb
environment:
MYSQL_ROOT_PASSWORD: 'LOOOOOONGPASSWORD'
volumes:
- blog1-db-volume:/usr/lib/mysql
env_file: .env
volumes:
blog1-db-volume:
driver: local
volumesで ./wordpress
をマウントしているのは、僕がこの構造に移行する時にファイルを丸っとコピーしたかったからなので無くてもいいです。データベースの永続化も行っています。このdocker-compose.ymlがあるディレクトリとDBのボリュームをバックアップすれば簡単にブログのバックアップとれますね。
.env
も使っていて、下記のような感じ。
WORDPRESS_DB_NAME=wordpress
WORDPRESS_DB_USER=wp_user
WORDPRESS_DB_PASSWORD=LONGLONGPASS
MYSQL_RANDOM_ROOT_PASSWORD=yes
MYSQL_DATABASE=wordpress
MYSQL_USER=wp_user
MYSQL_PASSWORD=LONGLONGPASS
.env
は便利ですが平文なのであんまりおすすめできる手段ではないですね。まあ、DBへの接続情報は wp-config.php
にも記述されてるんですが。平文で。
この .env
のパーミッションはよく考えたほうが良いかも。もしくは別の手段を使うべきですが、ブログで記事にする上で楽なのでこんな感じにしてます。
blog2を作る
ほとんどblog1と同じ。別のディレクトリに同じようにdocker-compose.ymlとwordpressディレクトリを作ります。
version: '3'
services:
blog2_wordpress:
image: wordpress
container_name: blog2_wordpress
depends_on:
- db
volumes:
- ./wordpress:/var/www/html
links:
- db:mysql
env_file: .env
db:
image: mariadb
environment:
MYSQL_ROOT_PASSWORD: 'LOOOOOONGPASSWORD'
volumes:
- blog1-db-volume:/usr/lib/mysql
env_file: .env
volumes:
blog2-db-volume:
driver: local
使い方
まず各ブログでdocker-compose up -dして、最後にrootディレクトリに置いたdocker-compose.ymlでdocker-compose up -dするといいです。すると、設定した各URLにアクセスするとHTTPS化されたwordpressが見えると思います。 たくさんブログを運営する必要がある人とかは便利かもしれない。僕はもうLet’s Encryptの証明書更新がこけてるとかで悲しい思いをしなくて済むだけで十分。