Nginx

高性能で軽量なWebサーバー・リバースプロキシサーバー。イベント駆動型アーキテクチャによる高い同時接続処理能力。静的コンテンツ配信に特化。

アプリケーションサーバーWebサーバーリバースプロキシロードバランサー高性能軽量

アプリケーションサーバー

Nginx

概要

Nginxは高性能で軽量なWebサーバー・リバースプロキシサーバーです。イベント駆動型アーキテクチャにより高い同時接続処理能力を実現し、静的コンテンツ配信に特化しています。日本で50%のシェア、世界的にも高いシェアを誇り、大規模サイトや高トラフィックサイトで標準的に採用されています。Apacheより高い処理能力を持ち、メモリ使用量も少ないのが特徴です。

詳細

Nginxは2004年にIgor Sysoevによって開発され、「C10K問題」(1万同時接続問題)の解決を目的として設計されました。現在では世界中の高トラフィックサイトで使用され、Webサーバー市場でApacheと並ぶ二大勢力の一角を占めています。マスター・ワーカープロセスモデルとイベント駆動型の非同期処理により、少ないメモリで大量の同時接続を処理できます。

主要な技術的特徴

  • イベント駆動型アーキテクチャ: 非同期、非ブロッキングI/O
  • 高性能: 低メモリ使用量で高いスループット
  • リバースプロキシ: バックエンドサーバーへの効率的な負荷分散
  • SSL/TLS終端: 高性能なSSL処理
  • キャッシュ機能: 高速コンテンツ配信
  • モジュール式設計: 必要な機能のみを組み込み可能

用途

  • 静的コンテンツ配信
  • リバースプロキシ・ロードバランサー
  • SSL/TLS終端
  • API Gateway
  • Webアプリケーションサーバー(Unit)
  • CDN エッジサーバー

メリット・デメリット

メリット

  • 高いパフォーマンス: 大量の同時接続を効率的に処理
  • 低メモリ使用量: リソース効率が良い
  • 高い安定性: 長時間稼働でもメモリリークなし
  • 豊富な機能: リバースプロキシ、負荷分散、キャッシュ
  • 柔軟な設定: 細かい調整が可能
  • 活発な開発: 継続的な機能追加と改善

デメリット

  • 設定の複雑さ: 高度な設定には専門知識が必要
  • 動的コンテンツ: PHPなど動的言語の処理には追加設定必要
  • デバッグの困難さ: 設定ミスの特定が困難な場合がある
  • 学習コストメ: Apache比較でディレクティブの違い
  • Windows対応: Windowsでの性能は制限的

インストール・基本設定

前提条件

# システム要件確認
uname -a
cat /etc/os-release

インストール方法

Ubuntu/Debian

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

# Nginx signing key
curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo apt-key add -

# 安定版リポジトリの追加
echo "deb 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

CentOS/RHEL

# リポジトリファイル作成
sudo tee /etc/yum.repos.d/nginx.repo <<EOF
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/\$releasever/\$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
EOF

# インストール
sudo yum install nginx
# または
sudo dnf install nginx

ソースコンパイル

# 依存関係のインストール
sudo apt install build-essential libpcre3-dev libssl-dev zlib1g-dev

# Nginxソースダウンロード
wget http://nginx.org/download/nginx-1.25.3.tar.gz
tar -xzf nginx-1.25.3.tar.gz
cd nginx-1.25.3

# 設定とコンパイル
./configure \
    --prefix=/etc/nginx \
    --sbin-path=/usr/sbin/nginx \
    --modules-path=/usr/lib/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 \
    --with-http_ssl_module \
    --with-http_realip_module \
    --with-http_addition_module \
    --with-http_gzip_static_module \
    --with-http_secure_link_module \
    --with-http_stub_status_module \
    --with-file-aio \
    --with-threads

make && sudo make install

基本設定

メイン設定ファイル(nginx.conf)

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

# イベント処理設定
events {
    worker_connections 1024;
    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;

    # Gzip圧縮
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_types
        text/plain
        text/css
        text/xml
        text/javascript
        application/javascript
        application/xml+rss
        application/json;

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

基本的なサーバー設定

# /etc/nginx/conf.d/default.conf
server {
    listen 80;
    server_name example.com www.example.com;
    root /var/www/html;
    index index.html index.htm;

    # 静的ファイル配信
    location / {
        try_files $uri $uri/ =404;
    }

    # キャッシュ設定
    location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }

    # ログ設定
    access_log /var/log/nginx/example.com.access.log;
    error_log /var/log/nginx/example.com.error.log;
}

