はじめに:なぜNginxなのか

Nginx(エンジンエックス)は、世界中のウェブサイトの約34%が使用しているウェブサーバーで、Apacheと並んで二大勢力を形成しています。2004年にロシアの開発者Igor SysoevがC10K問題(同時接続1万コネクションの処理)を解決するために設計したNginxは、イベント駆動(event-driven)非同期アーキテクチャを採用し、少ないメモリで大量の同時接続を処理できます。

実務においてNginxは単なるウェブサーバーを超え、リバースプロキシロードバランサーAPIゲートウェイキャッシュサーバーなど多様な役割を果たします。特にコンテナ環境やマイクロサービスアーキテクチャが普及するにつれ、Nginxの重要性はますます高まっています。

このガイドでは、Nginxのインストールから実戦運用に必要なすべての設定を体系的に解説します。初心者でも実践できる基本設定から、実務で必ず知っておくべき高度な設定まで、実際の設定ファイル例とともに詳しく説明します。

1. Nginxのインストール

1.1 Ubuntu/Debian系のインストール

# パッケージリストを更新してインストール
sudo apt update
sudo apt install nginx -y

# バージョン確認
nginx -v

# サービスの起動と自動起動の登録
sudo systemctl start nginx
sudo systemctl enable nginx

# ステータス確認
sudo systemctl status nginx

1.2 RHEL/CentOS/Rocky Linux系のインストール

# EPELリポジトリの追加 (CentOS 7)
sudo yum install epel-release -y
sudo yum install nginx -y

# Rocky Linux 9 / RHEL 9
sudo dnf install nginx -y

# サービスの起動と自動起動の登録
sudo systemctl start nginx
sudo systemctl enable nginx

# ファイアウォールの許可
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

1.3 公式Nginxリポジトリから最新版をインストール

ディストリビューション標準リポジトリのNginxはバージョンが古い場合が多いです。最新機能が必要な場合は公式リポジトリを追加します:

# Ubuntu - Nginx公式リポジトリの追加
sudo apt install curl gnupg2 ca-certificates lsb-release -y

# 署名キーの追加
curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo gpg --dearmor -o /usr/share/keyrings/nginx-archive-keyring.gpg

# リポジトリの追加 (stable)
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/ubuntu $(lsb_release -cs) nginx" | sudo tee /etc/apt/sources.list.d/nginx.list

# インストール
sudo apt update
sudo apt install nginx -y
TIP: 公式リポジトリのNginxにはmainline(最新機能、奇数バージョン)とstable(安定版、偶数バージョン)の2つのトラックがあります。本番環境ではstableを推奨します。

1.4 インストールの確認

# ブラウザで確認: http://サーバーIP
# またはコマンドラインで確認
curl -I http://localhost

# インストールパスの確認
nginx -V    # コンパイルオプションとモジュールの確認
nginx -t    # 設定の構文検証

2. Nginxのディレクトリ構造と設定ファイル

2.1 主要ディレクトリ構造

パス 説明
/etc/nginx/ メイン設定ディレクトリ
/etc/nginx/nginx.conf メイン設定ファイル(すべての設定の起点)
/etc/nginx/conf.d/ 追加設定ファイル(*.confを自動読み込み)
/etc/nginx/sites-available/ 利用可能なサイト設定(Ubuntu)
/etc/nginx/sites-enabled/ 有効化されたサイトのシンボリックリンク(Ubuntu)
/etc/nginx/mime.types MIMEタイプのマッピング
/var/log/nginx/access.log アクセスログ
/var/log/nginx/error.log エラーログ
/var/www/html/ デフォルトのWebルートディレクトリ
/usr/share/nginx/html/ デフォルトのWebルート(RHEL系)

2.2 nginx.confの基本構造

Nginxの設定はブロック(block)構造で構成されており、階層的にネストされます:

# === グローバルコンテキスト (Main Context) ===
user nginx;                          # ワーカープロセスの実行ユーザー
worker_processes auto;               # ワーカープロセス数 (auto = CPUコア数)
error_log /var/log/nginx/error.log warn;  # エラーログのパスとレベル
pid /run/nginx.pid;                  # PIDファイルのパス

# === イベントコンテキスト ===
events {
    worker_connections 1024;         # ワーカーあたりの最大同時接続数
    use epoll;                       # イベント処理方式 (Linux)
    multi_accept on;                 # 一度に複数の接続を受け入れ
}

