server { listen 80 default_server; listen [::]:80 default_server; server_name _; # Logging access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; # ========================================= # Frontend Static Assets (served directly by nginx) - MUST BE FIRST # ========================================= # Use ^~ to prevent regex locations from matching location ^~ /assets/ { alias /var/www/frontend/build/client/assets/; expires 1y; add_header Cache-Control "public, immutable"; access_log off; } # ========================================= # Backend API Routes (Laravel) # ========================================= root /var/www/backend/public; index index.php index.html; location ~ ^/(api|sanctum)/ { try_files $uri $uri/ /index.php?$query_string; location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; # Laravel-specific settings fastcgi_param HTTP_PROXY ""; fastcgi_read_timeout 300; fastcgi_buffer_size 128k; fastcgi_buffers 256 16k; fastcgi_busy_buffers_size 256k; fastcgi_temp_file_write_size 256k; } } # Handle API routes that don't map to files location ~ ^/(api|sanctum) { try_files $uri /index.php?$query_string; } # PHP file handler for backend location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } # ========================================= # Frontend Routes (React Router via Node.js) # ========================================= location / { proxy_pass http://127.0.0.1:3000; proxy_http_version 1.1; # Standard proxy headers 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; # WebSocket support (for React Router HMR if needed) proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; # Timeouts proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; } # ========================================= # Security & Performance # ========================================= # Deny access to hidden files location ~ /\. { deny all; access_log off; log_not_found off; } # Disable logging for favicon and robots.txt location = /favicon.ico { access_log off; log_not_found off; } location = /robots.txt { access_log off; log_not_found off; } # Cache static assets location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ { expires 30d; add_header Cache-Control "public, immutable"; } }