Files
chorus-services-website/nginx.conf
anthonyrawlins f343f89d24 Initial commit: CHORUS Services marketing website
Complete Next.js website with Docker containerization:
- Next.js 14 with TypeScript and Tailwind CSS
- Responsive design with modern UI components
- Hero section, features showcase, testimonials
- FAQ section with comprehensive content
- Contact forms and newsletter signup
- Docker production build with Nginx
- Health checks and monitoring support
- SEO optimization and performance tuning

Ready for integration as git submodule in main CHORUS project.

Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-01 22:45:06 +10:00

183 lines
5.1 KiB
Nginx Configuration File

# CHORUS Services Website - Production Nginx Configuration
# Optimized for performance, security, and Traefik integration
events {
worker_connections 1024;
use epoll;
multi_accept on;
}
http {
# Basic settings
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
client_max_body_size 20M;
# Hide nginx version
server_tokens off;
# 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" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log warn;
# Gzip compression
gzip on;
gzip_vary on;
gzip_min_length 1000;
gzip_proxied any;
gzip_comp_level 6;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/javascript
application/xml+rss
application/json
image/svg+xml;
# Brotli compression (if available)
# 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;
# Security headers
add_header X-Frame-Options "DENY" 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 Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
# Cache settings for static assets
map $sent_http_content_type $expires {
default off;
text/html epoch;
text/css max;
application/javascript max;
~image/ 1y;
~font/ 1y;
application/pdf 1M;
}
expires $expires;
# Rate limiting
limit_req_zone $binary_remote_addr zone=website:10m rate=10r/s;
# Upstream for Next.js server
upstream nextjs {
server 127.0.0.1:3000;
keepalive 32;
}
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
index index.html;
# Security: Hide .files
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
# Rate limiting
limit_req zone=website burst=20 nodelay;
# Health check endpoint
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
# Static assets from Next.js build
location /_next/static/ {
alias /usr/share/nginx/html/_next/static/;
expires 1y;
add_header Cache-Control "public, immutable";
# Brotli/Gzip pre-compressed files
location ~* \.(js|css)$ {
gzip_static on;
expires 1y;
add_header Cache-Control "public, immutable";
}
}
# Public assets
location /images/ {
alias /usr/share/nginx/html/images/;
expires 1M;
add_header Cache-Control "public";
}
location /icons/ {
alias /usr/share/nginx/html/icons/;
expires 1M;
add_header Cache-Control "public";
}
# Favicon and manifest files
location ~* ^/(favicon\.ico|manifest\.json|robots\.txt|sitemap\.xml)$ {
expires 1w;
add_header Cache-Control "public";
}
# Next.js API routes and pages
location / {
try_files $uri $uri/ @nextjs;
}
# Proxy to Next.js server
location @nextjs {
proxy_pass http://nextjs;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
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_cache_bypass $http_upgrade;
# Timeouts
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# Buffer settings
proxy_buffering on;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
}
# Error pages
error_page 404 /404.html;
error_page 500 502 503 504 /500.html;
location = /404.html {
root /usr/share/nginx/html;
internal;
}
location = /500.html {
root /usr/share/nginx/html;
internal;
}
}
}