@@ -56,7 +56,108 @@ GIT_TEMPLATE_DIR=''
5656The second step is to create an Nginx configuration in the folder ` nginx/templates/default.conf.template ` following this template:
5757
5858``` nginx
59+ # IP limit: 10 requests/second with a 10 MB shared memory zone
60+ limit_req_zone $binary_remote_addr zone=api_ratelimit:10m rate=10r/s;
5961
62+ # Limit simultaneous connections per IP (not essential)
63+ limit_conn_zone $binary_remote_addr zone=perip:10m;
64+
65+ server {
66+ listen 80;
67+ listen [::]:80;
68+
69+ root /usr/share/nginx/html;
70+ index index.html;
71+
72+ # Security headers
73+ add_header X-Frame-Options "SAMEORIGIN" always;
74+ add_header X-Content-Type-Options "nosniff" always;
75+ add_header X-XSS-Protection "1; mode=block" always;
76+ add_header Referrer-Policy "strict-origin-when-cross-origin" always;
77+
78+ # Gzip compression
79+ gzip on;
80+ gzip_types
81+ text/plain
82+ text/css
83+ text/js
84+ text/xml
85+ text/javascript
86+ application/javascript
87+ application/json
88+ application/xml+rss;
89+ gzip_min_length 1000;
90+
91+ # Cache static assets
92+ location /_next/static/ {
93+ expires 1y;
94+ add_header Cache-Control "public, immutable";
95+ }
96+
97+ location /images/ {
98+ expires 1y;
99+ add_header Cache-Control "public, immutable";
100+ }
101+
102+ location /assets/ {
103+ expires 1y;
104+ add_header Cache-Control "public, immutable";
105+ }
106+
107+ # Return 429 instead of 503 when the limit is exceeded
108+ limit_req_status 429;
109+
110+ # Favicon for API routes
111+ location /api/favicon.ico {
112+ alias /usr/share/nginx/html/images/securechain-logo.ico;
113+ expires 1y;
114+ add_header Cache-Control "public, immutable";
115+ access_log off;
116+ }
117+
118+ # API routes - proxy to backend
119+ location /api/ {
120+ proxy_pass $BACKEND_URL/;
121+ proxy_http_version 1.1;
122+
123+ proxy_set_header Host $host;
124+ proxy_set_header X-Real-IP $remote_addr;
125+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
126+ proxy_set_header X-Forwarded-Proto $scheme;
127+
128+ proxy_set_header Upgrade $http_upgrade;
129+ proxy_set_header Connection "upgrade";
130+
131+ proxy_cookie_domain off;
132+ proxy_cookie_path off;
133+
134+ proxy_pass_header Set-Cookie;
135+
136+ # Allows small bursts (burst 20) without rejection (no nodelay = delayed)
137+ limit_req zone=api_ratelimit burst=20;
138+ }
139+
140+ # SPA fallback
141+ location / {
142+ try_files $uri $uri/ $uri.html /index.html;
143+ }
144+
145+ # Health check
146+ location /health {
147+ access_log off;
148+ return 200 "healthy\n";
149+ add_header Content-Type text/plain;
150+ }
151+
152+ # Deny access to hidden files
153+ location ~ /\. {
154+ deny all;
155+ }
156+
157+ # Error pages
158+ error_page 404 /404.html;
159+ error_page 500 502 503 504 /500.html;
160+ }
60161```
61162
62163## Docker Deployment
0 commit comments