RoonServerをsystemdから公式Dockerイメージへ移行した
先日Roon LabsのコミュニティフォーラムにてRoonServerの公式Dockerイメージがghcrで公開されたというお知らせがありました。これを機にもともとサーバー上でsystemdで動かしていたRoonServerをDockerでの運用へと移行しました。
公式Dockerイメージの公開
これまでもRoonServerの非公式のDockerイメージはサードパーティから提供されていましたが悪意のあるコードの混入やベースイメージの脆弱性が放置されるリスクといったセキュリティ上の懸念からわたしはそれらを利用してきませんでした。公式が提供するLinux環境向けのインストールスクリプトを用いてホストへ直接インストールしRoonServer自体のアップデート機構に任せるのがもっとも確実だと考えていたからです。
今回GitHub Container Registry (ghcr.io) にて公式からDockerイメージが提供されたことでほかのセルフホストサービスと同様に統一された手法で安全にデプロイやメンテナンスができるようになりました。
移行後の構成とネットワーク要件
今回の移行にあたり使用しているcompose.yamlは以下の通りです。わたしの環境に依存する監視用のコンテナなどは取り除きRoonServerを稼働させるために必要最小限の構成を記載しています。
services:
roonserver:
container_name: roonserver
environment:
ROON_INSTALL_BRANCH: production
image: ghcr.io/roonlabs/roonserver:latest
network_mode: host
restart: always
volumes:
- roon-data:/Roon
- ${ROON_SERVER_MUSIC_DIR}:/Music
- ${ROON_SERVER_BACKUP_DIR}:/RoonBackups
volumes:
roon-data:RoonServerをDockerで稼働させる際重要になるのがnetwork_mode: hostの指定です。Roonはネットワーク上のRoon ReadyデバイスやChromecastやAirPlay機器などを探索するためにマルチキャストやブロードキャストを用いた通信を行います。Dockerの標準であるブリッジネットワークではこれらの通信が遮断されてオーディオ機器を正しく認識できなくなってしまうためホストネットワークをそのまま利用する必要があります。
バックアップからの移行手順
移行作業において少し工夫が必要だったのはミュージックフォルダやバックアップフォルダのパスの取り扱いです。
RoonServerの公式DockerイメージではマウントポイントがDockerfileのVOLUME命令によって/Musicや/RoonBackupsに規定されています。コンテナ内のパスをこれまでの環境と同じにすることも可能でしたが今後の運用で混乱を招かないようにするため単純に公式が規定するパスへ合わせることにしました。
これまでsystemdで動かしていた環境では全く別のディレクトリパスを用いていました。Roonはディレクトリのパスを基準にしてライブラリを管理しているため単純に別のディレクトリパスをマウントしてしまうとバックアップから復元した際にライブラリの整合性が取れなくなる懸念がありました。
そのため移行前の環境においてホスト側に以下のようにシンボリックリンクを作成しあらかじめ/Musicおよび/RoonBackupsとしてRoonに認識させてからRoonアプリ経由でバックアップを作成するという手順を踏みました。
ln -s /mnt/media/Music /Music
ln -s /home/ykzts/.roon/backups /RoonBackupsバックアップの作成後新しいDocker環境のRoonServerを立ち上げRoonアプリからバックアップのインポートを行いました。インポートの仕様を正しく把握したうえでこの手順を踏んだことにより以前のライブラリ情報や設定が/Musicや/RoonBackupsパスを基準として正しく引き継がれました。インポートが正常に完了し音楽が問題なく再生できることを確認できたため最終的にホスト側に作成したシンボリックリンクを削除して移行作業を完了としました。
おわりに
オーディオ環境の構築においては機材のルーティングなど様々な課題がありますが今回はサーバー側のソフトウェアの配置をすっきりと整理することができました。
公式イメージの利用により今後のアップデートも容易になるため引き続きこの構成で運用していこうと思います。