Chapter 2

Chapter 2: Install & Configure Nginx

Sekarang kita akan install Nginx dan configure untuk serve static site.

Apa itu Nginx?

Nginx (dibaca “engine-x”) adalah web server yang:

  • ✅ Sangat cepat & lightweight
  • ✅ Handle banyak concurrent connections
  • ✅ Low memory usage
  • ✅ Popular untuk static sites & reverse proxy

Alternatif: Apache, Caddy, Lighttpd

Install Nginx

# Update package list
sudo apt update

# Install Nginx
sudo apt install nginx -y

# Check version
nginx -v
# Output: nginx version: nginx/1.18.0 (Ubuntu)

# Check status
sudo systemctl status nginx

Output harusnya:

● nginx.service - A high performance web server
     Loaded: loaded (/lib/systemd/system/nginx.service)
     Active: active (running)

Test Nginx

Buka browser dan akses server IP Anda:

http://YOUR_SERVER_IP

Harusnya muncul “Welcome to nginx!” page.

Nginx Directory Structure

/etc/nginx/
├── nginx.conf              # Main config
├── sites-available/        # Available site configs
│   └── default            # Default site config
├── sites-enabled/          # Enabled site configs (symlinks)
│   └── default → ../sites-available/default
├── snippets/              # Reusable config snippets
└── conf.d/                # Additional configs

Important directories:

  • /etc/nginx/ - Configuration files
  • /var/www/html/ - Default web root
  • /var/log/nginx/ - Log files

Basic Nginx Commands

# Start Nginx
sudo systemctl start nginx

# Stop Nginx
sudo systemctl stop nginx

# Restart Nginx
sudo systemctl restart nginx

# Reload config (tanpa downtime)
sudo systemctl reload nginx

# Enable auto-start on boot
sudo systemctl enable nginx

# Check config syntax
sudo nginx -t

# View logs
sudo tail -f /var/log/nginx/access.log
sudo tail -f /var/log/nginx/error.log

Create Site Directory

# Create directory untuk site
sudo mkdir -p /var/www/yourdomain.com/html

# Set ownership
sudo chown -R $USER:$USER /var/www/yourdomain.com/html

# Set permissions
sudo chmod -R 755 /var/www/yourdomain.com

# Create test index.html
echo "<h1>Hello from yourdomain.com!</h1>" > /var/www/yourdomain.com/html/index.html

Configure Nginx Site

Create New Server Block

# Create config file
sudo nano /etc/nginx/sites-available/yourdomain.com

Paste config berikut:

server {
    listen 80;
    listen [::]:80;

    server_name yourdomain.com www.yourdomain.com;

    root /var/www/yourdomain.com/html;
    index index.html index.htm;

    # Logs
    access_log /var/log/nginx/yourdomain.com.access.log;
    error_log /var/log/nginx/yourdomain.com.error.log;

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

    # Gzip compression
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_types text/plain text/css text/xml text/javascript
               application/x-javascript application/xml+rss
               application/json application/javascript;

    # Security headers
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;

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

Penjelasan Config:

DirectiveFungsi
listen 80Listen di port 80 (HTTP)
server_nameDomain yang di-serve
rootDocument root directory
indexDefault file names
try_filesCoba serve file, kalau tidak ada return 404
gzipCompress files sebelum send ke client
add_headerSecurity headers
expiresBrowser caching untuk static files

Enable Site

# Create symbolic link ke sites-enabled
sudo ln -s /etc/nginx/sites-available/yourdomain.com /etc/nginx/sites-enabled/

# Remove default site (optional)
sudo rm /etc/nginx/sites-enabled/default

# Test config
sudo nginx -t

# Output harusnya:
# nginx: configuration file /etc/nginx/nginx.conf test is successful

# Reload Nginx
sudo systemctl reload nginx

Test Configuration

Jika belum punya domain, test dengan IP:

# Edit config sementara
sudo nano /etc/nginx/sites-available/yourdomain.com

# Ubah server_name menjadi:
server_name YOUR_SERVER_IP;

# Reload
sudo nginx -t && sudo systemctl reload nginx

Buka browser: http://YOUR_SERVER_IP

Harusnya muncul “Hello from yourdomain.com!”

Multiple Sites (Virtual Hosts)

Nginx bisa serve multiple sites dari satu server:

/etc/nginx/sites-available/
├── site1.com
├── site2.com
└── site3.com

/var/www/
├── site1.com/html/
├── site2.com/html/
└── site3.com/html/

Buat config baru untuk setiap site:

sudo cp /etc/nginx/sites-available/yourdomain.com /etc/nginx/sites-available/site2.com
sudo nano /etc/nginx/sites-available/site2.com
# Ubah server_name dan root path

Performance Tuning

Edit main config:

sudo nano /etc/nginx/nginx.conf

Tambahkan/update:

# Worker processes (1 per CPU core)
worker_processes auto;

# Max connections per worker
events {
    worker_connections 1024;
    use epoll;
}

http {
    # ... existing config ...

    # Keepalive timeout
    keepalive_timeout 65;

    # Client body size limit
    client_max_body_size 10M;

    # Timeouts
    client_body_timeout 12;
    client_header_timeout 12;
    send_timeout 10;

    # Hide Nginx version
    server_tokens off;
}

Monitoring & Logs

View Logs

# Access log (who accessed your site)
sudo tail -f /var/log/nginx/yourdomain.com.access.log

# Error log (what went wrong)
sudo tail -f /var/log/nginx/yourdomain.com.error.log

# All access logs
sudo tail -f /var/log/nginx/access.log

Log Format Example

192.168.1.100 - - [10/Mar/2024:10:30:45 +0000] "GET / HTTP/1.1" 200 1234

Format: IP - - [timestamp] "METHOD path HTTP/version" status bytes

Troubleshooting

502 Bad Gateway

Penyebab: Backend app tidak running atau unreachable

Solusi:

# Check nginx status
sudo systemctl status nginx

# Check error logs
sudo tail /var/log/nginx/error.log

# Restart nginx
sudo systemctl restart nginx

403 Forbidden

Penyebab: Permission issue

Solusi:

# Check file permissions
ls -la /var/www/yourdomain.com/html/

# Fix ownership
sudo chown -R www-data:www-data /var/www/yourdomain.com/html/

# Fix permissions
sudo chmod -R 755 /var/www/yourdomain.com/html/

Config Test Failed

# Test config and show errors
sudo nginx -t

# Common errors:
# - Missing semicolon ;
# - Typo in directive name
# - Bracket mismatch { }

Nginx Won’t Start

# Check if port 80 already used
sudo lsof -i :80

# Check system logs
sudo journalctl -xeu nginx

# Check nginx error log
sudo cat /var/log/nginx/error.log

Security Hardening

1. Disable Directory Listing

Tambahkan di server block:

location / {
    autoindex off;
}

2. Limit Request Rate (DDoS Protection)

# Di nginx.conf, dalam http block:
limit_req_zone $binary_remote_addr zone=limitreq:10m rate=10r/s;

# Di server block:
limit_req zone=limitreq burst=20 nodelay;

3. Block Bad Bots

# Di server block:
if ($http_user_agent ~* (bot|crawler|spider|scraper)) {
    return 403;
}

4. Fail2Ban Integration

# Install fail2ban
sudo apt install fail2ban -y

# Configure for nginx
sudo nano /etc/fail2ban/jail.local

Add:

[nginx-http-auth]
enabled = true

[nginx-noscript]
enabled = true

[nginx-badbots]
enabled = true
# Restart fail2ban
sudo systemctl restart fail2ban

Useful Nginx Snippets

Force HTTPS Redirect

server {
    listen 80;
    server_name yourdomain.com www.yourdomain.com;
    return 301 https://$server_name$request_uri;
}

Custom Error Pages

error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;

location = /404.html {
    root /var/www/yourdomain.com/html;
    internal;
}

Basic Authentication

# Install tools
sudo apt install apache2-utils

# Create password file
sudo htpasswd -c /etc/nginx/.htpasswd admin

# Add to nginx config:
location /admin {
    auth_basic "Restricted Area";
    auth_basic_user_file /etc/nginx/.htpasswd;
}

Kesimpulan

Sekarang Anda sudah:

✅ Install Nginx ✅ Configure server block ✅ Understand Nginx directory structure ✅ Know basic commands & troubleshooting ✅ Applied security best practices ✅ Ready untuk deploy Hugo site!

Di chapter selanjutnya, kita akan build Hugo site dan upload ke server!


Previous: ← Chapter 1 - Setup VPS & SSH Next: Chapter 3 - Deploy Hugo Site →