nginx完全設定ガイド:高速Webサーバー構築の実践テクニック

インフラ・ネットワーク

nginxとは?高性能Webサーバーの基礎知識

nginxは「エンジンエックス」と読む、世界で最も使われているWebサーバーの一つです。Netflixの動画配信、WordPressの高速化、ロードバランシング…現代のWeb技術の中核を担っています。

「Apacheじゃダメなの?」という疑問もあるでしょう。本記事では、nginxの特徴から実践的な設定まで、現場で使える知識を徹底解説します。

nginx vs Apache:なぜnginxを選ぶのか

特徴 nginx Apache
同時接続処理 10万接続以上(イベント駆動) 数千接続(プロセス/スレッド)
メモリ使用量 軽量(数MB〜) 重い(数百MB〜)
静的ファイル配信 超高速 普通
設定ファイル シンプル、宣言的 .htaccess対応、柔軟
リバースプロキシ 標準機能、高性能 mod_proxyで対応
じゅんち8

100万PV/月のサイトをApacheからnginxに移行したら、サーバー台数が1/3になりました。特に静的ファイル配信とリバースプロキシの性能は圧倒的です。今ではすべてのプロジェクトでnginxを使っています。

インストール:各環境での導入方法

Ubuntu/Debian

# 最新安定版のインストール
sudo apt update
sudo apt install nginx

# バージョン確認
nginx -v

# サービス管理
sudo systemctl start nginx
sudo systemctl enable nginx
sudo systemctl status nginx

CentOS/RHEL/AlmaLinux

# EPELリポジトリ追加
sudo yum install epel-release

# nginxインストール
sudo yum install nginx

# SELinuxの設定(必要な場合)
sudo setsebool -P httpd_can_network_connect 1

Docker

# 公式イメージで起動
docker run -d 
  --name nginx 
  -p 80:80 
  -v ./html:/usr/share/nginx/html 
  -v ./nginx.conf:/etc/nginx/nginx.conf 
  nginx:alpine

基本設定:nginx.confの構造を理解する

設定ファイルの階層構造

# /etc/nginx/nginx.conf
user www-data;
worker_processes auto;
pid /run/nginx.pid;
error_log /var/log/nginx/error.log warn;

events {
    worker_connections 2048;
    use epoll;
    multi_accept on;
}

http {
    # MIMEタイプ設定
    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" "$http_x_forwarded_for"';

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

    # パフォーマンス設定
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    server_tokens off;

    # Gzip圧縮
    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_types text/plain text/css text/xml text/javascript 
               application/json application/javascript application/xml+rss 
               application/rss+xml application/atom+xml image/svg+xml 
               text/x-js text/x-cross-domain-policy application/x-font-ttf 
               application/x-font-opentype application/vnd.ms-fontobject 
               image/x-icon;

    # バーチャルホスト設定読み込み
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

実践:よく使う設定パターン

1. 静的サイトのホスティング

# /etc/nginx/sites-available/static-site.conf
server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;
    root /var/www/example.com;
    index index.html;

    # ファイルが見つからない場合の処理
    location / {
        try_files $uri $uri/ =404;
    }

    # 画像の有効期限を長く設定
    location ~* .(jpg|jpeg|png|gif|ico|css|js)$ {
        expires 365d;
        add_header Cache-Control "public, immutable";
    }

    # セキュリティヘッダー
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
}

2. PHPアプリケーション(WordPress等)

# /etc/nginx/sites-available/wordpress.conf
server {
    listen 80;
    server_name blog.example.com;
    root /var/www/wordpress;
    index index.php index.html;

    # WordPress固有の設定
    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    # PHP処理
    location ~ .php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_buffer_size 128k;
        fastcgi_buffers 256 16k;
        fastcgi_busy_buffers_size 256k;
    }

    # アップロードサイズ制限
    client_max_body_size 100M;

    # wp-adminへのアクセス制限
    location ~ ^/wp-admin {
        allow 192.168.1.0/24;
        deny all;
        location ~ .php$ {
            include snippets/fastcgi-php.conf;
            fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
        }
    }

    # 静的ファイルのキャッシュ
    location ~* .(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {
        expires max;
        log_not_found off;
        access_log off;
    }
}

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

