DevOps & Cloud

Nginx: Web Server & Load Balancer

Tutorial lengkap Nginx dari instalasi hingga konfigurasi lanjutan — server blocks, reverse proxy, load balancing, SSL/TLS, caching, dan optimasi performa

1. Pengenalan Nginx

Nginx (diucapkan "engine-x") adalah web server open-source berkinerja tinggi yang juga berfungsi sebagai reverse proxy, load balancer, dan HTTP cache. Nginx dirancang untuk menangani koneksi simultan yang sangat tinggi dengan penggunaan resource yang minimal.

Nginx diperkenalkan oleh Igor Sysoev pada tahun 2004 untuk mengatasi masalah C10K problem — yaitu kemampuan web server menangani 10.000 koneksi simultan. Berbeda dengan Apache yang menggunakan model thread-per-connection, Nginx menggunakan event-driven, asynchronous architecture yang sangat efisien.

Nginx vs Apache

Aspek Nginx Apache
ArchitectureEvent-driven, asynchronousProcess/thread per connection
Koneksi SimultanSangat tinggi (ribuan)Sedang (ratusan)
Memory UsageRendah (~2.5MB base)Lebih tinggi
Static ContentSangat cepatCukup cepat
Dynamic ContentVia FastCGI/proxymod_php (embedded)
ConfigurationCentrally managed.htaccess per direktori
Load BalancingBuilt-in, nativeVia mod_proxy
Market Share~34% dari busiest sites~31%

Kegunaan Utama Nginx

Diagram: Peran Nginx dalam Arsitektur Web
┌───────────────────────────────────────────────────────────────┐
│                 NGINX PERAN & USE CASES                       │
│                                                               │
│  ┌─────────────┐                                              │
│  │   CLIENTS   │  Browser, Mobile App, API Client             │
│  │ (Millions)  │                                              │
│  └──────┬──────┘                                              │
│         │ HTTPS                                               │
│         ▼                                                     │
│  ┌──────────────────────────────────────────────┐             │
│  │              NGINX                            │             │
│  │  ┌────────────────────────────────────────┐  │             │
│  │  │ 1. Web Server    — Serve static files  │  │             │
│  │  │ 2. Reverse Proxy — Terminate SSL       │  │             │
│  │  │ 3. Load Balancer — Distribute traffic   │  │             │
│  │  │ 4. API Gateway   — Rate limiting        │  │             │
│  │  │ 5. HTTP Cache    — Cache responses      │  │             │
│  │  │ 6. WebSocket     — WS proxy            │  │             │
│  │  └────────────────────────────────────────┘  │             │
│  └────────┬──────────────┬──────────────┬──────┘             │
│           │              │              │                      │
│           ▼              ▼              ▼                      │
│    ┌──────────┐  ┌──────────┐  ┌──────────┐                  │
│    │ App      │  │ App      │  │ App      │                  │
│    │ Server 1 │  │ Server 2 │  │ Server 3 │                  │
│    │ :3000    │  │ :3000    │  │ :3000    │                  │
│    └──────────┘  └──────────┘  └──────────┘                  │
└───────────────────────────────────────────────────────────────┘

2. Instalasi & Konfigurasi Dasar

Instalasi Nginx sangat straightforward. Berikut langkah-langkah untuk menginstal dan mengkonfigurasi Nginx pada server Linux.

Instalasi Nginx

Bash — Instalasi Nginx
# Ubuntu/Debian
sudo apt update
sudo apt install nginx -y

# CentOS/RHEL/Rocky
sudo dnf install nginx -y

# Start dan enable Nginx
sudo systemctl start nginx
sudo systemctl enable nginx

# Cek status
sudo systemctl status nginx

# Test apakah Nginx berjalan
curl http://localhost
# Atau buka http://server-ip di browser

# Cek versi dan modules
nginx -V

Struktur Konfigurasi Nginx

