HR-ATS-Portal/frontend/nginx.conf

61 lines
2.5 KiB
Nginx Configuration File

server {
listen 80;
server_name _;
root /usr/share/nginx/html;
index index.html;
# CV / multipart uploads (MAX_PDF_SIZE_MB is 10; leave headroom for form fields).
client_max_body_size 25m;
# Security headers on every response.
add_header X-Content-Type-Options nosniff always;
add_header X-Frame-Options DENY always;
add_header Referrer-Policy strict-origin-when-cross-origin always;
# Same-origin API proxy. The SPA is built with an empty VITE_API_BASE so
# fetch('/jobs/fetch') stays on this host; without this block nginx would
# serve index.html for those paths (200 HTML) and the Jobs board would
# parse an empty payload. OpenAPI (/docs, /redoc, /openapi.json) is
# intentionally NOT proxied — keep the schema off the public edge.
location ~ ^/(health|users|roles|permissions|permission-tags|managers|inbox|email|job|jobs|candidate|notes|interview|feedback|activity|pipeline|notifications|analytics|offers|tasks|assessments|org-settings|saved-searches|search)(/|$) {
proxy_pass http://backend-api:8000;
proxy_http_version 1.1;
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_set_header Authorization $http_authorization;
proxy_connect_timeout 10s;
proxy_send_timeout 120s;
proxy_read_timeout 120s;
}
# One SPA at `/`. Without this, /auth/confirm-email (a router path, not a
# file) 404s when a confirmation email link is opened cold.
location / {
try_files $uri $uri/ /index.html;
}
# Hashed filenames, so they can be cached hard.
location /assets/ {
expires 1y;
add_header Cache-Control "public, immutable";
add_header X-Content-Type-Options nosniff always;
add_header X-Frame-Options DENY always;
add_header Referrer-Policy strict-origin-when-cross-origin always;
}
# index.html must never be cached, or a redeploy keeps serving the old asset hashes.
location = /index.html {
add_header Cache-Control "no-store";
add_header X-Content-Type-Options nosniff always;
add_header X-Frame-Options DENY always;
add_header Referrer-Policy strict-origin-when-cross-origin always;
}
gzip on;
gzip_min_length 1024;
gzip_types text/css text/javascript application/javascript application/json image/svg+xml;
}