# /etc/nginx/sites-available/reverse-proxy.conf
upstream backend {
    # ロードバランシング設定
    least_conn;  # 最少接続数
    server backend1.local:8080 weight=3;
    server backend2.local:8080 weight=2;
    server backend3.local:8080 backup;
    
    # ヘルスチェック
    keepalive 32;
}

server {
    listen 80;
    server_name api.example.com;

    # プロキシ基本設定
    location / {
        proxy_pass http://backend;
        proxy_http_version 1.1;
        
        # ヘッダー設定
        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;
        
        # WebSocket対応
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        
        # タイムアウト設定
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
        
        # バッファリング設定
        proxy_buffering on;
        proxy_buffer_size 4k;
        proxy_buffers 8 4k;
        proxy_busy_buffers_size 8k;
    }
}
じゅんち8

リバースプロキシの設定は特に重要です。Dockerコンテナへのルーティングや、Node.jsアプリのロードバランシングなど、現代的なアーキテクチャには必須の機能です。

SSL/TLS設定:Let’s Encryptで無料HTTPS化

Certbotによる自動設定

# Certbotインストール
sudo apt install certbot python3-certbot-nginx

# 証明書取得と自動設定
sudo certbot --nginx -d example.com -d www.example.com

# 自動更新テスト
sudo certbot renew --dry-run

# cronで自動更新(/etc/cron.d/certbot)
0 */12 * * * root certbot renew --quiet

手動SSL設定(A+評価獲得)

# /etc/nginx/sites-available/secure-site.conf
server {
    listen 80;
    server_name example.com;
    return 301 https://$server_name$request_uri;
}

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

    # 証明書設定
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    
    # SSL設定(Mozilla SSL Configuration Generator推奨)
    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;
    
    # DHパラメータ
    ssl_dhparam /etc/nginx/dhparam.pem;
    
    # セッションキャッシュ
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:10m;
    ssl_session_tickets off;
    
    # OCSP Stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
    
    # セキュリティヘッダー
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    
    root /var/www/example.com;
    index index.html;
    
    location / {
        try_files $uri $uri/ =404;
    }
}

パフォーマンスチューニング

1. Worker設定の最適化

# CPUコア数に合わせて設定
worker_processes auto;
worker_rlimit_nofile 65535;

events {
    worker_connections 4096;
    use epoll;
    multi_accept on;
}

2. FastCGIキャッシュ(WordPress高速化)

# /etc/nginx/nginx.conf のhttpセクション
fastcgi_cache_path /var/cache/nginx levels=1:2 
                   keys_zone=WORDPRESS:100m 
                   max_size=1g 
                   inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";

# サイト設定ファイル
set $skip_cache 0;

# POST requests and URLs with query strings should always go to PHP
if ($request_method = POST) {
    set $skip_cache 1;
}   
if ($query_string != "") {
    set $skip_cache 1;
}   

# Don't cache WordPress admin and login pages
if ($request_uri ~* "/wp-admin/|/wp-login.php") {
    set $skip_cache 1;
}

location ~ .php$ {
    fastcgi_cache WORDPRESS;
    fastcgi_cache_bypass $skip_cache;
    fastcgi_no_cache $skip_cache;
    fastcgi_cache_valid 200 60m;
    add_header X-FastCGI-Cache $upstream_cache_status;
    
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
}

3. 静的ファイルの最適化

# Brotli圧縮(gzipより効率的)
load_module modules/ngx_http_brotli_filter_module.so;
load_module modules/ngx_http_brotli_static_module.so;

