2025-08-02 03:22:09 +02:00
|
|
|
server {
|
|
|
|
|
listen 80;
|
|
|
|
|
server_name localhost;
|
2025-08-12 12:17:27 +02:00
|
|
|
|
|
|
|
|
# Serve static React build files
|
|
|
|
|
root /var/www/html/frontend/dist;
|
|
|
|
|
index index.html;
|
2025-08-02 03:22:09 +02:00
|
|
|
|
2025-08-12 12:17:27 +02:00
|
|
|
# API requests to Laravel backend
|
|
|
|
|
location /api/ {
|
|
|
|
|
root /var/www/html/backend/public;
|
|
|
|
|
try_files /index.php =404;
|
|
|
|
|
|
2025-08-02 03:22:09 +02:00
|
|
|
fastcgi_pass 127.0.0.1:9000;
|
|
|
|
|
fastcgi_index index.php;
|
2025-08-12 12:17:27 +02:00
|
|
|
fastcgi_param SCRIPT_FILENAME /var/www/html/backend/public/index.php;
|
2025-08-02 03:22:09 +02:00
|
|
|
include fastcgi_params;
|
|
|
|
|
|
|
|
|
|
# Increase timeouts for long-running requests
|
|
|
|
|
fastcgi_read_timeout 300;
|
|
|
|
|
fastcgi_send_timeout 300;
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-12 12:17:27 +02:00
|
|
|
# Serve Laravel public assets (images, etc.)
|
|
|
|
|
location /images/ {
|
|
|
|
|
alias /var/www/html/backend/public/images/;
|
|
|
|
|
expires 1y;
|
|
|
|
|
add_header Cache-Control "public, immutable";
|
2025-08-02 03:22:09 +02:00
|
|
|
}
|
|
|
|
|
|
2025-08-12 12:17:27 +02:00
|
|
|
# React app - catch all routes
|
|
|
|
|
location / {
|
|
|
|
|
try_files $uri $uri/ /index.html;
|
2025-08-02 03:22:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Static assets with far-future expiry
|
|
|
|
|
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot|map)$ {
|
|
|
|
|
expires 1y;
|
|
|
|
|
add_header Cache-Control "public, immutable";
|
|
|
|
|
access_log off;
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-12 12:17:27 +02:00
|
|
|
# Security headers
|
|
|
|
|
add_header X-Frame-Options "SAMEORIGIN";
|
|
|
|
|
add_header X-Content-Type-Options "nosniff";
|
|
|
|
|
add_header X-XSS-Protection "1; mode=block";
|
|
|
|
|
|
|
|
|
|
# Deny access to hidden files
|
|
|
|
|
location ~ /\.ht {
|
|
|
|
|
deny all;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Deny access to sensitive files
|
|
|
|
|
location ~ /\.(env|git) {
|
|
|
|
|
deny all;
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-02 03:22:09 +02:00
|
|
|
location = /favicon.ico {
|
|
|
|
|
access_log off;
|
|
|
|
|
log_not_found off;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
location = /robots.txt {
|
|
|
|
|
access_log off;
|
|
|
|
|
log_not_found off;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Gzip compression
|
|
|
|
|
gzip on;
|
|
|
|
|
gzip_vary on;
|
|
|
|
|
gzip_min_length 1024;
|
|
|
|
|
gzip_proxied any;
|
|
|
|
|
gzip_comp_level 6;
|
|
|
|
|
gzip_types
|
|
|
|
|
text/plain
|
|
|
|
|
text/css
|
|
|
|
|
text/xml
|
|
|
|
|
text/javascript
|
|
|
|
|
application/javascript
|
|
|
|
|
application/xml+rss
|
|
|
|
|
application/json;
|
|
|
|
|
}
|