Linuxのパッケージ管理に関する世界観です。
自分の書いたブログ「神々とともに生きる詩人」2021/01/27より。
また、Linuxなどではパッケージ管理システムと呼ばれる管理機構によって、システムの全ソフトウェアを管理する。
このメリットは、依存性の解決であり、プログラムが導入されていても、それに依存するプログラムが導入されていないから、といった理由でシステムが動かず破損することを防げる。
通常は、RPMやDpkg/Debなどといった低レベルなシステムの上に、DNFやAptといった使いやすい管理ツールを用いる。
このDNFやAptを用いると、ネットワーク上のリポジトリから、パッケージをコマンドひとつでインストールし、更新や依存するパッケージの導入なども全て自動で実行できる。
パッケージ管理システムを用いると、システムを常に安全かつ最新に保つことができるが、実際は全てのパッケージがリポジトリに用意されているわけではなく、自分の使いたいバージョンが導入できるとも限らないため、ソースtarball(tar.gzファイルのこと)からconfigureやmakeでビルドすることも時には必要である。
LinuxというOSは、昔から、カーネルだけが単体で配布され、それにGNUやその他のツールを導入しなければ使えなかった。
初期のハッカーは、リーナス・トーバルズとやり取りしながら、そうしたツールの導入を自分で行い、自分の責任でLinuxカーネルを導入し、開発に参加していた。
こうしたLinuxの「配布版」として生まれたのは、Slackwareなどの最初期のLinuxディストリビューション。UNIXのシステム管理が分からない人間でも、簡単にLinuxシステム一式を導入し、使うことができた。
だが、さまざまなところからソフトウェアを組み合わせたSlackwareには、「依存関係」と「更新」の問題がある。
依存関係とは、「このソフトウェアをインストールするためには、別途ほかのソフトウェアが必要」であるということ。
更新の問題とは、さまざまなソフトウェアを別々にインストールするため、「最新のセキュリティパッチなどの情報を入手しづらく、自分の手で更新されているかを確認しなければならない」ということ。
パッケージ管理システムは、こうした依存関係と更新の問題を解決し、同時にソフトウェアパッケージを簡単に導入することができる機構であり、WindowsなどにはないLinuxに特有の機構である。
パッケージ管理システムで導入できるソフトウェアパッケージは、依存関係を自動的に解決し、必要なパッケージは追加インストールすることができる。また、パッケージはリポジトリに公開され、新しいパッケージが安定版で入手可能になれば、dnfやaptを用いることで即座に更新することができる。
パッケージ管理システムとは、Linuxで使われるアプリケーションのインストールやアンインストール、そして更新や管理のシステムである。
昔のLinuxでは、ソースコードの入ったtarballをそれぞれのシステムの管理者がコンパイルして、手動でmakeなどのコマンドでインストールしていたが、こうすると、さまざまなソフトウェア配布サイトから集めてきたフリーソフトウェアの更新を自分で把握しなければならないし、依存関係のチェックなどが大変で、一般のユーザーはとても自分ですることは出来なかった。
だが、Red Hatのようなディストリビューションの開発者は、「パッケージ管理システム」というものを作った。RPMでは、そもそものtarballにspecファイルと呼ばれる「インストール方法やソフトウェアの特性(主に依存関係)」を付属し、「パッケージ」という、ソフトウェア構成状態の含まれたコンパイル済みのアーカイブにし、インストールや更新は「パッケージ管理システム」と呼ばれるシステム全体で統一された「機構」によって管理することで、インストールや更新を楽にし、「一部の専門ユーザー(オタク)でなくても、Linuxのさまざまなソフトウェアをきちんと動くように導入出来る」という、画期的なものだった。
今のディストリビューションというのは、ほとんどがこのパッケージ管理システムに基づいている。Red HatのRPMのほか、Debianやその派生(Ubuntuなど)のDeb/Dpkgが二大パッケージ管理システムだが、ほかにもGentooのPortageやArchのPacmanなどがある。ほかにもたくさん、雨後の竹の子のように増えている。
このパッケージ管理システムというのは、ソフトウェアをパッケージにする代わり、その構成データを全て、.rpmとか.debなどの専用のファイル形式を持つアーカイブにし、そのアーカイブをシステムのrpmなどのコマンドでインストール・管理することになっている。また、ソースパッケージというものもあり、そもそもソフトウェアをビルドしてバイナリにする段階で、ソースパッケージを簡単に自動でバイナリパッケージにすることができるようになっている。
Linuxディストリビューションの開発では、パッケージの取りまとめ作業のようなことをプロジェクトとしてしていて、きちんと全てのパッケージが動くように、システムを安定してバグの無い状態で最新のリリースを出せるように心がけている。だから、DebianのメンテナやRed Hatの従業員は、きちんとOSとしてパッケージが動くことを想定して、diffのパッチを当てたり、カーネルとユーザーランドがきちんと動くように調節を行っている。さまざまなプロジェクトからバラバラにリリースされるソフトウェアを、ひとつのシステムとして動かしているのは、ディストリビュータが頑張ってメンテナンスや開発を行っているからである。それもあって、Linuxは必ずしも、無料であるとは限らないのである。
そして、RPMやDebのひとつ上の水準の階層として、yum/dnfやaptのような「パッケージ管理ツール」というものがある。これは、.rpmや.debのようなファイルを、「インターネットから自動でダウンロードして、コマンド一発で依存関係など全ての処理をし、自動で全部のパッケージを更新することができる」というものである。
パッケージをインストールするのをRPMだとすると、そのパッケージをどこかのサーバーが配布しなければならない。Red HatやDebianは、これを「リポジトリ」というインターネット上のミラーサーバーに公開している。このリポジトリをシステムに登録し、パッケージ管理ツールでコマンドを打ち込むことで、何ひとつ考えなくてもインストールは完了し、常に最新版に更新することができる。これはMicrosoftのやっている「Windows Update」と同様だが、本当はOSだけではなく「パッケージ全てを一発で更新できる」という特徴がある。
また、リポジトリの設定を変えることでDebianならばstableからsidに「ディストリビューションのバージョンを更新」することができるし、Red Hatでもリポジトリを追加することで「Red Hat以外のサーバーのサードパーティのリポジトリ」からパッケージをインストールすることもできる。これはGoogle Chromeのような「一部オープンソースでないアプリケーション」にも適用できる。
ただ、これは二つの知っておくべき点がある。一つは、「パッケージには必ずメンテナが居る」ということ。ボランティアのパッケージのバージョンを上げたりインストールに必要なコマンドをきちんと明記してくれる、善意のメンテナが居るから、Debianのような膨大な数のパッケージも、常にきちんと動く状態になる。これは、商用のディストリビュータ会社が多い理由でもある。会社が金でやるのであれば、全てのRPMを管理する下っ端のプログラマを雇うことが出来る。Fedoraのようなコミュニティのディストリビューションも、メンテナはほとんどが母体となる会社の従業員である。
もう一つの問題は、「パッケージを開発者でもユーザーでもない、第三者が再配布しなければ、パッケージ管理システムは成り立たない」ということである。膨大なパッケージがDebianのリポジトリに登録されているものの、それは元の開発者でもなく、使うユーザーでもない、「第三者のボランティア」がやっている。このため、たとえば実際には使ったこともないのにパッケージメンテナになっていたり、あるいは、セキュリティや致命的なバグの修正はマイナーディストリビューションでは遅れることやきちんとやっていないことがある。
だが、これらの問題は最近、FlatpakやSnappyなどの「アプリケーション仮想化ツール」が新しい実験を始めている。ディストリビュータのメンテナがパッケージを提供するのではなく、Windowsのフリーソフトのように、ディストリビューションのパッケージ管理システムとは別の、仮想的な導入しやすいパッケージの配布の形態をし、そのパッケージの配布や管理はそれぞれのソフトウェアのプロジェクトが「じかに行う」というものである。また、最近はFlatpakはさらに発展しており、flathubというFlatpak向けのパッケージ集積サイトがある。こうした場所からパッケージを導入することで、システムのパッケージとは別に最新のアプリケーションを簡単に導入できる。詳細はFlatpakやSnappyを参照のこと。
ただし、パッケージ管理システムは、Linuxだけのものではない。最近はJavaScriptのパッケージ管理システムや、マイナーなところではEmacsのパッケージ管理システムもあるし、Rubyのような日本のプロジェクトでも、同様のパッケージ管理システムのようなものは生まれている。Macにもパッケージ管理システムはあるし、WindowsだってWindows Updateは用意している。Windowsの場合、さまざまなプロジェクトがクローズドソースでプログラムを作っているため、統一されたリポジトリで再配布とするのは難しい。このため、Firefoxだろうが、WinSCPだろうが、あるいはGitだろうが、Windowsの場合はそれぞれのソフトウェアの流儀に従うしかない。これを「手間」だと見るか、あるいは「独立性」と見るかは人それぞれである。Linuxも便利とは言うが、全くクローズドソースなソフトウェアのことは考えていない。そもそもフォトショやイラレのような商用アプリケーションは動かない。それを「動かない」と見るか、「純粋に全て無料であることが保証されていてありがたい」と見るかも、人それぞれである。
そもそも、パッケージ管理システムの何が良いかと言うと、「依存関係を解決してくれる」ことだ。
さまざまなライブラリやコンポーネントを使うプログラムをインストールしたい場合、あるコンポーネントがなければ、そのプログラムは動作しない。これを依存関係と言う。
これを手動コンパイルでインストールしようとすると、さまざまな複雑な依存関係があらわになって、ディストリビューションを開発したい場合などでは、絶対に動かないようなわけのわからないことになってしまう。
多くのシステムが、依存関係の解決ができないことによって、破壊されてきた。
だが、RPMなどのパッケージ管理システムでは、パッケージの依存関係を計算して、自動的に「これはインストールしても動く」「これはインストールしても動かない」ということを簡単に確認できる。
RPMが生まれたことによって、ディストリビューションの開発が容易になった。一部のオタクやマニアでなくても、動くLinuxシステムを構築することができるようになった。
また、Debianのapt-getのようなパッケージ管理システムのネットワークインストールツールを使って、「必要なパッケージを全部自動でネットワークから取得してインストールしてくれる」ようなツールが生まれた。これによって、firefoxを使う場合は、「apt install firefox」と実行するだけで、面倒なこと全てを自動でやってくれる。オープンソースなので、リポジトリのあるミラーサーバーを経由することで、自分でさまざまなWebサイトにアクセスしてダウンロードしなくても、コマンド一発でリポジトリからダウンロードしてくれる。
この方式の長所はもう一つあって、それは「パッケージ全てを簡単に最新版に保つことが出来る」ということだ。Debianの安定板なら、致命的なバグとセキュリティがfixされたパッケージを、apt update && apt upgradeで簡単に最新版にすることもできる。ほとんどのオープンソースソフトウェアは、リポジトリにパッケージがあるため、お金もかからず、簡単に最新版に出来る。
そして、パッケージのメンテナが見ると、「ソースパッケージ」を使うことで、バイナリのビルドが自動化出来る。この方式はとても画期的で、GentooのPortageでは、USEフラグを設定することで、ほとんど自動的にバイナリパッケージをソースパッケージから構築出来る。
もう一つの利点は、システム全体をクリーンに保つことが出来るということ。パッケージの依存関係は、インストール時だけではなく、アンインストール時にも働く。少し前は出来なかった「不要になった依存パッケージのアンインストール」は、最近はどのパッケージ管理システムでも出来るようになった。Fedoraのyum/dnfなどでは、history機能を使って、その時インストールした全てのパッケージを、全部簡単にundoすることが出来る。システムが壊れる心配もない。
パッケージ管理システムは好評だが、Windowsに比べると、手動で管理する余地が少ないと感じられるかもしれない。Windowsはそれぞれがインストール導入システム(InstallShieldなど)を使っているが、この方式は、個人のフリーソフト作成者などからすると、簡単にインストールしたパッケージをすぐにアンインストール出来るし、.zipなどで配布されている場合は、圧縮ファイルからフォルダを解凍して.exeを実行するだけで簡単にプログラムが実行できる。こうした方式の長所はLinuxでも最近取りいれられていて、AppImageやflatpakやsnappyのようなアプリケーション仮想化システムでは、簡単にアプリケーションイメージをダウンロードしてすぐにインストールできる仕組みを開発している。この方式が上手く働けば、ディストリビューションがわざわざ「第三者が介入して」パッケージをリポジトリに提供しなくても、アプリケーション開発者とユーザーの間で簡単にフリーソフトの配布ができるようになるだろう。
元の話に戻ると、パッケージ管理システムは、雨後の竹の子のようにいくらでも増えている。RPM/Yum (Red Hat), Deb/Apt (Debian), Portage (Gentoo) などの主要なものだけではなく、zypper (openSUSE), Pacman (Arch), マイナーなところではGuixなどいくらでもある。どうでも良いほど増えているが、それは「自分のディストリビューションを作りたい」という一向に増え続けるニーズのためだ。だが、パッケージ管理システムは「とてもたくさんのパッケージを一人でメンテナンスできるわけがない」というところもある。Debianなどの大手ディストリビュータでは可能だろうが、マイナーなところではとても管理しきれず、Vine Linuxのようなディストリビューションは全く管理できていないし、FedoraのようなところではChromiumのような「アップデートしまくるパッケージ」は最初からきちんと管理していない。Linux Mintなどでは、「Ubuntuとリポジトリを共有する」という賢い解決策を取っている。こうした意味から言っても、ディストリビューションの乱立のしすぎは、利用者にとってあまり良いことではない。
後日注記:Windowsについて言えば、コントロールパネルのプログラムのアンインストールからパッケージを削除することはできる。だが、たとえばVisual Studioなどをインストールする場合、必要なパッケージが大量にインストールされてしまい、後で消すことができなくなる。消そうとした場合、パッケージを間違えて削除してしまい、結果システムが壊れることがある。Linuxもこれと同じで、パッケージ管理システムがなければ、巨大システムは簡単に、その時点で「一瞬の靄のように」破壊されてしまう。よって、パッケージ管理システムは、サーバーやエンタープライズなどシステムを破壊してはならない場合には必須である。
パッケージ管理システムとリポジトリのメリットは、「コマンド一発で、システムの(パッケージ管理システムでインストールした)全アプリケーションの安全性が保たれる」ということ。
たとえば、Windowsなどの場合、WindowsのOSのセキュリティホールはWindows Updateで修正されても、WinSCPやFirefoxまでは修正してくれない。それぞれのアプリケーションを最新にする努力が必要だ。
Linuxでは、その努力は必要ない。ディストリビューションのリポジトリがセキュリティホールを修正したバージョンをミラーサイトにリリースするため、コマンドを一発実行するだけで、FirefoxからGIMPまで、全てのアプリケーションのセキュリティホールを修正してくれる。これは、オープンソースのなせる業(再配布・修正が可能)である。
これは、サーバーシステムなどでは特にありがたい機能で、ApacheからPHP、MySQLまで、全てのコンポーネントを一気にアップデートできる。
だが、これはもろ刃の剣で、システムが破損する可能性を常に持っている。Debianなどでは、セキュリティホールと致命的なバグをアップデートするだけで、ローリングリリースのように、機能が増えAPIの変わった最新のバージョンにすることはないため、比較的安心できる。だが、ローリングリリースのArchや、とにかく最新にしたがるFedoraでシステムを作るのはやめた方が無難だろう。
パッケージの更新は、コマンドラインから行うこともできるほか、aptitudeを使ってメニュー形式でインストールしたり、PackageKitなどを使ってGUIからも行うことが出来る。また、ネットワークからSSHでパッケージ更新をかけることも出来る。他には、cronで定期的に実行する専用のパッケージをインストールすることで、ほとんど何もしないで管理することもできる。
最近は、Dockerという仮想化コンテナも普及している。ホストのLinuxカーネルを共有した上で、いくらでもLinuxのシステムを仮想的にコンテナの上で構築できる。この場合は、Dockerfileにソフトウェア情報を書けば良い。便利な世の中だが、どんどん複雑化しているため、15年前の僕の知識で対応できるかどうかは怪しい。クラウド環境(Amazon EC2など)でサーバーインフラを貸してもらうこともできるだろう。
後日注記:実際にはLinuxでもソースtarballからパッケージをインストールする場合は多く、この場合は自分の手でパッケージを更新しなければならないため、なかなか全自動でシステムを更新し管理するというのは難しい。よって、セキュリティ情報は日ごろから注視しておかなければならないが、Debianなどではメーリングリストなどでセキュリティ関係のMLを購読することで、こうした情報を知ることができる。
Red Hat系のパッケージ管理システム。
RPMを参照のこと。
Red Hat系の高度なパッケージ管理ツール。
DNF/Yumを参照のこと。
Debian系のパッケージ管理システム。
Deb/Dpkgを参照のこと。
Debian系の高度なパッケージ管理ツール。
Aptを参照のこと。
openSUSEのパッケージ管理ツール。
SUSEを参照のこと。
openSUSEの設定ツール。統合されていて使いやすいと評判。
Mandriva Linuxのパッケージ管理ツール。
Gentoo Linuxのソースベースのパッケージ管理システム。何でもかんでも最適化コンパイルが出来、バイナリ形式ではないため、さまざまなアーキテクチャに対応させやすい。
Gentooを参照のこと。
Arch Linuxのパッケージ管理システム。
Arch Linuxを参照のこと。
Lispによるパッケージ管理システム。
パッケージのフォーマットを変換する。RPM形式をDeb形式にしたりtgz形式にしたりすることができる。
Linuxサーバーのセキュリティを学ぼう (1/3) - @ITの記事のページ3にあるように、yum-cronというパッケージをインストールすることで、自動で定期的にOSがアップデートされるようになる。ただ、システムが壊れるリスクもあるので注意が必要だ。
Debianなら、unattended-upgradesが使える。
UNIXシステム管理(cron)も参照のこと。
AppImage/Flatpak/Snappyを使うことで、システムのパッケージとは別に、仮想サンドボックス化されたどのディストリビューションにも入れられる手軽なパッケージを導入できる。パッケージの集約サイトであるflathubやsnapcraftなどを利用することも可能。
Flatpak/AppImageやSnappyを参照のこと。
最近では、Dockerというコンテナ型仮想化システムにより、Dockerfileでシステムイメージを作成し、Docker Hubのような場所でイメージを簡単に入手して、docker runでコンテナを起動することができる。
これにより、たとえばMySQLを使いたい場合は、自分で面倒な導入作業や設定作業を行わなくても、Dockerで簡単にコンテナイメージを起動できる。
MySQLコンテナやRailsコンテナを簡単に導入でき、どの環境でも同じ環境で開発が行えるほか、それぞれに仮想マシンを割り当てて、簡単にスクラップ・ビルドができる。
Dockerを参照のこと。
また、Gitを用いることで、従来ソースパッケージなどを用いて行っていた、「オープンソースの開発への参加」が簡単になった。
ソースコードがGitHubなどで公開されている場合、簡単にgit cloneでそれをローカルにコピーできる。コミットするだけで開発でき、プルリクエストすればマージされることも期待できる。
gitやDockerの普及とともに、従来のパッケージ管理システムを使うのではなく、もっと簡単・高度にソフトウェアを導入・管理することが可能になってきている。
Gitを参照のこと。
僕は、「システム指向」ではなく、「ログ指向」のパッケージ管理、ということをやってはどうかと思う。
たとえば、パッケージXの依存関係でYをインストールした時、「2019.05.17にパッケージXの依存関係でYをインストール」という情報を残しておき、パッケージYを削除したい時は、「このパッケージYは2019.05.17にパッケージXの依存関係としてインストールされました。本当に削除しますか?」のようなメッセージを表示する。
システムの何に必要かという情報を残すだけではなく、過去にどのような目的でインストールしたかという行動をログとしてパッケージ管理に残して追跡することで、「なんでこのパッケージをインストールしたのだろう」と忘れて疑問に思っても、パッケージ管理システムがそれを覚えていてくれる。パッケージの管理がしやすくなって画期的ではないかと思う。
機能として、その時インストールした全てのパッケージをリスト表示したり、システムを壊さない範囲でその時インストールした全てのパッケージを一括でアンインストールしたり、ということができると良いだろう。また、今までインストールしたパッケージの履歴を一覧表示し、セッションや日付ごとに管理できるようなGUIを持ったフロントエンドを作っても良い。
Debianでは、ディストリビューションをインストールする際に、千を超えるほどのパッケージが自動的にインストールされます。
この時、それらひとつひとつのパッケージに、メンテナンスをしているメンテナがいることを忘れないようにしましょう。
パッケージのメンテナが、それぞれのソフトウェアを簡単に導入できるようなパッケージにしてくれているからこそ、Debianは動くのです。
パッケージのメンテナに感謝を忘れないようにしましょう。彼らは、あなたがDebianを使えるように、ボランティアで多大なる努力と貢献をわたしたちのために捧げてくれているのです。
2023.06.16
ソースからのインストールを参照のこと。
diffとpatchについてはdiffとpatch・テキスト処理を参照のこと。