http {
    # Brotli設定
    brotli on;
    brotli_comp_level 6;
    brotli_types text/plain text/css text/xml text/javascript 
                 application/json application/javascript application/xml+rss 
                 application/rss+xml application/atom+xml image/svg+xml;
    
    # 静的ファイル配信の最適化
    open_file_cache max=1000 inactive=20s;
    open_file_cache_valid 30s;
    open_file_cache_min_uses 2;
    open_file_cache_errors on;
}

セキュリティ強化

1. レート制限(DDoS対策)

http {
    # レート制限ゾーン定義
    limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
    limit_req_zone $binary_remote_addr zone=login:10m rate=3r/m;
    limit_conn_zone $binary_remote_addr zone=perip:10m;
    
    server {
        # 一般的なリクエスト制限
        location / {
            limit_req zone=general burst=20 nodelay;
            limit_conn perip 10;
        }
        
        # ログインページの制限
        location /wp-login.php {
            limit_req zone=login burst=3 nodelay;
        }
    }
}

2. 基本認証の追加

# パスワードファイル生成
sudo htpasswd -c /etc/nginx/.htpasswd admin

# nginx設定
location /admin {
    auth_basic "Restricted Area";
    auth_basic_user_file /etc/nginx/.htpasswd;
}

3. IPアクセス制限

location /secret {
    # 特定IPのみ許可
    allow 192.168.1.0/24;
    allow 10.0.0.0/8;
    deny all;
    
    # 国別制限(GeoIP2モジュール使用)
    if ($geoip2_data_country_code != "JP") {
        return 403;
    }
}

トラブルシューティング

エラー 原因 解決方法
502 Bad Gateway バックエンドが応答しない upstream設定確認、バックエンド起動確認
413 Request Entity Too Large アップロードサイズ制限 client_max_body_size増加
504 Gateway Timeout 処理時間超過 proxy_read_timeout増加
403 Forbidden 権限不足 ファイル権限、ディレクトリ権限確認
設定エラー 構文エラー nginx -t で検証

便利なデバッグコマンド

# 設定ファイルの検証
sudo nginx -t

# 設定のリロード(無停止)
sudo nginx -s reload

# アクセスログのリアルタイム監視
tail -f /var/log/nginx/access.log

# エラーログの確認
tail -f /var/log/nginx/error.log

# 設定の確認
nginx -T

# プロセス状態確認
ps aux | grep nginx

監視とログ分析

アクセスログの解析

# GoAccessによるリアルタイム解析
sudo apt install goaccess
goaccess /var/log/nginx/access.log -o /var/www/html/report.html --log-format=COMBINED

# 特定IPのアクセス数確認
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20

# ステータスコード別集計
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn

Prometheus + Grafanaでの監視

# nginx-vts-exporterの設定
location /status {
    vhost_traffic_status_display;
    vhost_traffic_status_display_format json;
    allow 127.0.0.1;
    deny all;
}
じゅんち8

nginxの設定は奥が深いですが、基本パターンを理解すれば応用が効きます。特にリバースプロキシとキャッシュ設定をマスターすると、セルフホスティング環境でも商用サービス並みのパフォーマンスが実現できます。

まとめ:nginx設定のベストプラクティス

  1. 設定前に必ずバックアップcp nginx.conf nginx.conf.bak
  2. 変更後は必ず検証nginx -tでエラーチェック
  3. 段階的な設定変更:一度に多くを変更しない
  4. ログの活用:問題解決の鍵はログにある
  5. セキュリティファースト:最小権限の原則を守る

nginxは学習曲線は急ですが、一度理解すれば非常に強力なツールです。本記事の設定例を参考に、ぜひ自分のプロジェクトに応用してみてください。

関連記事:Git/GitHub入門でコード管理を学び、Dockerと組み合わせれば、モダンな開発環境が構築できます。

関連記事

タイトルとURLをコピーしました