# === HTTPコンテキスト ===
http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    # ログフォーマットの定義
    log_format main '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent"';

    access_log /var/log/nginx/access.log main;

    sendfile on;                     # カーネルレベルのファイル転送
    tcp_nopush on;                   # sendfileと併用
    tcp_nodelay on;                  # 少量パケットの遅延防止
    keepalive_timeout 65;            # 接続維持時間

    # gzip圧縮
    gzip on;
    gzip_types text/plain text/css application/json application/javascript;

    # 追加設定ファイルの読み込み
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;  # Ubuntu方式
}
注意: 設定を変更した後は必ずnginx -tで構文を検証し、sudo systemctl reload nginxで適用してください。restartの代わりにreloadを使用すると、サービスを中断せずに設定を反映できます。

3. Server Block(バーチャルホスト)設定

Server BlockはApacheのVirtualHostに相当し、1つのNginxサーバーで複数のドメイン(サイト)を運用できるようにします。

3.1 基本的な静的ウェブサイト

# /etc/nginx/conf.d/example.com.conf
server {
    listen 80;                       # IPv4ポート
    listen [::]:80;                  # IPv6ポート
    server_name example.com www.example.com;

    root /var/www/example.com/html;  # ドキュメントルート
    index index.html index.htm;      # デフォルトインデックスファイル

    # デフォルトlocation
    location / {
        try_files $uri $uri/ =404;   # ファイル → ディレクトリ → 404
    }

    # エラーページのカスタマイズ
    error_page 404 /404.html;
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root /usr/share/nginx/html;
    }

    # ログ設定(サイト別に分離)
    access_log /var/log/nginx/example.com.access.log;
    error_log /var/log/nginx/example.com.error.log;
}
# Webルートディレクトリの作成
sudo mkdir -p /var/www/example.com/html
sudo chown -R $USER:$USER /var/www/example.com/html

# テストページの作成
echo "<h1>Welcome to example.com</h1>" > /var/www/example.com/html/index.html

# 設定の検証と適用
sudo nginx -t
sudo systemctl reload nginx

3.2 Ubuntuのsites-available / sites-enabledパターン

# 設定ファイルの作成
sudo nano /etc/nginx/sites-available/example.com

# シンボリックリンクで有効化
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/

# デフォルトサイトの無効化(必要に応じて)
sudo rm /etc/nginx/sites-enabled/default

# 適用
sudo nginx -t
sudo systemctl reload nginx

3.3 複数ドメインの運用(マルチサイト)

