worker_processes 4; events { worker_connections 1024; } http { include /etc/nginx/mime.types; client_max_body_size 2m; # don't send the nginx version number in error pages and Server header server_tokens off; sendfile on; upstream website { server website:4000; } upstream main { server main:80; } upstream api { server api:3000; } upstream api-device { server api-device:3000; } upstream api-rabbit { server api-rabbit:3000; } upstream designer { server designer:80; } upstream runner { server runner:80; } upstream static { server static:80; } upstream websocket-worker { server websocket-worker:3030; } # Restore the real client IP from the upstream reverse proxy # Trust all RFC 1918 private ranges (covers any Docker network config) set_real_ip_from 10.0.0.0/8; set_real_ip_from 172.16.0.0/12; set_real_ip_from 192.168.0.0/16; real_ip_header X-Real-IP; limit_req_zone $binary_remote_addr zone=auth:10m rate=1r/s; limit_req_zone $binary_remote_addr zone=website:10m rate=5r/s; limit_req_zone $binary_remote_addr zone=global:10m rate=10r/s; # redirect all http traffic to https server { listen 80 default_server; {% if (onelab.services.revproxy.ipv6|default(true)) != false %} listen [::]:80 default_server; {% endif %} server_name localhost; gzip on; gzip_vary on; gzip_min_length 10240; gzip_proxied expired no-cache no-store private auth; gzip_types text/plain text/css application/json application/x-javascript application/javascript text/xml application/xml application/xml+rss text/javascript; gzip_disable "MSIE [1-6]\."; root /data/; location ^~ /lab/ { rewrite ^/lab/(.*?) /app/lab/$1 last; } location ^~ /assets/ { location ~* \.(?:css|js|woff|woff2|jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ { expires 1M; access_log off; add_header Cache-Control "public"; try_files $uri $uri/ /error-404.html =404; } expires -1; add_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0'; try_files $uri $uri/ /error-404.html =404; } location ^~ /static/ { location ~* \.(?:css|js|woff|woff2|jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ { expires 1M; access_log off; add_header Cache-Control "public"; proxy_pass http://static; proxy_redirect off; 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-Host $server_name; } expires -1; add_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0'; proxy_pass http://static; proxy_redirect off; 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-Host $server_name; } location ^~ /sitemap.xml { limit_req zone=global burst=10 nodelay; proxy_pass http://api; proxy_redirect off; 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-Host $server_name; } location ^~ /robots.txt { limit_req zone=global burst=10 nodelay; proxy_pass http://api; proxy_redirect off; 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-Host $server_name; } location ^~ /api/ { limit_req zone=global burst=10 nodelay; proxy_pass http://api; proxy_redirect off; proxy_set_header Cookie $http_cookie; 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-Host $server_name; } location ^~ /api/v1/auth/ { # apply rate limiting limit_req zone=auth burst=5 nodelay; proxy_pass http://api; proxy_redirect off; proxy_set_header Cookie $http_cookie; 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-Host $server_name; } location ^~ /api/v1/firmwares { limit_req zone=global burst=10 nodelay; client_max_body_size 600M; proxy_pass http://api; proxy_redirect off; proxy_set_header Cookie $http_cookie; 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-Host $server_name; } location ^~ /api/v1/rmq/ { proxy_pass http://api-rabbit; proxy_redirect off; proxy_set_header Cookie $http_cookie; 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-Host $server_name; } location ^~ /device-api/ { limit_req zone=global burst=10 nodelay; client_max_body_size 600m; proxy_pass http://api-device; proxy_redirect off; proxy_set_header Cookie $http_cookie; 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-Host $server_name; } location ^~ /app/designer/ { location ~* \.(?:css|js|woff|woff2|jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ { expires 1M; access_log off; add_header Cache-Control "public"; proxy_pass http://designer; proxy_redirect off; proxy_set_header Cookie $http_cookie; 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-Host $server_name; } expires -1; add_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0'; proxy_pass http://designer; proxy_redirect off; proxy_set_header Cookie $http_cookie; 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-Host $server_name; } location ^~ /app/runner/ { location ~* \.(?:css|js|woff|woff2|jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ { expires 1M; access_log off; add_header Cache-Control "public"; proxy_pass http://runner; proxy_redirect off; proxy_set_header Cookie $http_cookie; 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-Host $server_name; } expires -1; add_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0'; proxy_pass http://runner; proxy_redirect off; proxy_set_header Cookie $http_cookie; 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-Host $server_name; } location ^~ /ws/ { proxy_pass http://websocket-worker; proxy_redirect off; proxy_set_header Cookie $http_cookie; 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-Host $server_name; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } location ^~ /app/ { location ~* \.(?:css|js|woff|woff2|jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ { expires 1M; access_log off; add_header Cache-Control "public"; proxy_pass http://main; proxy_redirect off; proxy_set_header Cookie $http_cookie; 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-Host $server_name; } expires -1; add_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0'; proxy_pass http://main; proxy_redirect off; proxy_set_header Cookie $http_cookie; 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-Host $server_name; } # Static assets for website (including /media/ subdirectory) location ~* ^/.+\.(?:css|js|woff|woff2|ttf|eot|jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ { expires 1M; access_log off; add_header Cache-Control "public"; proxy_pass http://website; proxy_redirect off; proxy_set_header Cookie $http_cookie; 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-Host $server_name; } # Website SSR routes (rate limited) location ~ ^/(library(/[^/]+)?|login(/(reset|change))?|signup)?$ { limit_req zone=website burst=10 nodelay; expires -1; add_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0'; proxy_pass http://website; proxy_redirect off; proxy_set_header Cookie $http_cookie; 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-Host $server_name; } # Catch-all for junk requests location / { try_files $uri $uri/ /error-404.html =404; } } }