File Structure — Nginx Configuration
/etc/nginx/
├── nginx.conf              ← Konfigurasi utama
├── conf.d/                 ← Tambahan config (auto-include)
│   └── default.conf
├── sites-available/        ← Semua virtual host (Ubuntu)
│   ├── default
│   └── mysite.com
├── sites-enabled/          ← Symlink ke sites-available (aktif)
│   └── default → ../sites-available/default
├── snippets/               ← Config snippets yang reusable
│   ├── ssl-params.conf
│   └── fastcgi-php.conf
├── mime.types              ← Mapping MIME types
└── modules-enabled/        ← Dynamic modules

Konfigurasi Dasar nginx.conf

Nginx — /etc/nginx/nginx.conf
# /etc/nginx/nginx.conf

user www-data;
worker_processes auto;        # Auto = jumlah CPU core
pid /run/nginx.pid;
error_log /var/log/nginx/error.log warn;

events {
    worker_connections 2048;  # Max koneksi per worker
    multi_accept on;          # Terima koneksi baru sekaligus
    use epoll;                # Event method untuk Linux
}

http {
    # Basic settings
    sendfile on;              # Menggunakan sendfile() untuk efisiensi
    tcp_nopush on;            # Optimasi packet
    tcp_nodelay on;           # Kirim data segera
    keepalive_timeout 65;     # Timeout keep-alive connection
    types_hash_max_size 2048;
    server_tokens off;        # Sembunyikan versi Nginx

    # MIME types
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    # Logging
    log_format main '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent" '
                    'rt=$request_time';
    access_log /var/log/nginx/access.log main buffer=16k flush=5s;

    # Gzip compression
    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 4;
    gzip_min_length 256;
    gzip_types
        text/plain
        text/css
        text/javascript
        application/json
        application/javascript
        application/xml
        image/svg+xml;

    # Include server blocks
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}
💡 Perintah Penting Nginx
  • sudo nginx -t — Test konfigurasi sebelum reload (SANGAT PENTING!)
  • sudo nginx -s reload — Reload konfigurasi tanpa downtime
  • sudo nginx -s stop — Stop Nginx secara paksa
  • sudo systemctl reload nginx — Reload via systemd
  • sudo tail -f /var/log/nginx/error.log — Monitor error log real-time

3. Server Blocks (Virtual Hosts)

Server blocks memungkinkan Anda menjalankan beberapa website/domain pada satu server Nginx. Setiap server block mendefinisikan konfigurasi terpisah untuk setiap domain, mirip dengan virtual hosts di Apache.

Contoh Server Block untuk Website

Nginx — Server Block
# /etc/nginx/sites-available/mysite.com

# Redirect HTTP ke HTTPS
server {
    listen 80;
    listen [::]:80;
    server_name mysite.com www.mysite.com;
    return 301 https://$host$request_uri;
}

# Server block utama (HTTPS)
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name mysite.com www.mysite.com;

    # Document root
    root /var/www/mysite.com/public;
    index index.html index.htm;

    # SSL certificate
    ssl_certificate /etc/letsencrypt/live/mysite.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/mysite.com/privkey.pem;

    # Logging
    access_log /var/log/nginx/mysite.com.access.log;
    error_log /var/log/nginx/mysite.com.error.log;

    # Serve static files
    location / {
        try_files $uri $uri/ /index.html;
    }

    # Cache static assets
    location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2)$ {
        expires 30d;
        add_header Cache-Control "public, immutable";
    }

    # Block access ke hidden files
    location ~ /\. {
        deny all;
    }

    # Custom error pages
    error_page 404 /404.html;
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root /usr/share/nginx/html;
    }
}

Aktifkan Server Block

Bash — Enable Server Block
# Buat symlink ke sites-enabled
sudo ln -s /etc/nginx/sites-available/mysite.com /etc/nginx/sites-enabled/

# Test konfigurasi
sudo nginx -t
# Output: syntax is ok, test is successful

# Reload Nginx
sudo systemctl reload nginx

