Nginx (Proxy)
高性能リバースプロキシサーバー。HTTP/2、HTTP/3対応、SSL終端、キャッシング機能。イベント駆動アーキテクチャで低メモリ使用量。
NGINX
NGINXは、高性能でスケーラブルなWebサーバー、リバースプロキシ、ロードバランサーです。非同期イベント駆動アーキテクチャにより、少ないメモリで多数の同時接続を処理でき、静的コンテンツの配信、動的アプリケーションの処理、ロードバランシングに優れています。
主な特徴
高性能アーキテクチャ
- 非同期イベント駆動型処理
- 少ないメモリ使用量で高い同時接続数
- C10K問題の解決
- マルチプロセス・マルチワーカー構成
多機能プロキシ
- HTTPリバースプロキシ
- TCP/UDPプロキシ(stream module)
- 高度なロードバランシング
- SSL/TLS終端とオフロード
柔軟な設定システム
- 直感的な設定ファイル構文
- モジュールベースのアーキテクチャ
- 動的設定リロード
- 豊富な内蔵変数とディレクティブ
インストール
Ubuntu/Debian
# 公式リポジトリの追加
curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo gpg --dearmor -o /usr/share/keyrings/nginx-archive-keyring.gpg
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
# サービス有効化・開始
sudo systemctl enable nginx
sudo systemctl start nginx
CentOS/RHEL
# 公式リポジトリの追加
cat <<EOF | sudo tee /etc/yum.repos.d/nginx.repo
[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 systemctl enable nginx
sudo systemctl start nginx
ソースからのビルド
# 依存関係のインストール
sudo apt install build-essential libpcre3-dev libssl-dev zlib1g-dev
# NGINXソースのダウンロード
wget http://nginx.org/download/nginx-1.24.0.tar.gz
tar -xzf nginx-1.24.0.tar.gz
cd nginx-1.24.0
# コンパイル設定
./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 \
--access-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_gzip_static_module \
--with-http_secure_link_module \
--with-http_stub_status_module \
--with-stream \
--with-stream_ssl_module
# ビルド・インストール
make
sudo make install
Docker
# 基本起動
docker run --name my-nginx -p 80:80 -d nginx
# カスタム設定とコンテンツ
docker run --name my-nginx \
-p 80:80 \
-v /path/to/nginx.conf:/etc/nginx/nginx.conf:ro \
-v /path/to/html:/usr/share/nginx/html:ro \
-d nginx
# SSL対応
docker run --name my-nginx \
-p 80:80 \
-p 443:443 \
-v /path/to/ssl:/etc/nginx/ssl:ro \
-v /path/to/nginx.conf:/etc/nginx/nginx.conf:ro \
-d nginx
基本設定
メイン設定(nginx.conf)
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
use epoll;
multi_accept on;
}
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" "$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 4096;
# 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/atom+xml
image/svg+xml;
# セキュリティヘッダー
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
include /etc/nginx/conf.d/*.conf;
}
仮想ホスト設定
# /etc/nginx/conf.d/default.conf
server {
listen 80;
server_name example.com www.example.com;
root /usr/share/nginx/html;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
log_not_found off;
access_log off;
}
}
ロードバランシング
HTTP ロードバランサー
# upstream定義
upstream backend {
# ラウンドロビン(デフォルト)
server backend1.example.com;
server backend2.example.com;
server backend3.example.com backup;
}
upstream api_servers {
# 最小接続数
least_conn;
server api1.example.com:8080 weight=3;
server api2.example.com:8080 weight=2;
server api3.example.com:8080 weight=1;
}
upstream hash_backend {
# ハッシュ分散(一貫性ハッシュ)
hash $request_uri consistent;
server cache1.example.com:8080;
server cache2.example.com:8080;
server cache3.example.com:8080;
}
# サーバー設定
server {
listen 80;
server_name load-balancer.example.com;
location / {
proxy_pass http://backend;
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_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_connect_timeout 5s;
proxy_read_timeout 10s;
}
location /api/ {
proxy_pass http://api_servers/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /cache/ {
proxy_pass http://hash_backend/;
proxy_set_header Host $host;
proxy_cache_bypass $http_pragma $http_authorization;
}
}
高度なロードバランシング設定
upstream app_servers {
# 最小時間(NGINX Plus)
least_time header;
# サーバー設定オプション
server app1.example.com:8080 max_fails=3 fail_timeout=30s weight=5;
server app2.example.com:8080 max_fails=3 fail_timeout=30s weight=3;
server app3.example.com:8080 max_fails=3 fail_timeout=30s weight=2;
server app4.example.com:8080 max_conns=100;
# バックアップサーバー
server backup.example.com:8080 backup;
# ゾーン設定(NGINX Plus)
zone app_servers 64k;
# セッション持続性(NGINX Plus)
sticky cookie srv_id expires=1h domain=.example.com path=/;
}
# ランダム分散
upstream random_backend {
random two least_time=last_byte;
server srv1.example.com;
server srv2.example.com;
server srv3.example.com;
server srv4.example.com;
}
TCP/UDP ロードバランシング
# streamコンテキスト
stream {
upstream mysql_servers {
least_conn;
server mysql1.example.com:3306 max_fails=2 fail_timeout=30s;
server mysql2.example.com:3306 max_fails=2 fail_timeout=30s;
server mysql3.example.com:3306 backup;
}
upstream redis_servers {
hash $remote_addr consistent;
server redis1.example.com:6379;
server redis2.example.com:6379;
server redis3.example.com:6379;
}
upstream dns_servers {
server 8.8.8.8:53;
server 8.8.4.4:53;
server 1.1.1.1:53;
}
# MySQL プロキシ
server {
listen 3306;
proxy_pass mysql_servers;
proxy_timeout 3s;
proxy_connect_timeout 1s;
}
# Redis プロキシ
server {
listen 6379;
proxy_pass redis_servers;
proxy_timeout 5s;
proxy_responses 1;
}
# DNS プロキシ(UDP)
server {
listen 53 udp;
proxy_pass dns_servers;
proxy_timeout 1s;
proxy_responses 1;
}
}
SSL/TLS設定
基本SSL設定
server {
listen 443 ssl http2;
server_name secure.example.com;
# SSL証明書
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
# SSL設定
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers off;
# HSTS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# OCSP ステープリング
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/nginx/ssl/chain.crt;
# セッション設定
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 1d;
ssl_session_tickets off;
location / {
proxy_pass http://backend;
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;
}
}
# HTTPからHTTPSへのリダイレクト
server {
listen 80;
server_name secure.example.com;
return 301 https://$server_name$request_uri;
}
Let's Encrypt証明書の取得
# Certbotのインストール
sudo apt install certbot python3-certbot-nginx
# 証明書の取得と設定
sudo certbot --nginx -d example.com -d www.example.com
# 証明書の自動更新設定
sudo crontab -e
# 以下を追加
0 12 * * * /usr/bin/certbot renew --quiet
キャッシュ設定
プロキシキャッシュ
# キャッシュパスの定義
proxy_cache_path /var/cache/nginx/proxy
levels=1:2
keys_zone=proxy_cache:10m
max_size=1g
inactive=60m
use_temp_path=off;
server {
listen 80;
server_name cache.example.com;
location / {
proxy_pass http://backend;
proxy_cache proxy_cache;
proxy_cache_valid 200 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_background_update on;
# キャッシュヘッダー
add_header X-Cache-Status $upstream_cache_status;
# キャッシュキー
proxy_cache_key "$scheme$request_method$host$request_uri";
# 条件付きキャッシュ
proxy_cache_bypass $http_pragma $http_authorization;
proxy_no_cache $http_pragma $http_authorization;
}
# キャッシュパージ(NGINX Plus)
location ~ /purge(/.*) {
allow 127.0.0.1;
deny all;
proxy_cache_purge proxy_cache "$scheme$request_method$host$1";
}
}
FastCGIキャッシュ
# FastCGIキャッシュパス
fastcgi_cache_path /var/cache/nginx/fastcgi
levels=1:2
keys_zone=fastcgi_cache:10m
max_size=500m
inactive=60m;
server {
listen 80;
server_name php.example.com;
root /var/www/html;
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
# FastCGIキャッシュ
fastcgi_cache fastcgi_cache;
fastcgi_cache_valid 200 60m;
fastcgi_cache_valid 404 10m;
fastcgi_cache_methods GET HEAD;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
# キャッシュバイパス条件
fastcgi_cache_bypass $http_pragma $http_authorization $cookie_nocache $arg_nocache;
fastcgi_no_cache $http_pragma $http_authorization $cookie_nocache $arg_nocache;
add_header X-FastCGI-Cache $upstream_cache_status;
}
}
セキュリティ設定
レート制限
# レート制限ゾーンの定義
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=login_limit:10m rate=1r/s;
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
server {
listen 80;
server_name api.example.com;
# 接続数制限
limit_conn conn_limit 20;
location /api/ {
# API レート制限
limit_req zone=api_limit burst=20 nodelay;
proxy_pass http://api_backend;
}
location /login {
# ログイン レート制限
limit_req zone=login_limit burst=5;
proxy_pass http://auth_backend;
}
}
アクセス制御
# GeoIPによる制御
geo $allowed_country {
default 0;
JP 1;
US 1;
DE 1;
}
server {
listen 80;
server_name restricted.example.com;
# 国別アクセス制御
if ($allowed_country = 0) {
return 403;
}
# IP制限
location /admin/ {
allow 192.168.1.0/24;
allow 10.0.0.0/8;
deny all;
proxy_pass http://admin_backend;
}
# Basic認証
location /private/ {
auth_basic "Restricted Area";
auth_basic_user_file /etc/nginx/htpasswd;
proxy_pass http://private_backend;
}
}
セキュリティヘッダー
# セキュリティ設定マップ
map $sent_http_content_type $nosniff_header {
~^text/html "nosniff";
}
server {
listen 443 ssl http2;
server_name secure.example.com;
# セキュリティヘッダー
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options $nosniff_header always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'" always;
# HSTS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# サーバー情報の隠蔽
server_tokens off;
more_clear_headers Server;
location / {
proxy_pass http://backend;
proxy_hide_header X-Powered-By;
}
}
監視とログ
詳細ログ設定
# カスタムログフォーマット
log_format detailed '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time $upstream_response_time '
'$upstream_addr $upstream_status';
log_format json escape=json '{'
'"timestamp": "$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",'
'"upstream_addr": "$upstream_addr"'
'}';
server {
listen 80;
server_name example.com;
# 複数のアクセスログ
access_log /var/log/nginx/access.log detailed;
access_log /var/log/nginx/access.json json;
# エラーログレベル
error_log /var/log/nginx/error.log warn;
location / {
proxy_pass http://backend;
}
}
ステータス・監視エンドポイント
# ステータスモジュール設定
server {
listen 80;
server_name status.example.com;
location /nginx_status {
stub_status;
allow 127.0.0.1;
allow 192.168.1.0/24;
deny all;
}
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
# Plus API(NGINX Plus)
location /api {
api write=on;
allow 127.0.0.1;
deny all;
}
# Plus ダッシュボード(NGINX Plus)
location = /dashboard.html {
root /usr/share/nginx/html;
}
}
ログローテーション
# /etc/logrotate.d/nginx
/var/log/nginx/*.log {
daily
missingok
rotate 52
compress
delaycompress
notifempty
create 644 nginx nginx
postrotate
if [ -f /var/run/nginx.pid ]; then
kill -USR1 `cat /var/run/nginx.pid`
fi
endscript
}
パフォーマンス最適化
ワーカープロセス最適化
# メインコンテキスト
user nginx;
worker_processes auto;
worker_cpu_affinity auto;
worker_priority -10;
worker_rlimit_nofile 65535;
events {
worker_connections 4096;
use epoll;
multi_accept on;
accept_mutex off;
}
http {
# バッファサイズ調整
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;
# タイムアウト設定
client_header_timeout 3m;
client_body_timeout 3m;
send_timeout 3m;
# TCP最適化
sendfile on;
tcp_nopush on;
tcp_nodelay on;
# Keepalive設定
keepalive_timeout 65;
keepalive_requests 1000;
# ファイルキャッシュ
open_file_cache max=1000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
}
圧縮設定
http {
# Gzip圧縮
gzip on;
gzip_vary on;
gzip_min_length 1024;
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/atom+xml
image/svg+xml
application/x-font-ttf
application/vnd.ms-fontobject
font/opentype;
# Brotli圧縮(モジュール必要)
brotli on;
brotli_comp_level 6;
brotli_types
text/plain
text/css
application/json
application/javascript
text/xml
application/xml
application/xml+rss
text/javascript;
}
トラブルシューティング
設定テストと再起動
# 設定ファイルのテスト
nginx -t
# 設定のリロード
nginx -s reload
# プロセス停止
nginx -s stop
# プロセス再起動(graceful)
nginx -s quit
# サービス管理
systemctl status nginx
systemctl restart nginx
systemctl reload nginx
デバッグとログ分析
# エラーログの確認
tail -f /var/log/nginx/error.log
# アクセスログの分析
tail -f /var/log/nginx/access.log | grep "GET"
# リアルタイム統計(NGINX Plus)
curl http://localhost/api/8/nginx
# プロセス情報
ps aux | grep nginx
よくある問題と解決法
# 504 Gateway Timeout対策
proxy_read_timeout 300s;
proxy_connect_timeout 75s;
proxy_send_timeout 300s;
# 413 Request Entity Too Large対策
client_max_body_size 100M;
# 502 Bad Gateway対策
upstream backend {
server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
keepalive 32;
}
# WebSocket対応
location /ws/ {
proxy_pass http://websocket_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
NGINXは、その高性能と柔軟性により、Webサーバー、リバースプロキシ、ロードバランサーとして世界中で広く採用されています。適切な設定と運用により、高可用性で拡張性の高いWebインフラストラクチャを構築できます。