そのNginx、「吊るしのスーツ」のままでいいの?
こんにちは!「LINUX工房」管理人の「リナックス先生」です。
前回は、PrometheusとGrafanaを使って、サーバーの健康状態を可視化する環境を整えました。
これで運用はバッチリです。
しかし、監視画面を見ていると気づくはずです。
「もっとレスポンスを速くできないか?」「使っていない機能がメモリを食っているのではないか?」
パッケージ管理ツール(dnf や apt)で入れたNginxは、あらゆるユーザーに対応するために「全部入り」の状態で作られています。
それは便利ですが、あなたにとって不要な機能も山盛りです。
先生、最近Googleのサイトとか見ると、圧縮形式が「gzip」じゃなくて「br(Brotli)」になってるんですけど、あれってNginxで使えないんですか?
設定ファイルに書こうとしたら「unknown directive」って怒られちゃって…。
あと、サーバーのヘッダー情報から「Nginx」って文字自体を消したいんですけど、それも無理みたいで。
いいところに気がついたわね。
Brotli圧縮やヘッダーの完全削除は、標準のパッケージ版Nginxには含まれていない機能なの。
それを使いたければ方法は一つ。
「ソースコードから自分でビルド(コンパイル)する」しかないわ。
自分だけのオーダーメイドNginxを作る、エンジニアとしての至高の領域へ案内するわよ!
本記事では、Nginxをソースコードからコンパイルする詳細な手順、Googleが開発した次世代圧縮「Brotli」の組み込み、不要なモジュールの削除、そして稼働中のサーバーを止めずにバイナリを入れ替える「無停止アップデート」の手法までを徹底解説します。
🚀 Nginx応用講座(全8回)カリキュラム
現在地:【第7回】動的モジュールとカスタムビルド。必要な機能だけを組み込む軽量化テクニック
- 【第1回】大規模負荷分散とキャッシュ戦略。数万リクエストをさばく「Proxy Cache」と「Upstream」の極意
- 【第2回】WAF(Web Application Firewall)の構築。ModSecurityと最新のNginxセキュリティ
- 【第3回】マイクロサービス時代のルーティング。gRPC、WebSocket、認証プロキシ(auth_request)の統合
- 【第4回】Nginxをプログラマブルに。Lua言語(OpenResty)による動的処理と機能拡張
- 【第5回】絶対停止させない高可用性(HA)。KeepalivedによるVIP管理とフェイルオーバー
- 【第6回】可観測性(Observability)の確保。Prometheus/Grafana連携とカスタムメトリクス
- 【第7回】動的モジュールとカスタムビルド。必要な機能だけを組み込む軽量化テクニック
- 【第8回】Kubernetes Ingress Controller入門。クラウドネイティブ時代のNginx運用
※基本講座の復習はこちら:Nginx基本講座(全8回)アーカイブ
第1章:なぜ「ビルド」するのか? パッケージ版の限界
通常、Linuxでソフトウェアを入れる時は dnf install nginx で終わります。
しかし、プロの現場ではあえてソースコードからビルドするケースがあります。
カスタムビルドのメリット
- サードパーティモジュールの追加: 公式には含まれていない機能(Brotli圧縮、Headers More、ModSecurityなど)を追加できる。
- 軽量化・セキュリティ向上: 使わない機能(例:メールプロキシ機能、autoindex機能など)をコンパイル段階で除外することで、バイナリサイズを減らし、攻撃面(Attack Surface)を最小化できる。
- 最新版の利用: ディストリビューションのパッケージ更新を待たずに、最新のセキュリティパッチや機能を即座に適用できる。
- パス構成の自由化: インストール先やログの出力先を自社の規定に合わせて自由に変更できる。
デメリット(覚悟すべきこと)
- 管理の手間:
dnf updateで自動更新されません。脆弱性が見つかったら自分で再ビルドして入れ替える必要があります。 - ビルド環境の維持: コンパイラやライブラリの依存関係を自分で管理する必要があります。
このデメリットを上回るメリットがある場合のみ、ビルドに踏み切ります。
今回は「Brotli圧縮による高速化」と「不要機能の削除」を目的として進めます。
第2章:ビルド環境の準備とソースコードの取得
まずはコンパイルに必要な道具を揃えます。
※環境は AlmaLinux 9 を想定しています。
1. 必須ライブラリのインストール
Cコンパイラ(gcc)や、Nginxが依存するライブラリ(PCRE, OpenSSL, zlib)の開発用パッケージを入れます。
# 開発ツール群の一括インストール sudo dnf groupinstall "Development Tools" # 依存ライブラリのインストール sudo dnf install pcre-devel zlib-devel openssl-devel libxml2-devel libxslt-devel gd-devel perl-ExtUtils-Embed
2. ソースコードのダウンロード
Nginx公式サイトから最新のMainline版(執筆時点では1.27.x系を想定)をダウンロードします。/usr/local/src で作業するのが一般的です。
cd /usr/local/src sudo wget http://nginx.org/download/nginx-1.27.0.tar.gz sudo tar -zxvf nginx-1.27.0.tar.gz
3. サードパーティモジュールの準備
今回は以下の2つのモジュールを組み込みます。
- ngx_brotli: GoogleのBrotli圧縮を使うためのモジュール。
- headers-more-nginx-module: レスポンスヘッダーを自在に操るモジュール。
# Brotliモジュールの取得(サブモジュールも必要) sudo git clone --recurse-submodules https://github.com/google/ngx_brotli.git # Headers Moreモジュールの取得 sudo git clone https://github.com/openresty/headers-more-nginx-module.git
第3章:configureオプションの魔術(設計図を書く)
ビルドの最重要工程、./configure です。
ここで「何を入れて、何を入れないか」を決定します。
プロのテクニック:既存設定のコピー
ゼロからオプションを書くのは大変です。
既にパッケージ版Nginxが入っているなら、nginx -V コマンドで現在の構成を確認し、それをベースにするのが定石です。
nginx -V # 出力例: configure arguments: --prefix=/etc/nginx ...
今回の最強構成オプション
ディレクトリを nginx-1.27.0 に移動して実行します。
以下の例では、メール機能や古いモジュールを削ぎ落とし、Brotliなどを追加しています。
cd nginx-1.27.0
sudo ./configure \
--prefix=/etc/nginx \
--sbin-path=/usr/sbin/nginx \
--modules-path=/usr/lib64/nginx/modules \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--pid-path=/var/run/nginx.pid \
--lock-path=/var/run/nginx.lock \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--without-mail_pop3_module \
--without-mail_imap_module \
--without-mail_smtp_module \
--without-http_autoindex_module \
--without-http_geo_module \
--without-http_split_clients_module \
--without-http_uwsgi_module \
--without-http_scgi_module \
--add-module=../ngx_brotli \
--add-module=../headers-more-nginx-module
- –with-xxx: 標準では無効だけど有効にしたい機能(SSL, HTTP/2など)。
- –without-xxx: 標準で有効だけど無効にしたい機能(Mail, Autoindexなど)。
- –add-module: サードパーティモジュールのパスを指定。
エラーが出なければ、Makefileが生成されます。
コンパイルとインストール
sudo make # ここで数分待ちます sudo make install
これで、/usr/sbin/nginx に特製バイナリが配置されました!
第4章:Brotli圧縮とヘッダー削除の設定
せっかく組み込んだ機能を設定ファイルで有効化しましょう。
1. Brotli圧縮の有効化
nginx.conf の http ブロックに記述します。
gzipよりも圧縮率が高く、表示速度がさらに向上します。
http {
# Gzip設定(Brotli非対応ブラウザ用)
gzip on;
# Brotli設定
brotli on;
brotli_comp_level 6; # 1-11。6が推奨(速度と圧縮率のバランス)
brotli_static on; # .brファイルがあればそれを配信
brotli_types text/plain text/css application/javascript application/json image/svg+xml application/xml+rss;
}
2. Serverヘッダーの隠蔽
通常、レスポンスヘッダーには Server: nginx/1.27.0 のようにバージョンが含まれ、攻撃のヒントになります。server_tokens off; だけでは「Server: nginx」までは消せません。
Headers Moreモジュールなら完全に消せます。
http {
# Serverヘッダーを空にする(削除)
more_clear_headers Server;
# または偽装する
# more_set_headers 'Server: MyCustomServer';
}
第5章:動的モジュール(Dynamic Modules)の活用
「再ビルドのたびにNginx全体をコンパイルするのは面倒…」
そんな時は、モジュールだけを別ファイル(.so)としてビルドする「動的モジュール」を使います。
ビルド方法
configure 時に --add-module ではなく --add-dynamic-module を使います。
./configure ... --add-dynamic-module=../ngx_brotli
make modules を実行すると、objs/ ディレクトリに ngx_http_brotli_filter_module.so などが生成されます。
これを /usr/lib64/nginx/modules/ にコピーし、nginx.conf で読み込みます。
load_module modules/ngx_http_brotli_filter_module.so; load_module modules/ngx_http_brotli_static_module.so;
これで、本体のバイナリを入れ替えずに機能追加が可能になります(ただし、バイナリ互換性には注意が必要です)。
第6章:究極の奥義「無停止アップデート(On-the-fly Upgrade)」
「脆弱性が見つかったからNginxをバージョンアップしたい。でもサービスは止めるなと言われている」。
そんな無理難題を解決するのが、Nginxの無停止アップデート機能です。
古いプロセスがリクエストを処理している横で、新しいプロセスを立ち上げ、徐々に切り替えていく神業です。
手順1:新しいバイナリの配置
新しいバージョンでビルドしたバイナリを、既存の /usr/sbin/nginx に上書きします。
(念のため、古いバイナリは nginx.old としてバックアップしておきます)
sudo mv /usr/sbin/nginx /usr/sbin/nginx.old sudo cp objs/nginx /usr/sbin/nginx
手順2:USR2シグナルの送信
現在動いているマスタープロセスに対し、「新しいバイナリで新しいマスタープロセスを起動せよ」と命じます。
# マスタープロセスのPIDを確認 ps aux | grep nginx # root 1234 ... nginx: master process # USR2シグナル送信 sudo kill -USR2 1234
この時点で、プロセスリストには「新旧2つのマスタープロセス」と「それぞれのワーカープロセス」が共存しています。
新しいリクエストは両方に振り分けられる可能性があります。
手順3:WINCHシグナルの送信
古いマスタープロセスに対し、「ワーカープロセスを優雅に停止せよ(Graceful Shutdown)」と命じます。
sudo kill -WINCH 1234
古いワーカーは、現在処理中のリクエストが終わり次第終了します。
最終的に「古いマスター(待機中)」と「新しいマスター&新しいワーカー」の状態になります。
これですべての処理が新しいバイナリに切り替わりました。
手順4:完了(または切り戻し)
問題なければ、古いマスタープロセスを停止します。
sudo kill -QUIT 1234
もし新しいバージョンで不具合が出た場合は、HUP シグナルを古いマスターに送ることで、古いワーカーを復活させ、新しいマスターを停止することで瞬時に切り戻せます。
第7章:Systemdユニットファイルの作成
ソースビルドした場合、systemctl コマンド用の設定ファイルは自動生成されません。
自分で作成する必要があります。
sudo vi /usr/lib/systemd/system/nginx.service
[Unit] Description=The NGINX HTTP and reverse proxy server After=syslog.target network-online.target remote-fs.target nss-lookup.target Wants=network-online.target [Service] Type=forking PIDFile=/var/run/nginx.pid ExecStartPre=/usr/sbin/nginx -t ExecStart=/usr/sbin/nginx ExecReload=/usr/sbin/nginx -s reload ExecStop=/bin/kill -s QUIT $MAINPID PrivateTmp=true [Install] WantedBy=multi-user.target
作成後、反映させます。
sudo systemctl daemon-reload sudo systemctl enable nginx
これで、自作ビルド版NginxもOS標準の作法で管理できるようになりました。
まとめ:自分だけの最強Nginxを手に入れろ
お疲れ様でした!
今回は、Nginx運用の最高峰、カスタムビルドと無停止アップデートについて解説しました。
今回の重要ポイント:
configureで不要な機能を削ぎ落とし、セキュリティとパフォーマンスを高める。--add-moduleでBrotliなどの強力なサードパーティ機能を追加する。USR2とWINCHシグナルを駆使すれば、サービスを止めずに更新できる。- Systemdユニットファイルを自作して、運用を効率化する。
ここまで到達したあなたは、もう「Nginxを使っている人」ではなく「Nginxを完全に支配した人」です。
どんな要件が来ても、ソースコードレベルで対応できる自信がついたはずです。
さて、全8回の講座もいよいよ次で最終回です。
最後は、現代のインフラ技術の到達点、「Kubernetes(K8s)」の世界へ飛び込みます。
これまでの知識(LB、WAF、Lua、ビルド)が、コンテナオーケストレーションの中でどう活きるのか。
Nginxが果たす「Ingress Controller」という重要な役割について学びましょう。
次回、第8回(最終回)は「Kubernetes Ingress Controller入門。クラウドネイティブ時代のNginx運用」です。
コンテナ時代のトラフィック制御をマスターし、インフラエンジニアとしてのキャリアを完成させましょう。お楽しみに!
▼ カスタムビルド環境を手に入れる ▼
コンパイルを試す
「VPS」で自分専用環境
高度な技術を持つ企業へ
「ITエンジニア転職」


コメント