Configuration Guide

Configuration Overview

WebServ uses an nginx-inspired configuration syntax that is both powerful and familiar. Configuration files consist of directive blocks that define server behavior.

Configuration Structure

# Global directives (coming soon)
worker_processes auto;
error_log logs/error.log;

# Server blocks define virtual hosts
server {
    # Server-specific directives
    listen 80;
    server_name example.com;
    root /var/www/html;
    
    # Location blocks define URI-specific behavior
    location / {
        # Location-specific directives
        try_files $uri $uri/ =404;
    }
    
    location /api/ {
        proxy_pass http://backend;
    }
}
💡 Note: Comments start with # and continue to the end of the line. Directives end with semicolons ; and blocks are enclosed in braces {}.

Server Directives

Server directives define the behavior of virtual hosts and are placed within server {} blocks.

Directive Syntax Description
listen listen port [ssl]; Specifies the port to listen on, optionally with SSL
server_name server_name name ...; Defines server names for virtual hosting
root root path; Sets the document root directory
index index file ...; Defines default files to serve for directories
error_page error_page code ... uri; Defines custom error pages for HTTP status codes
client_max_body_size client_max_body_size size; Maximum allowed size of client request body

Listen Directive Examples

# Basic HTTP server
listen 80;

# HTTPS server
listen 443 ssl;

# Specific interface
listen 192.168.1.10:8080;

# IPv6
listen [::]:80;

Server Name Examples

# Exact match
server_name example.com;

# Multiple names
server_name example.com www.example.com;

# Wildcard
server_name *.example.com;

# Regular expression
server_name ~^www\.(.+)$;

Location Directives

Location blocks define how to process requests for specific URIs and are placed within server {} blocks.

Location Matching

# Exact match
location = /favicon.ico {
    expires 1y;
}

# Prefix match
location /images/ {
    expires 7d;
}

# Regular expression (case-sensitive)
location ~ \.(jpg|jpeg|png|gif)$ {
    expires 1M;
}

# Regular expression (case-insensitive)
location ~* \.(css|js)$ {
    expires 1y;
}
Directive Syntax Description
try_files try_files file ... uri; Tries files in order, falls back to URI
alias alias path; Maps location to a different path
return return code [text]; Returns HTTP response with status code
rewrite rewrite regex replacement; Rewrites URI using regular expressions
autoindex autoindex on|off; Enables/disables directory listing
expires expires time; Sets cache expiration headers

Configuration Examples

Static Website

server {
    listen 80;
    server_name mysite.com www.mysite.com;
    root /var/www/mysite;
    index index.html index.htm;
    
    # Cache static assets
    location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
    
    # Security headers
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";
    add_header X-XSS-Protection "1; mode=block";
    
    # Custom error pages
    error_page 404 /404.html;
    error_page 500 502 503 504 /50x.html;
}

API Server with Reverse Proxy

server {
    listen 80;
    server_name api.example.com;
    
    # API endpoints
    location /v1/ {
        proxy_pass http://127.0.0.1:3000;
        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;
        
        # CORS headers
        add_header Access-Control-Allow-Origin "*";
        add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
        add_header Access-Control-Allow-Headers "Content-Type, Authorization";
    }
    
    # Handle preflight requests
    location / {
        if ($request_method = 'OPTIONS') {
            add_header Access-Control-Allow-Origin "*";
            add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
            add_header Access-Control-Allow-Headers "Content-Type, Authorization";
            add_header Content-Length 0;
            return 204;
        }
    }
}

Multi-Domain Hosting

# Main website
server {
    listen 80;
    server_name example.com www.example.com;
    root /var/www/example.com;
    index index.html;
    
    location / {
        try_files $uri $uri/ =404;
    }
}

# Blog subdomain
server {
    listen 80;
    server_name blog.example.com;
    root /var/www/blog;
    index index.html;
    
    # WordPress-style permalinks
    location / {
        try_files $uri $uri/ /index.php?$args;
    }
}

# File sharing subdomain
server {
    listen 80;
    server_name files.example.com;
    root /var/www/files;
    
    # Enable directory browsing
    location / {
        autoindex on;
        autoindex_exact_size off;
        autoindex_localtime on;
    }
    
    # Restrict access to sensitive files
    location ~ /\. {
        deny all;
    }
}

Development Server

server {
    listen 8080;
    server_name localhost;
    root ./www;
    index index.html;
    
    # Disable caching for development
    expires -1;
    add_header Cache-Control "no-cache, no-store, must-revalidate";
    add_header Pragma "no-cache";
    
    # Enable directory listing
    autoindex on;
    
    # Detailed error pages
    error_page 404 /dev-404.html;
    
    # Hot reload support
    location /ws {
        proxy_pass http://127.0.0.1:3001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

Best Practices

Security

# Security headers example
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
add_header X-XSS-Protection "1; mode=block";
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";

# Hide server information
server_tokens off;

# Restrict sensitive files
location ~ /\.(ht|git|svn) {
    deny all;
}

Performance

# Performance optimizations
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;

# Gzip compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript;

Organization

⚠️ Important: Always test configuration changes in a development environment before applying them to production. Use webserv -t config.conf to validate syntax.

Need more help? Check out the Getting Started guide or API Reference.