出来心でこのblogをホストしているubuntuをアプリ込みでupdateしたら、Wordpressがすっかり動かなくなってしまい、色々やり直した話。
このblogをホストしているubuntuにloginしたら色々updateが溜まっていたようなので、気楽にupdateしてみた。するとここのwordpressが動かなくなった。どうも無理やりroutedで動かしていたのが動かなくなっていた。
今まではNATをしないためにiptablesをdisableにして、host側にrouting設定を入れておけばcontainerに対してもL3 routingしてくれてたのだが、どう設定してもそれがうまくいかなくなっていた。NATしない時はiptableやめちゃえって書いてあったはずの公式ドキュメントもない。いつの頃からかよく見るとiptablesのchain項目に’DOCKER xxx’というのが増えている。ここに設定している内容はiptables -Fとかでは全部消えないようで、iptables=falseとかしてもうまく動かない。chatgptが
どうやら新たに独自にrouted typeのbridge(network)を作ると、iptables他の設定はいじらずに通常のL3 networkはしてくれるっぽい。ただ、現在動いているコンテナのネットワーク設定は変えられないので、改めてcontainerを作るところから始めなきゃ行けないようだ。
とりあえず現在稼働中のやつのimageをとっておかねばというところで、mysql、wordpressのimageをcommitしておく
$ sudo docker commit momose-wordpress miscmemo-wordpress-latest:20240818 sha256:495adc56fa9dbd1cda8c969f7ab82d6f474d2871698e1d426f99523dd25efa04 $ sudo docker commit wp-mysql mysql:5.7.21-my20240818 sha256:4fb2a23c3b0016c3087e39be1453c01ce81a18df897a517a253d54a7f6f87bca
routedになるnetworkを作る。v6 prefixも指定し、gateway_mode_ipv4をroutedにし enable_ip_masqueradeをfalseにするのがポイント。
$ sudo docker network create --driver bridge --subnet 172.18.0.0/16 --ipv6 --subnet 2001:2c0:cc17:c302::/64 --opt com.docker.network.bridge.gateway_mode_ipv4=routed --opt com.docker.network.bridge.enable_ip_masquerade=false routed-net e8df9d66c9e9b68d22eddd0464451b1e955f14df0d51fc14d24bfee383c1a30b
退避させた(というかcommitした)imageを使ってこのnetwork上にcontainerを作る。前のやつは止めたままにしておく。今までアドレスはhost起動直後に各コンテナを手動で起動させることでIP address固定にするという原始的とも言えないほど原始的なことをしていたが、今回からは専用bridgeを作ってそこでIPアドレスを固定にする。
$ sudo docker run -d --name miscmemo-wp-mysql --network routed-net --ip 172.18.0.2 -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=mysql -e MYSQL_USER=wordpress -e MYSQL_PASSWORD=wordpress -p 3306:3306 mysql:5.7.21-my20240818 3abb3d2c34be91cbf8f0d48bee9491d84117713efaef12b371376e8502c02893 sudo docker run --network routed-net --ip 172.18.0.3 -v /var/www/html/:/var/www/html --name miscmemo-wordpress -d miscmemo-wordpress-latest:20240818 31ee2c1176cc7258b09fdf82b3c61d95e4762b6040c32b62c3c309ff743b4c17
ごちゃごちゃいじりすぎたので、docker本体をrestart。miscmemo-wordpress (wordpress本体; 172.18.0.3からmiscmemo-wp-mysql (wordpress用のmysql; 172.18.0.2)へのpingは通る。が、外(10.0.0.1とか)からは通らない。もちろん10.0.0.1には172.16.0.0/14宛のrouteはこのubuntu本体がnexthopになるようなrouteを設定してある。
これは例によってiptablesの設定が足りていなかろうということで、miscmemo-wordpress tcp:80宛は通るようにしておく。port限定しなくてもip全部通せばいいんじゃないかとも思うが、どうせ80以外は空いていないからとりあえずこれで。
$ sudo iptables -L [sudo] momose のパスワード: Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy DROP) target prot opt source destination DOCKER-USER all -- anywhere anywhere DOCKER-FORWARD all -- anywhere anywhere Chain OUTPUT (policy ACCEPT) target prot opt source destination Chain DOCKER (2 references) target prot opt source destination ACCEPT tcp -- anywhere 172.18.0.2 tcp dpt:mysql ACCEPT icmp -- anywhere anywhere DROP all -- anywhere anywhere DROP all -- anywhere anywhere Chain DOCKER-BRIDGE (1 references) target prot opt source destination DOCKER all -- anywhere anywhere DOCKER all -- anywhere anywhere Chain DOCKER-CT (1 references) target prot opt source destination ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED Chain DOCKER-FORWARD (1 references) target prot opt source destination DOCKER-CT all -- anywhere anywhere DOCKER-ISOLATION-STAGE-1 all -- anywhere anywhere DOCKER-BRIDGE all -- anywhere anywhere ACCEPT all -- anywhere anywhere ACCEPT all -- anywhere anywhere Chain DOCKER-ISOLATION-STAGE-1 (1 references) target prot opt source destination ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED RETURN all -- anywhere anywhere DOCKER-ISOLATION-STAGE-2 all -- anywhere anywhere DOCKER-ISOLATION-STAGE-2 all -- anywhere anywhere Chain DOCKER-ISOLATION-STAGE-2 (2 references) target prot opt source destination DROP all -- anywhere anywhere DROP all -- anywhere anywhere Chain DOCKER-USER (1 references) target prot opt source destination momose@peso:~$ sudo iptables -I DOCKER 1 -d 172.18.0.3 -p tcp --dport 80 -j ACCEPT momose@peso:~$ sudo iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy DROP) target prot opt source destination DOCKER-USER all -- anywhere anywhere DOCKER-FORWARD all -- anywhere anywhere Chain OUTPUT (policy ACCEPT) target prot opt source destination Chain DOCKER (2 references) target prot opt source destination ACCEPT tcp -- anywhere 172.18.0.3 tcp dpt:http ACCEPT tcp -- anywhere 172.18.0.2 tcp dpt:mysql ACCEPT icmp -- anywhere anywhere DROP all -- anywhere anywhere DROP all -- anywhere anywhere Chain DOCKER-BRIDGE (1 references) target prot opt source destination DOCKER all -- anywhere anywhere DOCKER all -- anywhere anywhere Chain DOCKER-CT (1 references) target prot opt source destination ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED Chain DOCKER-FORWARD (1 references) target prot opt source destination DOCKER-CT all -- anywhere anywhere DOCKER-ISOLATION-STAGE-1 all -- anywhere anywhere DOCKER-BRIDGE all -- anywhere anywhere ACCEPT all -- anywhere anywhere ACCEPT all -- anywhere anywhere Chain DOCKER-ISOLATION-STAGE-1 (1 references) target prot opt source destination ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED RETURN all -- anywhere anywhere DOCKER-ISOLATION-STAGE-2 all -- anywhere anywhere DOCKER-ISOLATION-STAGE-2 all -- anywhere anywhere Chain DOCKER-ISOLATION-STAGE-2 (2 references) target prot opt source destination DROP all -- anywhere anywhere DROP all -- anywhere anywhere Chain DOCKER-USER (1 references) target prot opt source destination
この状態でもmiscmemo.momose.orgまたは172.18.0.3にwebで繋いでも’Error establishing database connection’になる。DBにloginできないということか?
db containerを作るときは-p 3306:3306してあるので、localhostに繋げばいけるはずだが、やはりいけない(これは謎)ので、172.18.0.2にmysql clientで繋いでみる。
docker runしたときにMYSQL_USERとかMYSQL_PASSWORD設定したせいか、それらのユーザは設定されているが、databaseとしてwordpressは定義されていない。
mysql> select User from mysql.user; +---------------+ | User | +---------------+ | root | | wordpress | | mysql.session | | mysql.sys | | root | +---------------+ 5 rows in set (0.01 sec) mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | +--------------------+ 2 rows in set (0.00 sec)
結論から言えば、これはvolumeの設定の仕方(-v option)の設定の仕方が悪い。上記例では ‘-v /var/lib/mysql’としてしか設定していないが、これはcontainer内部の/var/lib/mysqlをホスト側の匿名ボリュームを使え、ということしか指定していない。今回は新たに匿名ボリュームを作ってそれを内部で使おうとしているのに過ぎないので、今までのmysqlのデータは見れなくなっている。
今まで使っていたmysqlコンテナはdocker inspectすると
"Mounts": [
{
"Type": "volume",
"Name": "437162831f28b01734805001401217d94ae83d2c2ba91df5121bf27b1ec582c2",
"Source": "/var/lib/docker/volumes/437162831f28b01734805001401217d94ae83d2c2ba91df5121bf27b1ec582c2/_data",
"Destination": "/var/lib/mysql",
で、hostの437…というvolumeを使っていたが、新しい方だと
"Mounts": [
{
"Type": "volume",
"Name": "ffbcf68f7e10fe79b6252f374094d4fd9ed61e0ac884ece61966cbdb7595b7cb",
"Source": "/var/lib/docker/volumes/ffbcf68f7e10fe79b6252f374094d4fd9ed61e0ac884ece61966cbdb7595b7cb/_data",
"Destination": "/var/lib/mysql",
となっていて、全く別のffbcという匿名ボリュームを指している。なので、旧データが復活できていない。
というわけで、mysqlデータが入っているはずの匿名ボリュームを指してコンテナを作り直す。
$ sudo docker run -d --name miscmemo-wp-mysql --network routed-net --ip 172.18.0.2 -v 437162831f28b01734805001401217d94ae83d2c2ba91df5121bf27b1ec582c2:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=mysql -e MYSQL_USER=wordpress -e MYSQL_PASSWORD=wordpress -p 3306:3306 mysql:5.7.21 434a61c30c7b967c440adbd8c3b518825da99e9b1be1b7e7463eb6f867a71c7f
一応これで旧mysqlデータも読み込めて、接続できるようになった。
が、なんかのはずみですぐこのmysqlコンテナが落ちる。通常の閲覧画面は見えるが、admin画面にアクセスしたら落ちる(画面的にはしばらく待たせられる状態になる。その後切れる)、loginしようとしたら落ちる、などなど。
原因はよくわからないので、この際旧データを吸い上げて新しいコンテナを設置の上、そのデータを読み込ませて復旧させることにした。
$ mysqldump -h 127.0.0.1 -u root --ssl-mode=DISABLED -p wordpress > miscmemo-wp.sql Enter password: -- Warning: column statistics not supported by the server.
ここで読み込んだファイルの先頭に、CREATE DATABASE wordpress;USE wordpress;を入れる。
$ mysql -h 172.18.0.2 -P 3306 -u root -p < miscmemo-wp.sql
$ mysql -h 172.18.0.2 -P 3306 -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 19
Server version: 9.4.0 MySQL Community Server - GPL
Copyright (c) 2000, 2025, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases
-> ;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| wordpress |
+--------------------+
5 rows in set (0.01 sec)
mysql> use wordpress;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
+-----------------------+
| Tables_in_wordpress |
+-----------------------+
| wp_aal_products |
| wp_aal_request_cache |
| wp_aal_tasks |
| wp_commentmeta |
| wp_comments |
| wp_links |
| wp_options |
| wp_postmeta |
| wp_posts |
| wp_pz_linkcard |
| wp_term_relationships |
| wp_term_taxonomy |
| wp_termmeta |
| wp_terms |
| wp_usermeta |
| wp_users |
+-----------------------+
16 rows in set (0.01 sec)
mysql> ^DBye
rootユーザでセットアップしてしまったためか、wordpress dbにアクセスできるのがwordpressユーザではなくrootユーザになってしまったので、wordpressコンテナの/var/www/wp-config.phpのUSERとPASSWORDをroot用のに変更、起動し直すと今度はうまくいった。adminアクセスとかも問題なさそう。
ただ、adminダッシュボード画面ではwordpress.orgにアクセスできないとか言っている。どうも外にうまく繋がっていないようだ。iptableで外向きもいけるように設定。
$ sudo iptables -I DOCKER 1 -s 172.18.0.3 -p tcp -j ACCEPT
実は外向けルータでnatのルールに172.18.0.3が入っていないことがわかったので、そっちも設定。FreeBSDの/etc/ipnat.rules、172.16.0.0/16だったのを172.16..0.0/14に。今までも172.17.x.xだったからいけなかったはずなんだがいけていたのはちょっと不思議ではある。
map ng0 172.16.0.0/14 -> 0.0.0.0/32 portmap tcp/udp 60000:65000 #map ng0 172.16.0.0/46 -> 0.0.0.0/32 icmpidmap icmp map ng0 172.16.0.0/14 -> 0.0.0.0/32 proxy port ftp ftp/tcp map ng0 172.16.0.0/14 -> 0.0.0.0/32 #
これで一通り復活はできた。途中作りまくった匿名ボリュームとか今後使わないだろうimageとかは決しておく。今のところこのエントリをかける程度までは安定して動いている。
iptablesを次のreboot前までには安定させないといけない。
ipv6を復活させよう。