Lightsail の wordpress (bitnami) イメージを使ってこのブログを運用していましたが、PHP の更新が必要だけど bitnami でのやり方がよくわからんし、調べるのも面倒ということで 1 vCPU, 1GB メモリの VM を2まで無料で使える Oracle Cloud に移設 & コンテナ化してしまうことにしました。 (が、Oracle Cloud の使い方を調べるのも超面倒… しかも学ぶモチベーションが… やっちまった)
コンテナとして実行するわけですが単一ホストでの実行とする、あるいはメモリ的に厳しければ DB を別サーバーに分けることにします。まずは単一サーバーで docker-compose での実行を試みます。シングルノードの swarm で rolling update というのもありますがとりあえずまだ考えない。
Docker Engine, docker-compose のインストール
Oracle Cloud なので Oracle Linux が最も最適化されているのだろうという勝手な思い込みで Oracle Linux 7.x を使うことにします。
sudo yum -y install docker-engine
sudo curl -L "https://github.com/docker/compose/releases/download/1.27.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose.yml の作成
Wordpress のコンテナイメージは wordpress:5.5.1-php7.4-apache で、MySQL のコンテナイメージは mysql/mysql-server:8.0.21 を使うことにします。こっちの MySQL は Oracle の MySQL Team がメンテナンスしているようです。Dockerfile などは github.com/mysql/mysql-docker にあります。
wordpress コンテナが起動時にどんな処理を行っているのかは docker-entrypoint.sh を参照。
で、次の docker-compose.yml
となりました。wp-content/plugins
と wp-content/themes
には旧環境のファイルをコピーしておきます。
version: "3.8"
services:
db:
image: mysql/mysql-server:8.0.21
volumes:
- ./mysql/data:/var/lib/mysql
- ./mysql/backup:/backup
environment:
MYSQL_ROOT_PASSWORD: $MYSQL_ROOT_PASSWORD
MYSQL_USER: wordpress
MYSQL_PASSWORD: $DB_PASSWORD
MYSQL_DATABASE: wordpress
wordpress:
image: wordpress:5.5.1-php7.4-apache
volumes:
- ./wordpress/wp-content/plugins:/var/www/html/wp-content/plugins
- ./wordpress/wp-content/themes:/var/www/html/wp-content/themes
- ./wordpress/wp-content/uploads:/var/www/html/wp-content/uploads
- ./wordpress/php.ini:/usr/local/etc/php/php.ini:ro
- ./wordpress/backup:/backup
depends_on:
- db
environment:
# https://api.wordpress.org/secret-key/1.1/salt/
WORDPRESS_AUTH_KEY: $WORDPRESS_AUTH_KEY
WORDPRESS_SECURE_AUTH_KEY: $WORDPRESS_SECURE_AUTH_KEY
WORDPRESS_LOGGED_IN_KEY: $WORDPRESS_LOGGED_IN_KEY
WORDPRESS_NONCE_KEY: $WORDPRESS_NONCE_KEY
WORDPRESS_AUTH_SALT: $WORDPRESS_AUTH_SALT
WORDPRESS_SECURE_AUTH_SALT: $WORDPRESS_SECURE_AUTH_SALT
WORDPRESS_LOGGED_IN_SALT: $WORDPRESS_LOGGED_IN_SALT
WORDPRESS_NONCE_SALT: $WORDPRESS_NONCE_SALT
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: $DB_PASSWORD
WORDPRESS_DB_NAME: wordpress
WORDPRESS_DB_CHARSET: utf8mb4
WORDPRESS_DB_COLLATE: utf8mb4_bin
WORDPRESS_CONFIG_EXTRA: |
define('WPMS_ON', true);
define('WPMS_MAIL_FROM', '$SMTP_USER');
define('WPMS_MAIL_FROM_FORCE', true);
define('WPMS_MAILER', 'smtp');
define('WPMS_SMTP_HOST', 'smtp.gmail.com');
define('WPMS_SMTP_PORT', 465);
define('WPMS_SSL', 'ssl');
define('WPMS_SMTP_AUTH', true);
define('WPMS_SMTP_USER', '$SMTP_USER');
define('WPMS_SMTP_PASS', '$SMTP_PASS');
define('WPMS_SMTP_AUTOTLS', true);
if (strpos($$_SERVER['HTTP_CLOUDFRONT_FORWARDED_PROTO'], 'https') !== false) {
$$_SERVER['HTTPS']='on';
}
if (strtolower($$_SERVER['HTTPS']) == 'on') {
define('WP_SITEURL', 'https://' . $$_SERVER['HTTP_HOST'] . '/');
define('WP_HOME', 'https://' . $$_SERVER['HTTP_HOST'] . '/');
} else {
define('WP_SITEURL', 'http://' . $$_SERVER['HTTP_HOST'] . '/');
define('WP_HOME', 'http://' . $$_SERVER['HTTP_HOST'] . '/');
}
ports:
- 80:80
tmpfs:
- /run
- /tmp
WORDPRESS_CONFIG_EXTRA
は wp-config.php に追記するコードです。WPMS_
で始まるものは WP Mail SMTP 用の設定です。ここでは gmail の SMTP サーバーを使うことにしています。Oracle Cloud にも SMTP サービスあるんですね。CloudFront は X-Forwarded-Proto
ではなく CloudFront-Forwarded-Proto
ヘッダーを挿入してくるのでそのための設定も入れています。$XXX
は docker-compose 実行時の環境変数に置き換えられますが、WORDPRESS_CONFIG_EXTRA の中での PHP の変数としての $_SERVER などは $$ として $ をエスケープする必要があります。
php.ini のカスタマイズは /usr/local/etc/php/conf.d ディレクトリ内にファイルをマウントすれば良いのですが、php.ini-production を使うべく、これをコンテナ内から取り出して編集して php.ini としてマウントすることにしました。
capabilities 設定もやるべきかな
Oracle Cloud の Security List (SecurityGroup みたいなやつ)
初期状態では外部から port 80 へはアクセスできませんでした。Instance の Network Security Groups ってのを設定すれば良さそうな感じではあるものの、その方法がわかりませんでした。Subnet の Default Security List というのがデフォルトでは 22/tcp と ICMP の type 3,4 だけを許可するようになっていたのでとりあえずここに 80/tcp を追加しました。Subnet のデフォルトルールで許可してしまうのは本来は良くないとは思うものの現状、他のインスタンスは使わないし、本来の設定方法もすぐには見つからないし、どれが無料でどれが有料かもわからないのでとりあえずこれで。仕事で使うわけでもないので Oracle Cloud を真面目に調査するの嫌だ…
Backup
docker-compose exec で db コンテナ内で mysqldump を実行しホストのディレクトリをマウントしている /backup に書き出します。パスワードはコンテナ起動時に環境変数で渡してあるのでそれを使いますが、-p
で指定するとセキュアじゃないよと Warning メッセージが出力されてうざいので MYSQL_PWD 変数に設定しています。conf ファイルに書くべきなのかもしれない。
docker-compose exec -T db \
bash -c "MYSQL_PWD=\$MYSQL_ROOT_PASSWORD \
mysqldump --add-drop-table -u root wordpress \
| gzip -9 > /backup/wordpress.dump.\$(date +%a).sql.gz"
upload したファイルはディレクトリをマウントしているだけなのでホスト側で tar にでもすれば ok。
さて、これらを Oracle Cloud の Object Storage に保存するには…
oci コマンドを使うと良いらしい Getting started with the OCI Command Line Interface (CLI)
bash -c "$(curl –L https://raw.githubusercontent.com/oracle/oci-cli/master/scripts/install/install.sh)"
でインストールできると書いてあるけど、Python 3 が入っていれば Home directory 配下に venv でインストールするだけっぽいので root で実行しなくても大丈夫。~/lib/oracle-cli
配下にインストールされて、~/bin/oci
にシンボリックリンクが張られました。
が、権限設定周りが全然わからん…
データ移行
旧環境からのデータ移行は Wordpress の export / import 機能を使ったのだけれど、widget 設定とかが飛んんでしまうのはなんとかならないものか? ファイルのコピーと DB の export / import にした方が良かったのかな。