PK
パーネルカニック研究所
今日もどこかでkernel panic。
root@pk-lab:~#

nginxをソースからビルドする

連載ナビ

この連載は「Linuxを使えるようになる」ではなく、「Linuxがどう動いているのか」を理解するための実践シリーズです。

今回は Linuxを理解する 〜 LFSで学ぶLinux内部構造 〜 の Part 7 / 第1回として、仕組みのつながりを意識しながら学びます。

—

apt install nginx の裏側は「configure → make → make install」でできている

パッケージマネージャでインストールされるnginxも、元をたどれば誰かがソースコードからビルドしたものです。結論から言うと、ソースビルドの工程は次の3段階で、これはLFSで約90個のパッケージに対して繰り返してきた手順とまったく同じです。

1. ./configure — ビルド環境を調査し、必要なライブラリの有無を確認して、Makefileを生成する。インストール先や有効にする機能もここで決める

2. make — Makefileに従ってソースをコンパイルし、実行バイナリを作る

3. make install — できあがったバイナリ・設定ファイル・ディレクトリ一式を、configure で指定した場所に配置する

今回はこの手順でnginxを自分でビルドし、apt install が一瞬で終わらせている「依存解決」と「配置」を、すべて自分の目で確認します。

nginxは単体では成立せず、3つのライブラリに依存しているから

なぜソースビルドをわざわざ体験するのか。理由は、nginxの主要機能が外部ライブラリへの依存で成り立っており、その関係はパッケージ導入では絶対に見えないからです。

nginxが標準的な構成でビルド時に要求する代表的なライブラリは3つです。

ライブラリ nginxでの役割 無いと起きること
PCRE (PCRE2) location ディレクティブなどの正規表現処理 rewriteモジュールが組み込めず configure が失敗
zlib gzip圧縮(gzip on;) gzipモジュールが組み込めず configure が失敗
OpenSSL HTTPS/TLS(--with-http_ssl_module 指定時) SSLモジュールが組み込めず configure が失敗

apt install nginx では、これらは「依存パッケージ」として自動的に一緒に入るため、存在にすら気づきません。しかしソースビルドでは、ライブラリが足りなければ configure がその場で止まり、「nginxが何に支えられて動いているか」を否応なく突きつけられます。この依存関係の理解は、本番で ldd の結果を読むときや、Alpineベースの軽量イメージでビルドが通らないとき(Part 1で見たglibc/muslの違い)に、そのまま効いてきます。

実際にビルドする — configureのエラーも含めて体験する

Ubuntu系のVMで実際にやってみます。まず、あえて依存を入れずに configure を実行して、エラーを見るところから始めるのがおすすめです。


# 1. ビルドに最低限必要なコンパイラ類
sudo apt update && sudo apt install -y build-essential

# 2. ソースコードの取得と展開(バージョンは nginx.org で最新のstable版を確認)
curl -O https://nginx.org/download/nginx-1.26.2.tar.gz
tar xzf nginx-1.26.2.tar.gz
cd nginx-1.26.2

# 3. まずはそのまま configure してみる
./configure --prefix=/usr/local/nginx

依存ライブラリが無い環境では、configure は途中でこう言って止まります。


./configure: error: the HTTP rewrite module requires the PCRE library.
You can either disable the module by using --without-http_rewrite_module
option, or install the PCRE library into the system ...

これが「nginxはPCREに依存している」ことの実物です。エラーメッセージが「モジュールを無効化するか、ライブラリを入れるか」という選択肢まで提示してくれている点にも注目してください。今回はライブラリを入れて先へ進みます。


# 4. 開発用ヘッダ付きのライブラリ(-dev パッケージ)を導入
sudo apt install -y libpcre2-dev zlib1g-dev libssl-dev

# 5. HTTPS対応を有効にして configure をやり直す
./configure --prefix=/usr/local/nginx --with-http_ssl_module

# 6. コンパイルとインストール
make
sudo make install

configure が成功すると、最後にインストール先のパス一覧(nginx binary: "/usr/local/nginx/sbin/nginx" など)が表示されてから Makefile が生成されます。make は数分で完了し、sudo make install で /usr/local/nginx 以下に配置されます。

