「自分の環境では動くのに!」– すべてのパッケージ作成者を悩ませる問題
FedoraでRPMをパッケージングしたことがあるなら、こんなシナリオに心当たりがあるはずです。.specファイルを書き、rpmbuildを実行し、すべてが完璧に仕上がった。しかし、その.rpmファイルを新しいサーバーに持っていったり、顧客に送ったりすると、ライブラリ不足のエラーが続出する。最悪の場合、パッケージはインストールできても、バージョンの競合で実行時にクラッシュすることもあります。
Fedoraをメインマシンとして2年以上使っている開発者として、私はこの落とし穴をよく理解しています。個人のマシンは、さまざまな開発用ライブラリ(devel)、プラグイン、追加のビルドツールが混在する「戦場」になりがちです。ホストマシンで直接ビルドすると、rpmbuildはそれらの既存ライブラリを自動的に「勝手に」取り込んでしまいます。BuildRequiresにそれらを記述し忘れると、結果として他の環境に依存しきった不完全なパッケージが生まれてしまいます。
なぜローカル環境は常に「裏切り者」なのか?
問題は「環境汚染(Environment Pollution)」にあります。日常的に使用しているOSは、以下の3つの主な理由から、パッケージングの基準としては決して適切ではありません。
- ライブラリの過剰: 他のアプリの依存関係が、意図せず現在のパッケージのビルド条件を満たしてしまうことがあります。例えば、古いプロジェクトの
openssl-develが残っていると、新しいアプリのビルド時にspecファイルへの記述を忘れていてもエラーが出ません。 - ゴミ設定: 環境変数や
/etc内の設定ファイルが、自分好みにカスタマイズされすぎています。 - バージョンの混在: いつインストールしたかも覚えていないような、独自の
glibcやカスタムライブラリを使用している可能性があります。
パッケージをどこでも動作させるには、絶対的に「クリーンな環境」が必要です。明示的に宣言したものだけが、その環境に存在することを許されるべきなのです。
環境隔離ソリューションের比較
最適なツールを選ぶ前に、私はさまざまな方法を試してきました:
- 仮想マシン (VM): ビルドのたびにVirtualBoxに新しいFedoraをインストールする方法です。非常にクリーンですが、非常に重いです。OSの起動と環境構築を待つのに、毎回少なくとも15〜20分はかかります。
- コンテナ (Podman/Docker): VMよりも大幅に高速です。しかし、ユーザー権限の管理、マウントポイント、異なるアーキテクチャのシミュレーション(Fedora上でRHEL向けにビルドするなど)は、依然として少し面倒です。
- Mockの使用: これはFedoraメンテナーの「黄金標準」です。Mockは最小限の
chroot環境を作成し、依存関係を自動的にダウンロードし、作業終了後にすべてをきれいにクリーンアップします。
Mock – プロフェッショナルなパッケージ作成者の救世主
Mockを内部ツールのパッケージングに6ヶ月間使用してみて、これが最もプロフェッショナルなワークフローだと感じています。Mockはクリーンなビルドができるだけでなく、クロスバージョンビルドもサポートしています。Fedora 40を使用していても、コマンド1つでFedora 39やAlmaLinux 9向けにビルドすることが可能です。
1. クイックインストールと設定
Fedoraでは、Mockは公式リポジトリで提供されています。以下のコマンドを実行するだけです:
sudo dnf install mock
sudoを毎回使わずにMockを使用するには、自分のユーザーをmockグループに追加します:
sudo usermod -a -G mock $USER
newgrp mock
newgrpコマンドは権限を即座に適用します。もしうまくいかない場合は、一度ログアウトして再度ログインすれば完了です。
2. ソースRPM (SRPM) の作成
Mockは.specファイルから直接ビルドしません。入力として.src.rpmファイルが必要です。以下のコマンドで作成します:
rpmbuild -bs my-package.spec
このファイルは通常、~/rpmbuild/SRPMS/ディレクトリに生成されます。
3. Mockによるビルドの実行
いよいよMockの真価を発揮する時です。Fedora 40のx86_64アーキテクチャ向けにビルドすると仮定して、以下を実行します:
mock -r fedora-40-x86_64 --rebuild ~/rpmbuild/SRPMS/my-package-1.0-1.fc40.src.rpm
Mockの自動プロセスには以下が含まれます:
- 新しいchrootディレクトリを作成し、コアパッケージ(bash, dnf, coreutils)をダウンロードします。
- specファイルを解析して、
BuildRequiresのリストを特定します。 - それらの依存関係を隔離された環境に自動的にインストールします。
- コンパイル、パッケージングを行い、完成したRPMファイルを出力します。
4. ログの確認とデバッグ
ビルド結果は/var/lib/mock/fedora-40-x86_64/result/に配置されます。以下の2つの重要なログファイルに注目してください:
- build.log: コンパイルプロセスが記録されます。コードにエラーがある場合は、ここを確認してください。
- root.log: 依存関係のインストールプロセスが記録されます。Mockが必要なライブラリを見つけられない場合、このファイルに理由が記載されています。
最適化のヒント:ビルド速度を3倍にする
Mockの弱点は、パッケージのダウンロードとchrootの展開に時間がかかることです。これを解決するために、私は常にハードディスクではなくRAM上のtmpfsを使用してビルドしています。これにより、平均的なパッケージのビルド時間を5分から2分未満に短縮できます。
tmpfsを有効にするには、以下のフラグを使用します:
mock -r fedora-40-x86_64 --plugin-option=tmpfs:max_size=4G --rebuild my-package.src.rpm
また、CentOS StreamやRHEL(EPEL経由)向けに頻繁にビルドする場合も、Mockは非常に強力にサポートします。-rフラグの後の値(例:epel-9-x86_64)を変更するだけで、Fedoraマシン上にRHEL標準の環境を構築できます。
Lời kết
Mockを使用することは、単に標準に従うだけでなく、自分自身を守ることでもあります。個人の環境に起因するくだらないエラーを完全に排除できます。アプリケーションをCOPRに公開したり、Fedoraのリポジトリに貢献したりする場合、Mockは不可欠なスキルです。ローカル環境に二度と騙されないようにしましょう!