高度な設定

リバースプロキシ設定

# アップストリーム定義
upstream backend {
    least_conn;
    server backend1.example.com:8080 weight=3;
    server backend2.example.com:8080 weight=2;
    server backend3.example.com:8080 weight=1 backup;
    keepalive 32;
}

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

    location / {
        proxy_pass http://backend;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        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_cache_bypass $http_upgrade;
        
        # タイムアウト設定
        proxy_connect_timeout 30s;
        proxy_send_timeout 30s;
        proxy_read_timeout 30s;
    }
}

SSL/TLS設定

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

    # SSL証明書
    ssl_certificate /etc/ssl/certs/example.com.crt;
    ssl_certificate_key /etc/ssl/private/example.com.key;

    # SSL設定
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384;
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    ssl_session_tickets off;

    # HSTS設定
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    # OCSP Stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
    resolver 8.8.8.8 8.8.4.4 valid=300s;

    location / {
        root /var/www/html;
        index index.html;
    }
}

# HTTP to HTTPS redirect
server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$server_name$request_uri;
}

ロードバランシング

# 重み付きラウンドロビン
upstream app_servers {
    server app1.example.com:8080 weight=3;
    server app2.example.com:8080 weight=2;
    server app3.example.com:8080 weight=1;
}

# IPハッシュ(セッション親和性)
upstream session_backend {
    ip_hash;
    server session1.example.com:8080;
    server session2.example.com:8080;
    server session3.example.com:8080;
}

# 最少接続
upstream least_conn_backend {
    least_conn;
    server lc1.example.com:8080;
    server lc2.example.com:8080;
    server lc3.example.com:8080;
}

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

    location /app/ {
        proxy_pass http://app_servers;
    }

    location /session/ {
        proxy_pass http://session_backend;
    }

    location /api/ {
        proxy_pass http://least_conn_backend;
    }
}

キャッシュ設定

# プロキシキャッシュ設定
proxy_cache_path /var/cache/nginx/proxy levels=1:2 keys_zone=my_cache:10m max_size=10g 
                 inactive=60m use_temp_path=off;

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

    location / {
        proxy_pass http://backend;
        proxy_cache my_cache;
        proxy_cache_valid 200 301 302 10m;
        proxy_cache_valid 404 1m;
        proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
        proxy_cache_lock on;
        proxy_cache_revalidate on;
        
        # キャッシュヘッダー
        add_header X-Cache-Status $upstream_cache_status;
        
        # キャッシュキー
        proxy_cache_key "$scheme$request_method$host$request_uri";
    }

    # キャッシュ削除用
    location ~ /purge(/.*) {
        allow 127.0.0.1;
        deny all;
        proxy_cache_purge my_cache "$scheme$request_method$host$1";
    }
}

パフォーマンス最適化

ワーカープロセス調整

# nginxチューニング設定
user nginx;
worker_processes auto;
worker_rlimit_nofile 100000;

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

http {
    # 接続設定
    keepalive_timeout 30;
    keepalive_requests 100;
    reset_timedout_connection on;
    send_timeout 2;
    
    # バッファサイズ
    client_body_buffer_size 128k;
    client_max_body_size 10m;
    client_header_buffer_size 1k;
    large_client_header_buffers 4 4k;
    output_buffers 1 32k;
    postpone_output 1460;
    
    # ファイル操作
    sendfile on;
    sendfile_max_chunk 128k;
    tcp_nopush on;
    tcp_nodelay on;
    open_file_cache max=200000 inactive=20s;
    open_file_cache_valid 30s;
    open_file_cache_min_uses 2;
    open_file_cache_errors on;
}

システムレベル最適化

# /etc/security/limits.conf
nginx soft nofile 100000
nginx hard nofile 100000

# /etc/sysctl.conf
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 5000
net.core.rmem_default = 262144
net.core.rmem_max = 16777216
net.core.wmem_default = 262144
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 12582912 16777216
net.ipv4.tcp_wmem = 4096 12582912 16777216
net.ipv4.tcp_max_syn_backlog = 8096
net.ipv4.tcp_slow_start_after_idle = 0
net.ipv4.tcp_tw_reuse = 1
net.ipv4.ip_local_port_range = 10240 65535

HTTP/2とHTTP/3設定

server {
    listen 443 ssl http2;
    # HTTP/3 (QUIC) サポート
    listen 443 quic reuseport;
    
    server_name example.com;
    
    # HTTP/3 ヘッダー追加
    add_header Alt-Svc 'h3=":443"; ma=86400';
    
    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;
    
    # HTTP/2 Server Push
    location / {
        root /var/www/html;
        http2_push /css/style.css;
        http2_push /js/app.js;
    }
}