# Buat direktori website
sudo mkdir -p /var/www/mysite.com/public
echo '

Hello from mysite.com

' | sudo tee /var/www/mysite.com/public/index.html # Set permission yang tepat sudo chown -R www-data:www-data /var/www/mysite.com sudo chmod -R 755 /var/www/mysite.com

4. Reverse Proxy

Reverse proxy adalah konfigurasi di mana Nginx menerima request dari client dan meneruskannya ke backend server (Node.js, Python, Go, Java, dll). Ini adalah use case paling umum dari Nginx dalam arsitektur modern.

Konfigurasi Reverse Proxy ke Node.js

Nginx — Reverse Proxy
# /etc/nginx/sites-available/api.mysite.com

upstream node_backend {
    server 127.0.0.1:3000;
    keepalive 32;    # Keep koneksi ke backend
}

server {
    listen 443 ssl http2;
    server_name api.mysite.com;

    ssl_certificate /etc/letsencrypt/live/api.mysite.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.mysite.com/privkey.pem;

    # Proxy ke Node.js backend
    location / {
        proxy_pass http://node_backend;
        proxy_http_version 1.1;

        # Headers untuk meneruskan info client
        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 support
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        # Timeout settings
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;

        # Buffer settings
        proxy_buffering on;
        proxy_buffer_size 4k;
        proxy_buffers 8 4k;
    }

    # Proxy untuk API tertentu ke service lain
    location /api/v2/ {
        proxy_pass http://127.0.0.1:4000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Reverse Proxy ke Beberapa Service

Diagram: Nginx sebagai Central Reverse Proxy
┌─────────────────────────────────────────────────────────────┐
│                  NGINX REVERSE PROXY                        │
│                                                             │
│  Client Request → Nginx (port 443)                         │
│                                                             │
│  ┌───────────────────────────────────────────────────────┐  │
│  │                 ROUTING RULES                         │  │
│  │                                                       │  │
│  │  /                    → React SPA (port 3001)         │  │
│  │  /api/v1/users        → User Service (port 4000)     │  │
│  │  /api/v1/orders       → Order Service (port 4001)    │  │
│  │  /api/v1/payments     → Payment Service (port 4002)  │  │
│  │  /ws                   → WebSocket (port 3002)       │  │
│  │  /admin               → Admin Panel (port 3003)      │  │
│  │  /static              → Static files (disk)          │  │
│  └───────────────────────────────────────────────────────┘  │
│                                                             │
│  Benefits:                                                  │
│  • Single entry point (port 80/443)                        │
│  • SSL termination di Nginx                                │
│  • Backend bisa di-restart tanpa user merasakan            │
│  • Rate limiting & security di satu tempat                  │
└─────────────────────────────────────────────────────────────┘

5. Load Balancing

Load balancing adalah teknik mendistribusikan traffic ke beberapa backend server. Nginx mendukung berbagai metode load balancing yang bisa dipilih sesuai kebutuhan aplikasi Anda.

Metode Load Balancing di Nginx

Metode Deskripsi Cocok Untuk
Round Robin (default)Request didistribusikan secara bergantian ke setiap serverServer dengan kapasitas sama
Least ConnectionsRequest dikirim ke server dengan koneksi aktif paling sedikitRequest dengan durasi bervariasi
IP HashClient IP selalu diarahkan ke server yang sama (sticky session)Aplikasi yang butuh session persistence
WeightedServer dengan weight lebih tinggi menerima lebih banyak requestServer dengan kapasitas berbeda
Generic HashBerdasarkan hash dari variable tertentu (URL, header, dll)Cache efficiency, custom routing

Konfigurasi Load Balancing

Nginx — Load Balancing Configs
# === 1. ROUND ROBIN (Default) ===
upstream app_servers {
    server 10.0.0.1:3000;
    server 10.0.0.2:3000;
    server 10.0.0.3:3000;
}

# === 2. WEIGHTED ===
upstream app_weighted {
    server 10.0.0.1:3000 weight=3;   # Terima 3x lebih banyak
    server 10.0.0.2:3000 weight=2;   # Terima 2x lebih banyak
    server 10.0.0.3:3000 weight=1;   # Standar
}

# === 3. LEAST CONNECTIONS ===
upstream app_least_conn {
    least_conn;
    server 10.0.0.1:3000;
    server 10.0.0.2:3000;
    server 10.0.0.3:3000;
}

# === 4. IP HASH (Sticky Session) ===
upstream app_ip_hash {
    ip_hash;
    server 10.0.0.1:3000;
    server 10.0.0.2:3000;
    server 10.0.0.3:3000;
}

# === 5. DENGAN HEALTH CHECK & FAILOVER ===
upstream app_robust {
    least_conn;

    server 10.0.0.1:3000 weight=3 max_fails=3 fail_timeout=30s;
    server 10.0.0.2:3000 weight=2 max_fails=3 fail_timeout=30s;
    server 10.0.0.3:3000 weight=1 max_fails=3 fail_timeout=30s;

    # Backup server (hanya aktif saat semua server utama down)
    server 10.0.0.4:3000 backup;

    # Server yang dikurangi (maintenance mode)
    # server 10.0.0.5:3000 down;

    keepalive 32;
}

# Server block menggunakan upstream
server {
    listen 443 ssl http2;
    server_name app.mysite.com;

    ssl_certificate /etc/letsencrypt/live/app.mysite.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/app.mysite.com/privkey.pem;

    location / {
        proxy_pass http://app_robust;
        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 Connection "";
        proxy_next_upstream error timeout http_500 http_502 http_503;
    }
}
⚠️ Catatan Health Check

Nginx Open Source melakukan health check secara pasif (berdasarkan response error). Untuk active health check yang bisa melakukan HTTP request ke backend secara berkala, Anda memerlukan Nginx Plus atau menggunakan tool tambahan seperti Consul atau HAProxy.

6. SSL/TLS & HTTPS

SSL/TLS adalah protokol kriptografis yang mengenkripsi komunikasi antara client dan server. Mengaktifkan HTTPS pada website Anda adalah keharusan untuk keamanan, SEO, dan kepercayaan pengguna. Let's Encrypt menyediakan SSL certificate gratis.

Instalasi SSL dengan Let's Encrypt

Bash — SSL Setup dengan Certbot
# Instalasi Certbot
sudo apt install certbot python3-certbot-nginx -y

# Generate dan install SSL certificate (otomatis edit Nginx config)
sudo certbot --nginx -d mysite.com -d www.mysite.com

# Atau generate saja tanpa auto-configure Nginx
sudo certbot certonly --nginx -d mysite.com

# Cek certificate
sudo certbot certificates

# Test auto-renewal
sudo certbot renew --dry-run

# Certbot akan auto-renew via systemd timer
sudo systemctl list-timers | grep certbot

# Manual renewal jika diperlukan
sudo certbot renew
sudo systemctl reload nginx

Hardened SSL Configuration

Nginx — SSL Hardening
# /etc/nginx/snippets/ssl-params.conf

# Protocols — hanya TLS 1.2 dan 1.3
ssl_protocols TLSv1.2 TLSv1.3;

# Ciphers yang aman
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 session caching
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;

# OCSP Stapling (optimasi SSL handshake)
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;

# Security Headers
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;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';" always;

# Diffie-Hellman parameter (generate: openssl dhparam -out /etc/nginx/dhparam.pem 4096)
ssl_dhparam /etc/nginx/dhparam.pem;
💡 Test Konfigurasi SSL

Setelah mengkonfigurasi SSL, test keamanannya:

7. Caching & Optimasi Performa

Caching adalah teknik menyimpan salinan response sehingga request berikutnya bisa dilayani tanpa memproses ulang dari backend. Nginx mendukung berbagai tingkat caching yang bisa mengurangi latency dan beban backend secara signifikan.

Proxy Caching

Nginx — Proxy Caching Configuration
# Di dalam http {} block di nginx.conf

# Definisikan cache zone
proxy_cache_path /var/cache/nginx
    levels=1:2
    keys_zone=my_cache:10m
    max_size=10g
    inactive=60m
    use_temp_path=off;

# Di dalam server {} block

# Proxy dengan caching
location / {
    proxy_pass http://backend;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;

    # Caching settings
    proxy_cache my_cache;
    proxy_cache_valid 200 302 10m;    # Cache response 200/302 selama 10 menit
    proxy_cache_valid 404 1m;          # Cache 404 selama 1 menit
    proxy_cache_valid any 5m;          # Cache semua lainnya 5 menit
    proxy_cache_use_stale error timeout updating http_500 http_502 http_503;
    proxy_cache_lock on;               # Hindari cache stampede

    # Cache bypass (jangan cache untuk kondisi tertentu)
    proxy_cache_bypass $http_authorization;
    proxy_no_cache $arg_nocache;

    # Tambah header untuk debug cache
    add_header X-Cache-Status $upstream_cache_status;
    # Miss = belum di-cache, Hit = dari cache, Bypass = dilewati
}

Konfigurasi Rate Limiting

Nginx — Rate Limiting
# Di dalam http {} block

# Definisikan rate limit zones
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;

# Di dalam server {} block

# Rate limit untuk API
location /api/ {
    limit_req zone=api_limit burst=20 nodelay;
    limit_conn conn_limit 10;
    proxy_pass http://backend;

    # Custom error page saat rate limit tercapai
    limit_req_status 429;
    error_page 429 /429.html;
}

# Rate limit ketat untuk login
location /api/auth/login {
    limit_req zone=login_limit burst=5 nodelay;
    proxy_pass http://backend;
}

Tips Optimasi Nginx Lainnya

💡 Checklist Optimasi Nginx
  • worker_processes auto — Sesuaikan dengan jumlah CPU core
  • sendfile on — Menggunakan kernel zero-copy untuk file transfer
  • gzip on — Kompresi response untuk bandwidth hemat
  • proxy_cache — Cache response backend di Nginx
  • keepalive — Pertahankan koneksi ke backend untuk efisiensi
  • HTTP/2 — Aktifkan listen 443 ssl http2
  • Buffer tuning — Sesuaikan proxy_buffer_size dan proxy_buffers
  • Static file caching — Set expires header untuk aset statis
  • Rate limiting — Lindungi API dari abuse
  • server_tokens off — Sembunyikan versi Nginx

8. Quiz: Uji Pemahamanmu!

Setelah membaca tutorial di atas, jawablah 5 pertanyaan berikut untuk menguji pemahamanmu tentang Nginx:

Pertanyaan 1: Apa arsitektur yang membuat Nginx sangat efisien menangani ribuan koneksi simultan?

a) Thread-per-connection model
b) Process-per-request model
c) Event-driven, asynchronous architecture
d) Blocking I/O model

Pertanyaan 2: Apa perintah untuk mengecek validitas konfigurasi Nginx sebelum reload?

a) nginx --check
b) nginx -t
c) nginx -s reload
d) systemctl check nginx

Pertanyaan 3: Metode load balancing apa yang memastikan request dari IP yang sama selalu diarahkan ke server yang sama?

a) Round Robin
b) Least Connections
c) IP Hash
d) Weighted

Pertanyaan 4: Apa fungsi dari proxy_cache_valid di Nginx?

a) Membatasi berapa banyak request yang bisa di-cache
b) Menentukan berapa lama response dengan status tertentu disimpan dalam cache
c) Menentukan ukuran maksimum cache di disk
d) Mengatur bandwidth untuk request yang di-cache

Pertanyaan 5: Tool apa yang digunakan untuk mendapatkan SSL certificate gratis dari Let's Encrypt?

a) OpenSSL
b) Certbot
c) ACME.sh
d) Both B and C (Certbot dan ACME.sh)