なお、実行時に必要なのは通常のライブラリなのに、ビルド時に -dev パッケージが要るのは、コンパイル時にはライブラリ本体に加えてヘッダファイル(関数の宣言)が必要だからです。これもLFSで散々向き合った「ビルド時依存と実行時依存の違い」そのものです。

成果物を検証する — ldd と nginx -V で「何とリンクされたか」を見る

ビルドが終わったら、できあがったバイナリを調べます。まず、Part 1のエラー調査でも使った ldd です。


ldd /usr/local/nginx/sbin/nginx

        linux-vdso.so.1 (0x0000...)
        libcrypt.so.1 => /lib/x86_64-linux-gnu/libcrypt.so.1 (0x0000...)
        libpcre2-8.so.0 => /lib/x86_64-linux-gnu/libpcre2-8.so.0 (0x0000...)
        libssl.so.3 => /lib/x86_64-linux-gnu/libssl.so.3 (0x0000...)
        libcrypto.so.3 => /lib/x86_64-linux-gnu/libcrypto.so.3 (0x0000...)
        libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x0000...)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x0000...)

先ほどの表の3つ(PCRE・zlib・OpenSSL)が、共有ライブラリとして実際にリンクされていることが確認できます。もう1つ、実務で頻出のコマンドが -V です。


/usr/local/nginx/sbin/nginx -V

バージョンとともに configure arguments: --prefix=/usr/local/nginx --with-http_ssl_module と表示されます。これはそのバイナリがどのオプションでビルドされたかの完全な記録で、「本番のnginxにこのモジュールは入っているか?」を調べる標準手段です。ソースビルドを一度やっておくと、この出力の意味が正確に読めるようになります。

ビルドの3工程を知れば、ミドルウェアの障害切り分けが変わる

nginxのソースビルドは「configure(依存確認とMakefile生成)→ make(コンパイル)→ make install(配置)」の3工程であり、PCRE・zlib・OpenSSLへの依存は configure のエラーと ldd の出力で実際に確認できる——これが今回の結論です。

バイナリはできましたが、まだ起動していません。次回はいよいよ最終回。このnginxを起動し、プロセス・ポート・HTTP応答の3層で動作を確認して、シリーズの総仕上げとします。

図解テキスト


nginx source (nginx.org)
  -> ./configure --prefix=... --with-http_ssl_module
       … 依存確認 (PCRE / zlib / OpenSSL) + Makefile生成
  -> make          … コンパイル
  -> make install  … /usr/local/nginx へ配置
  -> nginx binary  … ldd / nginx -V で検証

この回で実行するコマンド

上から順番に実行すれば、この回の内容を体験できます。

まずはそのままコピペして実行し、次に1行ずつ意味を確認してください。


sudo apt update && sudo apt install -y build-essential libpcre2-dev zlib1g-dev libssl-dev
curl -O https://nginx.org/download/nginx-1.26.2.tar.gz
tar xzf nginx-1.26.2.tar.gz
cd nginx-1.26.2
./configure --prefix=/usr/local/nginx --with-http_ssl_module
make
sudo make install
ldd /usr/local/nginx/sbin/nginx
/usr/local/nginx/sbin/nginx -V

ハンズオン手順

1. ターミナルを開いて、上のコマンドを1行ずつ実行する

2. configure の出力の最後に表示されるインストール先パス一覧をメモする

3. ldd の出力から、PCRE・zlib・OpenSSLに対応する行を探して印をつける

4. nginx -V の configure arguments: が自分の指定と一致することを確認する

5. エラーが出たら、そのエラーメッセージをそのまま残す(特に configure のエラーは全文が手がかり)

チェックポイント

  • コマンドが最後まで実行できた
  • configure / make / make install がそれぞれ何をする工程か説明できる
  • ビルド時に -dev パッケージが必要な理由を言える
  • 次の回に進む前に、分からない単語を1つ調べた

今回理解できたこと

  • nginxはPCRE・zlib・OpenSSLという依存ライブラリとセットで成立している
  • configureは依存確認とMakefile生成、makeはコンパイル、make installは配置を担当する
  • ldd と nginx -V で「何とリンクされ、どうビルドされたか」を後からでも確認できる