セキュリティ設定

基本セキュリティ

# セキュリティヘッダー
server {
    listen 443 ssl http2;
    server_name secure.example.com;

    # セキュリティヘッダー
    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 "no-referrer-when-downgrade" always;
    add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;

    # サーバー情報隠蔽
    server_tokens off;
    
    # 不要なメソッド拒否
    if ($request_method !~ ^(GET|HEAD|POST)$ ) {
        return 405;
    }

    location / {
        root /var/www/html;
    }
}

Rate Limiting

http {
    # レート制限ゾーン定義
    limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
    limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
    limit_req_zone $binary_remote_addr zone=general:10m rate=1r/s;

    server {
        listen 80;
        server_name example.com;

        # ログイン制限
        location /login {
            limit_req zone=login burst=3 nodelay;
            proxy_pass http://backend;
        }

        # API制限
        location /api/ {
            limit_req zone=api burst=20 nodelay;
            proxy_pass http://backend;
        }

        # 一般制限
        location / {
            limit_req zone=general burst=10 nodelay;
            root /var/www/html;
        }
    }
}

アクセス制御

# GeoIP による地域制限
http {
    geoip_country /usr/share/GeoIP/GeoIP.dat;
    
    map $geoip_country_code $allowed_country {
        default yes;
        CN no;
        RU no;
    }
}

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

    # 地域制限
    if ($allowed_country = no) {
        return 403;
    }

    # IP制限
    location /admin/ {
        allow 192.168.1.0/24;
        allow 10.0.0.0/8;
        deny all;
        
        auth_basic "Admin Area";
        auth_basic_user_file /etc/nginx/.htpasswd;
        
        proxy_pass http://admin_backend;
    }
}

監視・メンテナンス

Nginx Status設定

server {
    listen 127.0.0.1:80;
    server_name localhost;

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

    location /fpm_status {
        fastcgi_pass unix:/var/run/php-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
        allow 127.0.0.1;
        deny all;
    }
}

ログ分析設定

http {
    # カスタムログ形式
    log_format detailed '$remote_addr - $remote_user [$time_local] '
                       '"$request" $status $bytes_sent '
                       '"$http_referer" "$http_user_agent" '
                       '$request_time $upstream_response_time '
                       '$pipe $upstream_cache_status';

    # アクセスログ
    access_log /var/log/nginx/access.log detailed;
    
    # エラーログレベル
    error_log /var/log/nginx/error.log warn;
}

ヘルスチェック

#!/bin/bash
# nginx-health-check.sh

# Nginx プロセスチェック
if ! pgrep -x nginx > /dev/null; then
    echo "ERROR: Nginx is not running"
    exit 1
fi

# 設定ファイルチェック
if ! nginx -t >/dev/null 2>&1; then
    echo "ERROR: Nginx configuration is invalid"
    exit 1
fi

# ステータスチェック
STATUS=$(curl -s -o /dev/null -w "%{http_code}" http://localhost/nginx_status)
if [ "$STATUS" != "200" ]; then
    echo "ERROR: Nginx status endpoint not accessible"
    exit 1
fi

echo "OK: Nginx is healthy"
exit 0

本番環境運用

Systemd設定

# /etc/systemd/system/nginx.service
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=mixed
PrivateTmp=true

[Install]
WantedBy=multi-user.target

Docker設定

FROM nginx:1.25-alpine

# カスタム設定ファイルのコピー
COPY nginx.conf /etc/nginx/nginx.conf
COPY conf.d/ /etc/nginx/conf.d/

# SSL証明書のコピー
COPY ssl/ /etc/ssl/

# 静的ファイルのコピー
COPY html/ /var/www/html/

# ポート公開
EXPOSE 80 443

# ヘルスチェック
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -f http://localhost/health || exit 1

CMD ["nginx", "-g", "daemon off;"]

自動化スクリプト

#!/bin/bash
# nginx-deploy.sh

set -e

NGINX_CONFIG_DIR="/etc/nginx"
BACKUP_DIR="/backup/nginx"
DATE=$(date +%Y%m%d_%H%M%S)

# バックアップ作成
sudo mkdir -p $BACKUP_DIR
sudo tar -czf $BACKUP_DIR/nginx_config_$DATE.tar.gz $NGINX_CONFIG_DIR

# 設定テスト
sudo nginx -t

# グレースフルリロード
sudo nginx -s reload

echo "Nginx configuration deployed successfully"

参考ページ