paloma blog

NWエンジニアやってます。主に自宅環境のお遊びを書きます。Pythonもちょっと。タイトルは好きなカクテルから。

LXDコンテナのFireflyをdockerコンテナへ移行する

先日記載したUbuntuですが、電源ファンの異音が激しくなりとうとうダメそうです。
LXDで動かしていたFireflyは普段使いしていて止まると困るので引っ越しします。

WSL環境へ移行

メインとして使っているWindows上に移行します。 これは主にゲーム用のマシンなので仮想環境等を作りこむのでサクッと立ち上げられるようにします。 というわけでWSL内のDocker環境へ移行します。
移行と言ってもコンテナは作り直しでデータのみの移行です。

環境

PS C:\Users\masashi> wsl --status
既定の配布: Ubuntu
既定のバージョン: 2

Linux 用 Windows サブシステムの最終更新日: 2021/10/02
()
カーネル バージョン: 5.10.16
PS C:\Users\masashi> wsl lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 20.04.4 LTS
Release:        20.04
Codename:       focal

Docker install

FireflyはDockerイメージも提供しているので今回はサクッとこれで作ります。 まずはcomposeインストール。

masashi@DESKTOP-HBP3520:/mnt/c/Users/masashi$ sudo apt install docker-compose

Docker起動。

masashi@DESKTOP-HBP3520:/mnt/c/Users/masashi$ sudo systemctl start docker
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down

systemdじゃなかったか。 とりあえずinitdでも起動できれば良しとします。

masashi@DESKTOP-HBP3520:/mnt/c/Users/masashi$ service docker status
 * Docker is not running
masashi@DESKTOP-HBP3520:/mnt/c/Users/masashi$ service docker start
 * Docker must be run as root
masashi@DESKTOP-HBP3520:/mnt/c/Users/masashi$ sudo service docker start
 * Starting Docker: docker
masashi@DESKTOP-HBP3520:/mnt/c/Users/masashi/firefly-docker$ docker --version
Docker version 20.10.12, build e91ed57

ファイル修正

割愛しますが、定義系ファイルを準備します。
.env、.db.envファイルを修正。

masashi@DESKTOP-HBP3520:/mnt/c/Users/masashi/firefly-docker$ ls .env .db.env docker-compose.yml
.db.env  .env  docker-compose.yml

docker-composeで起動。

masashi@DESKTOP-HBP3520:/mnt/c/Users/masashi/firefly-docker$ sudo docker-compose -f docker-compose.yml up -d
Creating network "firefly-docker_default" with the default driver
Creating firefly-docker_db_1 ... done
Creating firefly-docker_app_1 ... done

あとはphp artisanを使ってDBの初期化等行いますが、ドキュメントにもあるのでこちらも割愛。 これで起動OKです。

masashi@DESKTOP-HBP3520:/mnt/c/Users/masashi/firefly-docker$ sudo docker ps
CONTAINER ID   IMAGE                                          COMMAND                  CREATED          STATUS                    PORTS                                                                                            NAMES
f9afd585b6b3   fireflyiii/core:latest                         "/usr/local/bin/entr…"   34 minutes ago   Up 34 minutes (healthy)   0.0.0.0:80->8080/tcp, :::80->8080/tcp                                                            firefly-docker_app_1
137c4d9a43b1   mariadb                                        "docker-entrypoint.s…"   34 minutes ago   Up 34 minutes             3306/tcp                                                                                         firefly-docker_db_1
93306eb90638   privoxy                                        "/usr/sbin/privoxy -…"   14 months ago    Up 20 hours               0.0.0.0:8118->8118/tcp, :::8118->8118/tcp                                                        priceless_mcclintock
833caa7799a8   cr.portainer.io/portainer/portainer-ce:2.9.3   "/portainer"             14 months ago    Up 20 hours               0.0.0.0:8000->8000/tcp, :::8000->8000/tcp, 0.0.0.0:9443->9443/tcp, :::9443->9443/tcp, 9000/tcp   portainer

前使ってたPrivoxyのコンテナも残ってました。
もう消してもいいかな。

