Nginx configuration file · 4912 bytes Raw Blame History
1 user nginx;
2 worker_processes auto;
3 error_log /var/log/nginx/error.log warn;
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
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 settings
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 server_tokens off;
33
34 # Gzip compression
35 gzip on;
36 gzip_vary on;
37 gzip_min_length 1024;
38 gzip_proxied any;
39 gzip_comp_level 6;
40 gzip_types
41 text/plain
42 text/css
43 text/xml
44 text/javascript
45 application/json
46 application/javascript
47 application/xml+rss
48 application/atom+xml
49 image/svg+xml;
50
51 # Rate limiting
52 limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
53 limit_req_zone $binary_remote_addr zone=auth:10m rate=5r/s;
54
55 # Upstream backend
56 upstream web-backend {
57 server web-client:8080;
58 keepalive 32;
59 }
60
61 # HTTP to HTTPS redirect
62 server {
63 listen 80;
64 listen [::]:80;
65 server_name _;
66
67 # Health check endpoint (allow HTTP)
68 location /health {
69 return 200 "healthy\n";
70 add_header Content-Type text/plain;
71 access_log off;
72 }
73
74 # Redirect all other traffic to HTTPS
75 location / {
76 return 301 https://$host$request_uri;
77 }
78 }
79
80 # HTTPS server
81 server {
82 listen 443 ssl http2;
83 listen [::]:443 ssl http2;
84 server_name _;
85
86 # SSL configuration
87 ssl_certificate /etc/nginx/ssl/cert.pem;
88 ssl_certificate_key /etc/nginx/ssl/key.pem;
89 ssl_session_timeout 1d;
90 ssl_session_cache shared:SSL:50m;
91 ssl_session_tickets off;
92
93 # Modern SSL configuration
94 ssl_protocols TLSv1.2 TLSv1.3;
95 ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
96 ssl_prefer_server_ciphers off;
97
98 # HSTS (optional, uncomment if using a real domain)
99 # add_header Strict-Transport-Security "max-age=63072000" always;
100
101 # Security headers
102 add_header X-Frame-Options DENY always;
103 add_header X-Content-Type-Options nosniff always;
104 add_header X-XSS-Protection "1; mode=block" always;
105 add_header Referrer-Policy "strict-origin-when-cross-origin" always;
106 add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; font-src 'self'; connect-src 'self' ws: wss:; media-src 'self' blob:;" always;
107
108 # Main application
109 location / {
110 proxy_pass http://web-backend;
111 proxy_http_version 1.1;
112 proxy_set_header Upgrade $http_upgrade;
113 proxy_set_header Connection 'upgrade';
114 proxy_set_header Host $host;
115 proxy_set_header X-Real-IP $remote_addr;
116 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
117 proxy_set_header X-Forwarded-Proto $scheme;
118 proxy_cache_bypass $http_upgrade;
119 proxy_read_timeout 300;
120 proxy_connect_timeout 300;
121 proxy_send_timeout 300;
122
123 # Rate limiting
124 limit_req zone=api burst=20 nodelay;
125 }
126
127 # Authentication endpoints with stricter rate limiting
128 location ~ ^/api/auth/ {
129 proxy_pass http://web-backend;
130 proxy_http_version 1.1;
131 proxy_set_header Host $host;
132 proxy_set_header X-Real-IP $remote_addr;
133 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
134 proxy_set_header X-Forwarded-Proto $scheme;
135
136 # Stricter rate limiting for auth
137 limit_req zone=auth burst=10 nodelay;
138 }
139
140 # Health check
141 location /health {
142 access_log off;
143 return 200 "healthy\n";
144 add_header Content-Type text/plain;
145 }
146
147 # Security: Block access to sensitive files
148 location ~ /\. {
149 deny all;
150 access_log off;
151 log_not_found off;
152 }
153
154 location ~ ^/(package\.json|Dockerfile|docker-compose\.yml)$ {
155 deny all;
156 access_log off;
157 log_not_found off;
158 }
159 }
160 }