Nginx configuration file · 3852 bytes Raw Blame History
1 user nginx;
2 worker_processes auto;
3 error_log /var/log/nginx/error.log notice;
4 pid /var/run/nginx.pid;
5
6 events {
7 worker_connections 1024;
8 use epoll;
9 multi_accept on;
10 }
11
12 http {
13 include /etc/nginx/mime.types;
14 default_type application/octet-stream;
15
16 # Logging format
17 log_format main '$remote_addr - $remote_user [$time_local] "$request" '
18 '$status $body_bytes_sent "$http_referer" '
19 '"$http_user_agent" "$http_x_forwarded_for" '
20 'rt=$request_time uct="$upstream_connect_time" '
21 'uht="$upstream_header_time" urt="$upstream_response_time"';
22
23 access_log /var/log/nginx/access.log main;
24
25 # Performance optimizations
26 sendfile on;
27 tcp_nopush on;
28 tcp_nodelay on;
29 keepalive_timeout 65;
30 types_hash_max_size 2048;
31 client_max_body_size 1G;
32
33 # Gzip compression
34 gzip on;
35 gzip_vary on;
36 gzip_min_length 1024;
37 gzip_proxied any;
38 gzip_comp_level 6;
39 gzip_types
40 text/plain
41 text/css
42 text/xml
43 text/javascript
44 application/json
45 application/javascript
46 application/xml+rss
47 application/atom+xml
48 image/svg+xml;
49
50 # Security headers
51 add_header X-Frame-Options DENY always;
52 add_header X-Content-Type-Options nosniff always;
53 add_header X-XSS-Protection "1; mode=block" always;
54 add_header Referrer-Policy "strict-origin-when-cross-origin" always;
55
56 server {
57 listen 8080;
58 listen [::]:8080;
59 server_name _;
60 root /usr/share/nginx/html;
61 index index.html;
62
63 # Security
64 server_tokens off;
65
66 # Static assets with long cache
67 location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
68 expires 1y;
69 add_header Cache-Control "public, immutable";
70 add_header X-Content-Type-Options nosniff;
71 }
72
73 # API proxy to backend
74 location /api/ {
75 proxy_pass http://web-server:3000;
76 proxy_http_version 1.1;
77 proxy_set_header Upgrade $http_upgrade;
78 proxy_set_header Connection 'upgrade';
79 proxy_set_header Host $host;
80 proxy_set_header X-Real-IP $remote_addr;
81 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
82 proxy_set_header X-Forwarded-Proto $scheme;
83 proxy_cache_bypass $http_upgrade;
84 proxy_read_timeout 300;
85 proxy_connect_timeout 300;
86 proxy_send_timeout 300;
87 }
88
89 # WebSocket support for API
90 location /api/status/ws {
91 proxy_pass http://web-server:3000;
92 proxy_http_version 1.1;
93 proxy_set_header Upgrade $http_upgrade;
94 proxy_set_header Connection "Upgrade";
95 proxy_set_header Host $host;
96 proxy_set_header X-Real-IP $remote_addr;
97 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
98 proxy_set_header X-Forwarded-Proto $scheme;
99 }
100
101 # SPA fallback - serve index.html for all routes
102 location / {
103 try_files $uri $uri/ /index.html;
104 add_header Cache-Control "no-cache, no-store, must-revalidate";
105 add_header Pragma "no-cache";
106 add_header Expires "0";
107 }
108
109 # Health check endpoint
110 location /health {
111 access_log off;
112 return 200 "healthy\n";
113 add_header Content-Type text/plain;
114 }
115
116 # Block access to sensitive files
117 location ~ /\. {
118 deny all;
119 access_log off;
120 log_not_found off;
121 }
122
123 location ~ ^/(package\.json|Dockerfile|docker-compose\.yml)$ {
124 deny all;
125 access_log off;
126 log_not_found off;
127 }
128 }
129 }