WebServ uses an nginx-inspired configuration syntax that is both powerful and familiar. Configuration files consist of directive blocks that define server behavior.
# 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;
}
}
# and continue to the end of the line. Directives end with semicolons ; and blocks are enclosed in braces {}.
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 |
# Basic HTTP server listen 80; # HTTPS server listen 443 ssl; # Specific interface listen 192.168.1.10:8080; # IPv6 listen [::]:80;
# 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 blocks define how to process requests for specific URIs and are placed within server {} blocks.
# 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 |
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;
}
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;
}
}
}
# 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;
}
}
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";
}
}
# 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 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;
webserv -t config.conf to validate syntax.
Need more help? Check out the Getting Started guide or API Reference.