# サイトA: /etc/nginx/conf.d/site-a.conf
server {
    listen 80;
    server_name site-a.com www.site-a.com;
    root /var/www/site-a/html;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

# サイトB: /etc/nginx/conf.d/site-b.conf
server {
    listen 80;
    server_name site-b.com www.site-b.com;
    root /var/www/site-b/html;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

# デフォルトサーバー(マッチしないリクエストの処理)
server {
    listen 80 default_server;
    server_name _;
    return 444;    # 接続を終了(レスポンスなし)
}

4. Locationブロック - URLマッチングの核心

locationブロックはNginx設定で最も頻繁に使用され、最も重要なディレクティブです。URLパスに応じて異なる処理を行うことができます。

4.1 マッチング方式と優先順位

構文 マッチング方式 優先順位
= /path 完全一致(Exact Match) 第1位(最優先)
^~ /path プレフィックス一致(正規表現検索なし) 第2位
~ /regex 正規表現(大文字小文字区別あり) 第3位
~* /regex 正規表現(大文字小文字区別なし) 第3位
/path プレフィックス一致(最長マッチ) 第4位(デフォルト)

4.2 実践Locationの例

server {
    listen 80;
    server_name example.com;
    root /var/www/example.com;

    # ルートパスのみ完全一致
    location = / {
        # メインページ専用処理
        try_files /index.html =404;
    }

    # /api/ で始まるパス → バックエンドプロキシ
    location /api/ {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    # 静的ファイル(画像、CSS、JS)
    location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2?)$ {
        expires 30d;                 # 30日キャッシュ
        add_header Cache-Control "public, immutable";
        access_log off;              # 静的ファイルのログ無効化
    }

    # PHPファイルの処理
    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    # 隠しファイルへのアクセスをブロック (.htaccess, .git など)
    location ~ /\. {
        deny all;
        access_log off;
        log_not_found off;
    }

    # favicon.ico の404ログ防止
    location = /favicon.ico {
        log_not_found off;
        access_log off;
    }

    # robots.txt
    location = /robots.txt {
        log_not_found off;
        access_log off;
    }
}
TIP: locationブロックの優先順位を覚えましょう:=(完全一致) → ^~(プレフィックス優先) → ~/~*(正規表現) → 一般プレフィックス。正確な理解がないと、予期しないルーティング問題が発生する可能性があります。

5. リバースプロキシ設定

リバースプロキシはNginxの最も強力な機能の1つです。クライアントのリクエストをバックエンドサーバー(Node.js、Python、Javaなど)に転送し、レスポンスを返します。

5.1 基本リバースプロキシ

# Node.jsアプリのプロキシ(ポート3000)
server {
    listen 80;
    server_name app.example.com;

    location / {
        proxy_pass http://127.0.0.1:3000;

        # 必須ヘッダーの転送
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # タイムアウト設定
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;

        # バッファ設定
        proxy_buffering on;
        proxy_buffer_size 4k;
        proxy_buffers 8 4k;
    }
}

5.2 WebSocketプロキシ

# WebSocketのサポートが必要な場合(チャット、リアルタイムアプリ)
server {
    listen 80;
    server_name ws.example.com;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;

        # WebSocketアップグレードヘッダー
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;

        # WebSocket接続維持時間
        proxy_read_timeout 86400s;   # 24時間
        proxy_send_timeout 86400s;
    }
}

5.3 パス別マルチバックエンドプロキシ

# マイクロサービスルーティング
server {
    listen 80;
    server_name example.com;

    # フロントエンド (React/Vue SPA)
    location / {
        root /var/www/frontend/dist;
        try_files $uri $uri/ /index.html;  # SPAルーティング
    }

    # APIサーバー (Node.js)
    location /api/ {
        proxy_pass http://127.0.0.1:3000/;    # 末尾の / が重要!
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    # 認証サーバー (Python)
    location /auth/ {
        proxy_pass http://127.0.0.1:5000/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    # ファイルアップロードサーバー(個別サイズ制限)
    location /upload/ {
        client_max_body_size 100M;   # アップロード最大100MB
        proxy_pass http://127.0.0.1:4000/;
        proxy_set_header Host $host;
    }
}
注意: proxy_pass URLの末尾のスラッシュ(/)に注意してください。proxy_pass http://backend/;はlocationパスを除去して転送し、proxy_pass http://backend;(スラッシュなし)はlocationパスを含めて転送します。

6. ロードバランシング

複数のバックエンドサーバーにトラフィックを分散して、高可用性とパフォーマンスを確保します。

6.1 ロードバランシング方式

# === Round Robin(デフォルト) ===
# 順番に交互にリクエストを分配
upstream backend_rr {
    server 192.168.1.10:8080;
    server 192.168.1.11:8080;
    server 192.168.1.12:8080;
}

# === Weighted Round Robin ===
# サーバー性能に応じて重み付け
upstream backend_weighted {
    server 192.168.1.10:8080 weight=5;    # 5倍多くのリクエスト
    server 192.168.1.11:8080 weight=3;
    server 192.168.1.12:8080 weight=1;
}

# === Least Connections ===
# 接続数が最も少ないサーバーに分配
upstream backend_lc {
    least_conn;
    server 192.168.1.10:8080;
    server 192.168.1.11:8080;
    server 192.168.1.12:8080;
}

# === IP Hash ===
# 同じクライアントIPは常に同じサーバーへ(セッション維持)
upstream backend_hash {
    ip_hash;
    server 192.168.1.10:8080;
    server 192.168.1.11:8080;
    server 192.168.1.12:8080;
}

# ロードバランサーの適用
server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://backend_rr;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

6.2 ヘルスチェックと障害対応

upstream backend {
    server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;
    server 192.168.1.11:8080 max_fails=3 fail_timeout=30s;
    server 192.168.1.12:8080 backup;     # バックアップサーバー(他のサーバーがすべて失敗した場合に使用)
    server 192.168.1.13:8080 down;       # 手動で無効化

    # max_fails=3: 3回失敗したら該当サーバーを無効化
    # fail_timeout=30s: 30秒後に再試行
    # backup: 他のすべてのサーバーがダウンした時のみ使用
    # down: 永続的に無効化(メンテナンス用)
}

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://backend;
        proxy_next_upstream error timeout http_500 http_502 http_503;
        proxy_next_upstream_tries 3;        # 最大3回他のサーバーを試行
        proxy_next_upstream_timeout 10s;    # タイムアウト
    }
}

7. HTTPS / SSL設定

7.1 Let's Encrypt無料証明書の発行

# Certbotのインストール
sudo apt install certbot python3-certbot-nginx -y    # Ubuntu
sudo dnf install certbot python3-certbot-nginx -y    # Rocky/RHEL

# 証明書の発行(Nginx自動設定)
sudo certbot --nginx -d example.com -d www.example.com

# 証明書の自動更新テスト
sudo certbot renew --dry-run

# 自動更新のcron確認
sudo systemctl status certbot.timer

7.2 SSL手動設定(最適化を含む)

# /etc/nginx/conf.d/example.com.conf
server {
    listen 80;
    server_name example.com www.example.com;
    # HTTP → HTTPSリダイレクト
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name example.com www.example.com;

    # SSL証明書のパス
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    # SSLプロトコル(TLS 1.2以上のみ許可)
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;

    # SSLセッションキャッシュ(ハンドシェイク性能向上)
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;

    # OCSP Stapling(証明書検証の高速化)
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4 valid=300s;

    # セキュリティヘッダー
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
    add_header X-Frame-Options DENY always;
    add_header X-Content-Type-Options nosniff always;
    add_header X-XSS-Protection "1; mode=block" always;

    root /var/www/example.com/html;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}
TIP: Mozilla SSL Configuration Generatorを使用すると、サーバー環境に最適なSSL設定を自動生成できます。

8. セキュリティ設定

8.1 基本セキュリティの強化

# /etc/nginx/conf.d/security.conf(共通セキュリティ設定)

# Nginxバージョン情報の非表示
server_tokens off;

# リクエストサイズの制限(デフォルト1MB)
client_max_body_size 10M;

# リクエストヘッダー/ボディのタイムアウト
client_header_timeout 10s;
client_body_timeout 10s;
send_timeout 10s;

# バッファオーバーフロー攻撃の防止
client_body_buffer_size 1K;
client_header_buffer_size 1k;
large_client_header_buffers 2 1k;

8.2 IPベースのアクセス制御

# 管理者ページのIP制限
location /admin/ {
    allow 10.0.0.0/8;           # 内部ネットワークを許可
    allow 192.168.1.100;         # 特定IPを許可
    deny all;                    # それ以外をブロック

    proxy_pass http://127.0.0.1:8080;
}

# 特定の国/IP帯域のブロック
# geoモジュールの活用
geo $blocked_ip {
    default 0;
    1.2.3.0/24 1;               # ブロックするIP帯域
    5.6.7.0/24 1;
}

server {
    if ($blocked_ip) {
        return 403;
    }
}

8.3 Rate Limiting(リクエスト制限)

# httpブロックでzoneを定義
http {
    # IPあたり毎秒10リクエストに制限
    limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;

    # IPあたりの同時接続数を制限
    limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
}

# serverブロックで適用
server {
    # APIにRate Limitを適用
    location /api/ {
        limit_req zone=api_limit burst=20 nodelay;
        # burst=20: 瞬間的に20個まで許可
        # nodelay: 超過分を即座に処理(待機しない)

        limit_req_status 429;    # 制限超過時に429レスポンス

        proxy_pass http://backend;
    }

    # ログインページ(より厳格な制限)
    location /login {
        limit_req zone=api_limit burst=5;
        limit_conn conn_limit 5;  # 同時5接続に制限

        proxy_pass http://backend;
    }
}

8.4 ボット/スクレイパーのブロック

# 悪意のあるUser-Agentのブロック
if ($http_user_agent ~* (scrapy|curl|wget|python-requests|httpclient|Go-http-client)) {
    return 403;
}

# 空のUser-Agentをブロック
if ($http_user_agent = "") {
    return 403;
}

# 特定リファラーのブロック(ホットリンク防止)
location ~* \.(jpg|jpeg|png|gif|webp)$ {
    valid_referers none blocked server_names *.example.com;
    if ($invalid_referer) {
        return 403;
    }
}

9. パフォーマンス最適化

9.1 Gzip圧縮

http {
    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;           # 圧縮レベル (1-9、6を推奨)
    gzip_min_length 256;         # 256バイト以上のみ圧縮
    gzip_types
        text/plain
        text/css
        text/xml
        text/javascript
        application/json
        application/javascript
        application/xml
        application/rss+xml
        application/atom+xml
        image/svg+xml
        font/woff
        font/woff2;
}

9.2 静的ファイルのキャッシング

# 静的リソースのブラウザキャッシング
location ~* \.(jpg|jpeg|png|gif|ico|webp|avif)$ {
    expires 365d;
    add_header Cache-Control "public, immutable";
    access_log off;
}

location ~* \.(css|js)$ {
    expires 30d;
    add_header Cache-Control "public";
    access_log off;
}

location ~* \.(woff|woff2|ttf|otf|eot)$ {
    expires 365d;
    add_header Cache-Control "public, immutable";
    access_log off;
    add_header Access-Control-Allow-Origin "*";  # CORS(フォント)
}

location ~* \.(html|htm)$ {
    expires 1h;
    add_header Cache-Control "public, must-revalidate";
}

9.3 プロキシキャッシング

http {
    # プロキシキャッシュ領域の定義
    proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m
                     max_size=1g inactive=60m use_temp_path=off;

    server {
        location / {
            proxy_pass http://backend;

            # キャッシュの有効化
            proxy_cache my_cache;
            proxy_cache_valid 200 302 10m;   # 200, 302 → 10分キャッシュ
            proxy_cache_valid 404 1m;        # 404 → 1分キャッシュ

            # キャッシュ状態ヘッダー(デバッグ用)
            add_header X-Cache-Status $upstream_cache_status;

            # キャッシュバイパス条件
            proxy_cache_bypass $http_cache_control;
            proxy_no_cache $http_pragma;
        }
    }
}

9.4 Workerプロセスのチューニング

# CPUコア数に合わせて設定
worker_processes auto;          # 自動検出(推奨)

events {
    worker_connections 4096;    # サーバー規模に応じて調整
    use epoll;                  # Linux最適イベントモデル
    multi_accept on;
}

http {
    # ファイルディスクリプタのキャッシング
    open_file_cache max=10000 inactive=20s;
    open_file_cache_valid 30s;
    open_file_cache_min_uses 2;
    open_file_cache_errors on;
}
# OSレベルのチューニング(カーネルパラメータ)
# /etc/sysctl.confに追加
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.ip_local_port_range = 1024 65535
net.ipv4.tcp_tw_reuse = 1

# ワーカープロセスのファイルディスクリプタ制限
# /etc/security/limits.conf
# nginx soft nofile 65535
# nginx hard nofile 65535

# またはnginx.confのグローバルコンテキストで:
worker_rlimit_nofile 65535;

10. ログ設定とモニタリング

10.1 カスタムログフォーマット

http {
    # 詳細ログフォーマット(応答時間を含む)
    log_format detailed '$remote_addr - $remote_user [$time_local] '
                        '"$request" $status $body_bytes_sent '
                        '"$http_referer" "$http_user_agent" '
                        '$request_time $upstream_response_time';

    # JSON形式のログ(ELK/Loki連携に有用)
    log_format json_log escape=json '{'
        '"time":"$time_iso8601",'
        '"remote_addr":"$remote_addr",'
        '"request":"$request",'
        '"status":$status,'
        '"body_bytes_sent":$body_bytes_sent,'
        '"request_time":$request_time,'
        '"upstream_response_time":"$upstream_response_time",'
        '"http_referer":"$http_referer",'
        '"http_user_agent":"$http_user_agent"'
    '}';

    # 条件付きログ(2xxレスポンスはログしない)
    map $status $loggable {
        ~^[23] 0;
        default 1;
    }

    server {
        access_log /var/log/nginx/access.log detailed;
        # access_log /var/log/nginx/access.json json_log if=$loggable;
    }
}

10.2 ログローテーション

# /etc/logrotate.d/nginx
/var/log/nginx/*.log {
    daily
    missingok
    rotate 14
    compress
    delaycompress
    notifempty
    create 0640 www-data adm
    sharedscripts
    postrotate
        [ -f /var/run/nginx.pid ] && kill -USR1 $(cat /var/run/nginx.pid)
    endscript
}

10.3 Nginxステータスモニタリング(stub_status)

# 内部からのみアクセス可能なステータスページ
server {
    listen 8080;
    server_name localhost;

    location /nginx_status {
        stub_status on;
        allow 127.0.0.1;
        allow 10.0.0.0/8;
        deny all;
    }
}

# 出力例:
# Active connections: 291
# server accepts handled requests
#  16630948 16630948 31070465
# Reading: 6 Writing: 179 Waiting: 106
# ステータスの確認
curl http://localhost:8080/nginx_status

# Prometheus連携時はnginx-prometheus-exporterを使用
# docker run -p 9113:9113 nginx/nginx-prometheus-exporter -nginx.scrape-uri=http://host:8080/nginx_status

11. 実戦運用のヒント

11.1 よく使うコマンド集

# 設定の構文検証(変更後は必ず実行!)
sudo nginx -t

# サービス中断なしで設定を適用
sudo systemctl reload nginx

# サービスの再起動(中断あり)
sudo systemctl restart nginx

# ログのリアルタイムモニタリング
tail -f /var/log/nginx/access.log
tail -f /var/log/nginx/error.log

# 特定のステータスコードのみフィルタ
tail -f /var/log/nginx/access.log | grep --line-buffered '" 500 '

# 接続状態の確認
ss -tlnp | grep nginx

# 現在のアクティブ接続数
ss -s | head -5

# Nginxマスター/ワーカープロセスの確認
ps aux | grep nginx

# 設定ファイルのパスとモジュールの確認
nginx -V 2>&1 | tr ' ' '\n' | grep -E "^--"

11.2 無停止設定変更の手順

# 1. 設定ファイルの修正
sudo nano /etc/nginx/conf.d/example.com.conf

# 2. 構文検証(必須!)
sudo nginx -t
# nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
# nginx: configuration file /etc/nginx/nginx.conf test is successful

# 3. reloadで適用(ダウンタイムなし)
sudo systemctl reload nginx

# もし構文エラーがあった場合:
# nginx: [emerg] unknown directive "servr" in /etc/nginx/conf.d/example.com.conf:2
# nginx: configuration file /etc/nginx/nginx.conf test failed
# → reloadせずにエラーを修正!

11.3 よくある間違いと解決方法

症状 原因 解決策
502 Bad Gateway バックエンドサーバーのダウンまたはソケットエラー バックエンドプロセスの確認、proxy_passアドレスの確認
504 Gateway Timeout バックエンドの応答遅延 proxy_read_timeoutの値を増加
413 Request Entity Too Large アップロードサイズの超過 client_max_body_sizeの値を増加
403 Forbidden ファイル権限またはSELinux ファイルの所有者/権限の確認、SELinuxコンテキストの確認
301リダイレクトループ HTTP⇔HTTPS設定の競合 serverブロックの分離、$scheme条件の確認
リアルタイムログが出ない access_log off;またはバッファリング locationブロックのログ設定を確認

12. 設定ファイルチェックリスト

本番サーバーにNginxをデプロイする前に、以下の項目を必ず確認してください:

  • 基本セキュリティ: server_tokens off;の設定有無
  • HTTPS: すべてのHTTPトラフィックがHTTPSにリダイレクトされているか
  • SSLプロトコル: TLS 1.2以上のみ許可しているか
  • セキュリティヘッダー: HSTS、X-Frame-Options、X-Content-Type-Optionsの設定
  • ファイルアクセス: .git.envなどの隠しファイルがブロックされているか
  • アップロード制限: client_max_body_sizeに適切な値が設定されているか
  • Rate Limiting: API、ログインなど機密性の高いパスに制限が設定されているか
  • Gzip圧縮: テキストベースのレスポンスで圧縮が有効化されているか
  • キャッシング: 静的ファイルに適切なexpiresが設定されているか
  • ログ: サイト別のログ分離とローテーションが設定されているか
  • Default Server: マッチしないリクエストの処理(return 444;
  • タイムアウト: proxy_read_timeoutなどの適切なタイムアウト設定
  • バックアップ: 設定ファイルのバックアップとバージョン管理(Git推奨)

まとめ:Nginxは設定こそが実力である

Nginxはインストールは簡単ですが、適切に運用するには設定に対する深い理解が必要です。このガイドで扱った内容は、実務で最も頻繁に遭遇するシナリオを基に構成しました。

重要なポイントをまとめると以下の通りです:

  • 基礎をしっかり - nginx.confのブロック構造と継承関係を理解しましょう。
  • locationの優先順位を覚えよ - =^~~/~* → 一般プレフィックス。これさえ知っていれば、ほとんどのルーティング問題を解決できます。
  • 変更前に必ずnginx -t - 設定エラーはサービス障害に直結します。構文検証は選択ではなく必須です。
  • reload ≠ restart - reloadは無停止反映、restartはサービス中断が発生します。
  • セキュリティは最初から - HTTPS、セキュリティヘッダー、Rate Limitingは運用開始前に設定しましょう。
  • ログは資産である - カスタムログフォーマットを設定し、定期的に分析すれば、障害予防とパフォーマンス改善に大いに役立ちます。

このガイドの設定例を自分の環境に合わせて修正し、適用してみてください。実践経験を積むほどNginxの設定は自然と身につき、複雑なアーキテクチャも自信を持って構築できるようになるでしょう。