localhostでユーザ登録画面が出てきました。
まあここまでは簡単です。

データ移行

起動だけならそんなに躓かずにできると思います。
しかし私は運用してきたデータを移行しないといけません。 mysqldumpのバックアップは日次で撮っているので最新のものがあるし、DBも同じMySQLなので移行もそんなに難しくないだろうと思っていました。

しかし移行でトラブって休日を丸一日潰してしまいました。

躓いた点

dumpファイルをリストアして終わりだろと思っていたら、まあ上手くいきませんでした。

  • パッケージのバージョン差分によりスキーマの変更
    • relationしているID等も差分あり
  • 運用していたFireflyのバージョンが古く現在提供されていない
  • LXD環境のパッケージは残っているがLXDを作り直すよりDocker上げたほうがデータ移行までが早そう

というワケで、データは丸々移行できなくてもいいから資産と取引ログだけ移行できれば良しにして、手打ちでdumpファイルを修正して流すことにしました。

portainer内のターミナルで作業したのでログが残っていないのですが、

  1. まずは起動後、ユーザ登録(たぶんユーザ作ってログインしないと初期値が展開されない)
  2. 諸々デフォルトのテーブルスキーマを確認
  3. 資産、取引ログ系のSQL文を修正、流し込み

という流れで移行できているかを確認し、2,3を数回やり直して上手く移行できました。
貨幣IDの値が変わっていたのと、ユーザグループIDというカラムが各テーブルに追加されていたのが主な変更点ですが、
取引ログに絡んでくる値だったので割り出しと修正に苦労しました。

取引の実データのほかジャーナル用のテーブルもあり、IDの関係で移行エラーになったりと依存関係も勉強になりました。

途中でわけわからなくなったときはDockerっぽく破棄して新しい環境を直ぐに作れるのでその点はやりやすくてよかったです。

資産の開設日の値だけどこを参照しているかわからず、最終的にブラウザからこちらも手入力で修正しました。
総資産の細かい値は覚えていなかったのですが、取引ログが全部移行できたのは確認したので移行OKとしました。

一応額は隠しながらのlocalhostで環境が復元できました。
いやーよかった。

即dumpも取ったのでいつ壊れてもOKです。

masashi@DESKTOP-HBP3520:/mnt/c/Users/masashi/firefly-docker$ sudo docker exec -it 137c4d9a43b1 mysqldump --single-transaction --character-set=utf8 -u firefly -p<password> -t firefly > newfirefly.sql

すんなりリカバリとは行きませんでしたが長期に止まることなく使い続けられそうで良かったです。

反省点

自宅の環境ということもあって冗長化無しだったのがいけなかった。
部屋はシンプルな方が好みなので勉強のためとはいえ筐体をガンガン買うというのは考え物です。
じゃあ仮想マシンで冗長させて、と言っても1筐体だったら電源障害出たら同じですからね。

物理2台くらいがベストな気がしますが、とりあえずはるべく早く同じ環境を復旧、という事を念頭に反省点です。

  • 同じ環境の退避先を作っておく
  • パッケージアップデートの試験をしておく
  • DBスキーマ拡張方法を押さえておく

dumpファイルだけあればなんとかなるだろの精神で始めたせいでやたら時間がかかってしまいました。
結果なんとかなったのですがもっとすんなり戻したいものです。

まずはやはりOSやパッケージ事リストアしてからのほうが復旧が容易ですね。
クラスタ構成とまではいかなくても壊れた時の逃がし先があるだけでだいぶ楽だったと思います。

また、同じバージョン使いっぱなしで構成の変化に気付かなかったので公式サイト等定期チェックしてある程度転々とバージョンアップしておくべきでした。
せっかく前もLXDコンテナだからやりやすかったのに…
あとは勉強関係でDBスキーマが変わった時の対応法を見ておこうと思いました。

参考サイト

ERROR 1452 (23000): Cannot add or update a child rowのエラーはこの辺参考に関連テーブルのレコードを削除しつつ反映できました。

MySQLで外部キーを貼り直すときにエラーが出た場合 - ハックノート

database - How to find all the relations between all mysql tables? - Stack Overflow