バックアップ、サービス移行、本番切替の話
Raspberry Pi 4で動かしていた自宅サーバを、Ryzen 7搭載のミニPCに移行しました。この記事は、この移行作業を後世に残すためにしたためるものです。 ……大げさですね(^^;)
今回はその第3回、実行編です。 テーマは、旧サーバからのバックアップ、サービス移行、本番切替までの話です。
第1回では、ラズパイ4の限界と移行先ミニPCを検討した話を書きました。 第2回では、Hermes Agentを使って移行計画を立て、新サーバの初期セットアップを進めた話を書きました。
今回はいよいよ、旧Raspberry Pi 4サーバ agul からデータを移し、新しいACEMAGIC M1上の agul-sv を本番サーバにしていきます。
Day 3はバックアップから始まった
Day 3は、朝からかなり詰め込んだ一日でした。
出社前に、旧サーバ側のバックアップを取り、新サーバ側へ初期展開するところまで進めました。 帰宅後に、各サービスの動作確認、トラブル対応、本番IPの切り替えを進める、という流れです。
移行対象はかなり多めです。
主なものだけでも、
- WordPress
- MariaDB
- メール
- DNS / BIND
- Mailman
- 蔵ログ
- SwitchBot
- OpenClaw関連データ
- 証明書
- 各種設定ファイル
があります。
第2回でも書いた通り、今回は単純にディスクを丸ごとコピーするのではなく、サービスごとに移行する方針にしました。
旧環境はRaspberry Pi 4のDebian 11、移行先はRyzen 7搭載ミニPCのUbuntu 26.04です。 CPUアーキテクチャも arm64 から x86_64 に変わります。
そのため、PythonのvenvやOpenClawのバイナリまわりなどは、そのままコピーしても動かない可能性があります。 バックアップはデータと設定を中心に取り、移行先では必要なものを再構築する形にしました。
バックアップと初期展開
まずは旧サーバ agul 側で、設定ファイルやデータのバックアップを作成しました。
対象になったのは、主に以下です。
/var/www/var/mail- MariaDBのdump
/etc配下の主要設定/etc/letsencrypt/etc/sakeapp/home/iinuma/.openclaw/home/iinuma/openclaw
バックアップは旧サーバ側でtarやDB dumpを作成し、新サーバ側へ転送して、SHA256で検証する形にしました。
このあたりは、Hermes Agentにスクリプトを作ってもらい、私がsudoで実行して結果を貼り戻す、という進め方です。
サーバ移行で怖いのは、コピーしたつもりが一部抜けていることです。 今回はバックアップ作成後にチェックサムを作り、新サーバ側で検証する流れにしたので、安心感がありました。
実際には、途中でバックアップ再開用スクリプトの修正が必要になったり、SSH鍵の向きが足りなくて、新サーバから旧サーバへpullできなかったりもしました。 ただ、エラーをHermes Agentに貼ると原因を切り分けて、修正版のスクリプトを作ってくれるので、かなりテンポよく進みました。
データはコピーできても、サービスが読めるとは限らない
バックアップ時には、設定ファイルや各種ディレクトリへのアクセスにsudoが必要でした。 この段階ではsudoでtarやdumpを取っているので、ファイルの所有者やUIDの違いはあまり表面化しません。
問題はその後でした。
新サーバ側へ展開して、実際にサービスとして動かし始めると、UID違いの影響が見えてきました。
特に分かりやすかったのがメールです。
Dovecot経由でIMAPアクセスしたときに、メールボックス内のファイルが読めない状態になりました。 バックアップや展開自体はできているのですが、Dovecotが実際にユーザー権限でMaildirを読もうとすると、Permission deniedになります。
原因は、旧サーバと新サーバでユーザーのUIDが違っていたことです。
旧Raspberry Pi側ではユーザーのUIDが 1001、新しいUbuntu側では 1000 になっていました。 sudoでバックアップしているときには見えなかった問題が、実運用の権限でアクセスした瞬間に表面化したわけです。
Hermes Agentにログを見せると、すぐにUID/GIDの違いを疑って、/var/mail/<ユーザー> 配下の所有権を確認し、修正する流れを提案してくれました。
最終的には、対象のMaildirを新環境のユーザーとmailグループに合わせて修正し、IMAPでメールが読めるようになりました。
サーバ移行では、データが「コピーできた」ことと、サービスが「実際に読める」ことは別物だと改めて実感しました。
WordPressのアップロード上限が戻っていた
WordPressの確認でも、ひとつ気づきがありました。
サイト自体は表示されるようになったのですが、メディアアップロードの上限値がデフォルトに戻っていました。
旧環境ではアップロード上限を調整していたのですが、移行先ではPHPのバージョンが上がっています。 その影響で、旧環境のPHP設定をそのまま引き継いだつもりでも、新しいPHP環境では反映されていない状態になっていました。
WordPressのファイルやDBは移行できていても、PHPの実行環境は別です。 特にApache経由のPHPでは、CLIで見える設定とWeb経由で効いている設定が違うこともあります。
Hermes Agentは、単に設定ファイルをコピーするのではなく、Web経由でPHPの実効値を確認する方針を出してくれました。 そのうえで、移行先のPHPバージョンに合わせたApache用の設定として、アップロード上限を再設定しました。
こういう「動いているように見えるけど、細かい設定が戻っている」系の問題は、移行後の確認でかなり大事です。
蔵ログとSwitchBotの移行
自作アプリとして動かしている蔵ログとSwitchBot関連のアプリも移行対象です。
蔵ログは、日本酒の在庫やレビューを管理するための自作アプリです。 Flaskで動いていて、DBとWebアプリ、さらにMCPサーバも絡んでいます。
SwitchBot側は、家庭内のセンサー情報などを扱うアプリです。 こちらもWebアプリとDB、定期収集用のcronが絡みます。
どちらも大規模なアプリではありませんが、日常的に使っているものなので、移行漏れすると地味に困ります。
ここでも、単純に /var/www をコピーすれば終わりではありませんでした。 Pythonのvenvは旧環境のものをそのまま使えないので、新環境で再作成する必要があります。
また、final syncで /var/www を旧サーバ側の内容で上書きしたことで、いったん新環境で作り直していたvenvが古い状態に戻ってしまう、という問題もありました。 このため、移行先で作成済みだったvenvを戻し、実際のimport pathで確認し直すことになりました。
SwitchBot側では、cronの移行も重要でした。 データ収集が定期実行されているので、Web画面が表示されるだけでは不十分です。 cronが新環境でも登録され、venvのPythonを使って動いているかまで確認する必要がありました。
このあたりも、Hermes Agentが「Webが200を返しているか」だけではなく、DBの更新やcronの登録状態まで確認してくれたのは助かりました。
Dovecotの設定はそのまま引き継げなかった
今回、特に感心したのがDovecotの移行です。
メールサーバはPostfixとDovecotで構成しています。 旧環境でもDovecotの設定にはかなり手こずった記憶があります。 初期構築時も、証明書、Maildir、認証、Postfixとの連携など、いろいろ調べながら設定したはずです。
今回も、旧環境の設定をそのまま持っていけば動くかというと、そうはいきませんでした。
移行先のDovecotはバージョンが上がっていて、設定ファイルの書き方や、使える変数が変わっていました。 旧設定をそのままコピーすると、設定の読み込みでエラーになったり、IMAPログイン後に切断されたりします。
ここでHermes Agentは、旧環境と新環境の設定値を比較し、必要な項目を新しいDovecotの設定形式に合わせて再構成してくれました。
具体的には、旧設定を丸ごと持ち込むのではなく、Ubuntu 26.04側のDovecot 2.4の標準設定をベースにして、必要な項目だけを上書きする方針です。
メールボックスの場所、SSL証明書、認証方式、Postfix連携用のsocketなど、必要なポイントを拾って再設定していきました。
正直、これは素直にHermes Agentすごいなと思いました。
Dovecotは初期構築時にも苦労した記憶があるので、ログと設定を比較しながら「このバージョンではこの書き方がよい」と整理してくれるのは、かなり助かります。
DNSとメールの確認が丁寧だった
もうひとつ感心したのが、疎通確認のやり方です。
今回のサーバはDNSサーバも兼ねています。 wandaba.com の名前解決は、自宅内から見るとローカルアドレス、外部から見るとパブリックアドレスになります。
つまり、同じ www.wandaba.com や mail.wandaba.com でも、
- 自宅内では
192.168.0.x - 外部からはグローバルIP
という見え方になります。
自分でやっていると、つい dig で引けた、curl で見えた、で済ませてしまいがちです。 しかしHermes Agentは、ローカルアクセスと外部アクセスをちゃんと分けて確認していました。
Webについては、
- 新サーバ自身から
127.0.0.1 - LAN内からローカルIP
- ドメイン名で内部DNS経由
- 外部からパブリック側経由
というように確認していました。
メールについても、
- ローカルでPostfix/Dovecotのポートが開いているか
- LAN内から
mail.wandaba.comがどう解決されるか - 外部から25番や993番に到達できるか
- MX、SPF、DKIM、DMARCがどう見えるか
を分けて確認していました。
特に、内部DNSではローカルアドレスを返し、外部DNSではパブリックアドレスを返すという構成をちゃんと認識してチェックしてくれたのは、かなり感心しました。
これは、自宅サーバならではの面倒なところです。 Webもメールも、ローカルと外部の両方で確認しないと、本当に移行できたとは言い切れません。
本番IPの切り替え
サービス単体の確認が進んだところで、本番IPの引き継ぎに入りました。
旧サーバ agul は 192.168.0.10 で動いていました。 新サーバ agul-sv は構築中は一時的なIPで動かしておき、最後に旧サーバのIPを引き継ぐ形です。
この切り替えでは、
- 旧サーバを停止または別IPへ退避
- 新サーバに
192.168.0.10を設定 - ARPやルーティングを確認
- Web、メール、DNSを再確認
という流れで進めました。
IPを引き継ぐと、SSHでは当然ながらhost keyが変わったという警告が出ます。 これは想定内です。 同じIPアドレスに別のマシンが来たので、SSHクライアントから見れば「違うホストでは?」となるわけです。
このあたりも、Hermes Agentに確認させながら、旧サーバと新サーバのMACアドレス、IPアドレス、SSH fingerprintを整理して進めました。
最終的に、新しい agul-sv が本番IP 192.168.0.10 を引き継ぎ、旧 agul は別IPに退避しました。
切替後の確認
本番IPを切り替えたあとは、ひたすら確認です。
確認した主な項目はこんな感じです。
- WordPressが表示できる
- 蔵ログが表示できる
- SwitchBotアプリが表示できる
- MariaDBのDBが復元されている
- BINDが内部向け名前解決を返す
- 外部からWebにアクセスできる
- Postfix/Dovecotでメール送受信・IMAP確認ができる
- Mailman3が表示できる
- ClamAVが動く
- Fail2banが動く
- systemdのfailed unitsが0
ここまで確認して、ようやく「移行できた」と言える状態になりました。
旧Raspberry Pi 4の agul はすぐに消さず、別IPでしばらく残しておくことにしました。 何か見落としがあった場合に、すぐ参照できるようにしておくためです。
Day 3で主要な移行は完了
こうして、Day 3で主要サービスの移行と本番切替まで完了しました。
もちろん、細かい後始末や監視はその後も続きます。 それでも、WordPress、メール、DNS、DB、自作アプリ、Mailmanまで含めて本番切替できたのは、かなり大きいです。
ただ、今回の移行で面白かったのは、サーバ移行そのものだけではありません。
OpenClawをHermes Agentに構築させたり、長時間作業でトークンリミットにぶつかったり、移行作業の知見が home-server-migration というスキルとして残ったりしました。
次回は、今回の移行を通じて感じたHermes Agentの使いどころと限界について書きます。
第4回、振り返り編に続きます。