遡ること4年くらい前、はじめてこのblog、miscmemoの開設時にLinux上のdockerコンテナで始めたんだが、以来wordpressはちょこちょこアップグレードしていたものの、ベースとなるPHPはaptとかで管理していたわけではないこともあり、まったくアップグレードしてこなかった。
この度、ようやくアップグレードできたので、ここにその顛末とメモを記す。
最初のmomose.orgブログ開設-とその顛末_エントリにもあるように、 このblogのwordpressは公式のdocker imageを使っている。この公式のimageはphpのsourceをこのコンテナ内にDLしてきてそれをbuildしてインストールするようなことをしているので、コンテナ内でapt upgradeとかするわけにもいかない。したところでいろいろ公式イメージとは齟齬が生じそうだ。
ここはやはりdockerっぽく、imageをアップグレードしてコンテナを作り直すのが正しそうである。
ただ、wordpressは写真などのメディアファイルをアップロードすると、wordpressコンテナ内の/var/www/html/wp-content/uploads以下に置くので、コンテナを移行する前にこれをレスキューする必要がある。また、これらはblogのコンテンツ同様ずっと持っておくものなので、どこかホストのディレクトリにおいておいて、コンテナ起動時に-vでマッピングするのがよさそうである。
まずはメディアファイルディレクトリをレスキュー。momose-wordpressとすべきところがタイプミスで今日までmomose-worpressになっているのはご愛嬌。このおかげで新旧がくべつしやすくなって移行が少しやりやすくなった。次からどうしよう。
(host)$ docker cp momose-worpress:/var/www/html/wp-content/uploads wordpress-content-uploads
最新イメージの取得、旧コンテナの停止、新コンテナの起動
(host)$ docker pull wordpress
(host)$ docker stop momose-worpress
(host)$ sudo docker run --name momose-wordpress --link wp-mysql5:mysql -d -p 8080:80 -v /home/momose/wordpress-content-uploads:/var/www/html/wp-content/uploads wordpress
どうやらwp-config.phpはauthenticateのハッシュ値などが異なるようで、そのままでは使えなさそうな雰囲気。ここはブラウザから新しいコンテナに直接つないで設定し直したほうがよさそう。
あと使っていたプラグイン(Enlighter Inline CodeとPz-Link Card)を追加。こういうのも後で引き継げるような方策を考えたほうがいいかもしれない。
これで一応移行は出来たはず。本当はhttps化とかしておきたいところだが、どうにもうまくいかないので、これはまた後日。(ここに書き足すかもしれない)
追記(2023.06.15): https化成功
Apacheで、miscmemo用のSSL設定を書き、https://miscmemo. …の時は内部ネットワークのwordpressコンテナにreverse proxyするような設定をしていたのだが、今までうまく行っていなかった
- 本文はhttpsで通信しているっぽいが、呼び出している.js, .cssなどがhttpでリンクされているので、昨今のブラウザはそこら辺は読んでくれないっぽい。なので本文は表示されるが、cssとかが読まれないので表示が乱れまくる。
- URLに/loginを追加してログイン後に管理画面に入ろうとしても変なところに繋ごうとしてうまくログイン画面が出てこない
- とりあえずhttpでlogin画面に入り、「設定」→「一般」で”WordPressアドレス(URL)”をhttps://〜に変えて、httpでもhttpsでもloginしようとするとリダイレクトループが発生してにっちもさっちも行かなくなる。
- この症状が最初に出た時は設定画面に二度と入れなくなるので、mysqlコンテナに入って、直接この設定が入っているレコードを修正。その手順については秘密のノートで。
「wordpress https リダイレクトループ」でググると、以下の設定をwp-config.phpに入れると良いみたいなことが書いてあってほんまかいなと思いながらやってみるとうまく行った。ログインはもちろん、ページ全体のhttps化も。
define('WP_HOME', 'https://miscmemo.momose.org');
define('WP_SITEURL', 'https://miscmemo.momose.org');
$_SERVER['HTTPS'] = 'on';
本ブログ創設以来4年ほど経ってようやく懸案事項解決。か?
追記の追記(2023.06.18)
新container上のwordpressはv6ではlistenしているようだが、sslではlistenしていないので、v6ではsslではつながらないことになる。実際、http://[v6 address]は繋がるが、https://[v6 address]ではつながらない。が、v6共存networkにいても繋がっているのはsafariのhappy eyeballのおかげなんだろうか。
追記の追記の追記(2023.07.03) – IPv6 SSL化の件
前記の通り、当初の「IPv6は直にWordPressコンテナへ、IPv4は仕方がないので入り口でReverse Proxy」というのが、SSL化した場合にうまくいっていない感があったのだが、とりあえずWordPressコンテナもSSL化してみた。
- Let‘s Encryptでmiscmemo.momose.orgの証明書を取得
- certbotはmomose.org本体で動かしているので、証明書本体は momose.org:/usr/local/etc/letsencrypt に格納される
- WordPressコンテナからもこれを参照できるようにする
- momose.orgからはNFS exportし、Wordpressコンテナはこれをマウントできるようにする。
- が、これがどうやってもうまくいかない。ただでさえNFSは難しくて俺も苦手だというのを差し置いてもうまくいく気がしない。
- もう仕方がないので今回は丸ごとletsencryptディレクトリを固めて持ってきた。
- WordPressコンテナのSSL有効化
- WordPressコンテナではWeb serverとしてApacheが使われているのだが、configの書き方がいつものFreeBSDでやっているのと相当勝手が違う。いつものserverではhttpd.confはSSLも何も一個のファイルにしてしまって、秘伝のタレ状態になっているのだが、WordpressコンテナのbaseであるDebianでは/etc/apach2/以下に整然と分けられていて、サイトでサポートされているconfigがsite-available/に、有効にされているものがsite-enable/にあって、コマンドで有効無効を切り分けたりする。SSLの場合はsite-available/default-ssl.confなんてものがあるのだが、そんなことは知らんので、default-ssl.confをsite-enable/にコピーしてきてしまった。
- configの中のSSLCertificateFileは/etc/ssl/certs/ssl-cert-snakeoil.pem、SSLCertificateKeyfileが/etc/ssl/private/ssl-cert-snakeoil.keyを参照しているので、それぞれletsencryptのfullchain.pem, privkey.pemを指すようなシンボリックリンクを作る
あとはWordpressコンテナをrestart。再びコンテナのシェルでapt install iproute2をしてss -aで443をlistenしているかをチェック。
https://miscmemo.momose.org/ にアクセスして、コンテナのss -aでIPv6 SSLのセッションがあったかを確認する。
あとはconfigの設定を綺麗にしたり、ペンディングしているコンテナからFreeBSD NFS serverのマウント、接続した時にIPv6ならkameが踊る(でなくともなんかIPv6で繋がったよマーク)ような仕組みを作り込んでおきたい。
ところがどっこい、Let’s encrypt証明書のアップデートに失敗 (2023.09.09)
miscmemo.momose.orgの証明書がアップデートできないよ、あと一週間で切れちゃうよ、という警告メールが来た。certbotによる証明書の更新は、そのドメイン直下の.well-known/acme-challengeディレクトリにサインされたファイル名をtouchしておいて、Let’s encryptからそこのURL(この場合はhttps://miscmemo.momose.org/.well-known/acme-challenge/<signed file name>)にアクセスすることで確認するのだが、これはcertbotからfilesystem的に見えるところにないといけない。
今回https://miscmemo.momose.org/に来るときに、IPv6でまず来てしまうので、Containerの方に行ってしまうが、そこのDocumentRootのディレクトリはこのcertbotからは見えないので、結局認証に失敗してしまう。
なんとかアクセスをIPv4に強制できれば、momose.org内で完結するのだが、その方法はどうやらない。ので、一時的にDNS serverからmiscmemo.momose.orgのIPv6アドレスを外す。
momoseorg.dbの$TTLとSOAのMinimumと念のためにRefreshをそれぞれ3600から360(6分)にしてnamed再起動。1時間経った頃にmiscmemo.momose.orgからAAAAを外し、named再起動。6分後にcertbot renew。成功したら各パラメータを元に戻し、/usr/local/etc/letsencryptをtar.gzし、Dockerホストにscp、DockerホストからWordpress Containerの/tmpにdocker cp。/tmp/letsencrypt.tar.gzを/etcに展開、コンテナ再起動。古い/etc/letsencryptは消す。
これを3ヶ月ごとにやらなければいけないというのはなかなか辛い。
更に追記(2023.07.05) – 接続時にIPv4かIPv6かを表示
「ダッシュボード」→「外観」→「テーマファイルエディター」のfunctions.phpに以下を追加。add_shortcode()しておくと後で本文中で’[v4orv6]‘とか書いておくと、IPv4かIPv6かが表示できる。が、本文でそんなことする使いでがあるかどうかはわからない。
function v4orv6() {
$ip = $_SERVER['REMOTE_ADDR'];
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
// IPv4
return "IPv4[" . $ip . "]";
} else {
// IPv6
return "IPv6[" . $ip . "]";
}
}
add_shortcode('v4orv6', 'v4orv6');
template-parts → header → site-branding.php で、
$description = get_bloginfo( 'description', 'display' );
を
$description = get_bloginfo( 'description', 'display' ) . ' ' . v4orv6();
に変更。
これでblogのキャッチフレーズ欄のところにv4 or v6、および接続元アドレスが表示される。イマイチ格好はよくない。
こんなにテーマファイル弄り回ったら次バージョンアップがしにくいんじゃないか。