Repository navigation
Expand file tree
/
Copy pathnginx.conf.example
More file actions
159 lines (131 loc) · 8.42 KB
/
Copy pathnginx.conf.example
File metadata and controls
159 lines (131 loc) · 8.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# ══════════════════════════════════════════════════════════════════════════════
# AVA CMS - NGINX CONFIGURATION EXAMPLE
# ══════════════════════════════════════════════════════════════════════════════
#
# Copy this to your nginx sites-available and customize paths.
# Replace "yoursite.com" and "/var/www/yoursite" with your values.
#
# Test config: sudo nginx -t
# Reload: sudo systemctl reload nginx
#
# Docs: https://ava.addy.zone/docs/hosting
# ══════════════════════════════════════════════════════════════════════════════
server {
listen 80;
listen [::]:80;
server_name yoursite.com www.yoursite.com;
# Redirect HTTP to HTTPS (recommended for production)
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name yoursite.com www.yoursite.com;
# ──────────────────────────────────────────────────────────────────────────
# IMPORTANT: Document root MUST be the /public folder
# ──────────────────────────────────────────────────────────────────────────
root /var/www/yoursite/public;
index index.php;
# SSL certificates (use certbot for Let's Encrypt)
ssl_certificate /etc/letsencrypt/live/yoursite.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yoursite.com/privkey.pem;
# Modern SSL configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
# ──────────────────────────────────────────────────────────────────────────
# SECURITY: Block access to sensitive files (defense-in-depth)
# ──────────────────────────────────────────────────────────────────────────
# These should not be accessible if root is set correctly, but this
# protects against misconfiguration.
# Block sensitive files in case of misconfiguration
location ~ ^/(ava|bootstrap\.php|composer\.(json|lock))$ {
deny all;
return 404;
}
# Block sensitive directories in case of misconfiguration
location ~ ^/(app|core|storage|vendor|content)/ {
deny all;
return 404;
}
# Block dotfiles (.git, .env, .htaccess, etc.)
location ~ /\. {
deny all;
return 404;
}
# ──────────────────────────────────────────────────────────────────────────
# PERFORMANCE: Static file caching
# ──────────────────────────────────────────────────────────────────────────
# Theme assets (/theme/...) live in app/themes/<theme>/assets, outside the
# web root, and are served by Ava. The ^~ prefix stops the static-file
# regex below from claiming them and returning 404.
location ^~ /theme/ {
try_files $uri /index.php?$query_string;
}
# Cache static assets (images, fonts, etc.)
location ~* \.(ico|gif|jpe?g|png|webp|avif|svg|woff2?|ttf|eot|otf|css|js)$ {
expires 1y;
access_log off;
try_files $uri =404;
# A location with its own add_header inherits none from the server
# block, so the security headers must be repeated here.
add_header Cache-Control "public, immutable";
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
}
# ──────────────────────────────────────────────────────────────────────────
# PHP HANDLING
# ──────────────────────────────────────────────────────────────────────────
# Main location block - route all requests through index.php
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# PHP-FPM handling
location ~ \.php$ {
# Only allow index.php to be executed
# This prevents execution of uploaded PHP files
location ~ ^/index\.php$ {
fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
# Timeouts
fastcgi_connect_timeout 60s;
fastcgi_send_timeout 60s;
fastcgi_read_timeout 60s;
# Buffers
fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
}
# Return 404 for any other .php file
return 404;
}
# ──────────────────────────────────────────────────────────────────────────
# SECURITY HEADERS
# ──────────────────────────────────────────────────────────────────────────
# Ava sets these itself on PHP responses. Here they cover files nginx serves
# directly from locations without their own add_header (see above).
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# Uncomment for stricter CSP (customize as needed)
# add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline';" always;
# ──────────────────────────────────────────────────────────────────────────
# LOGGING
# ──────────────────────────────────────────────────────────────────────────
access_log /var/log/nginx/yoursite.access.log;
error_log /var/log/nginx/yoursite.error.log warn;
# ──────────────────────────────────────────────────────────────────────────
# LIMITS
# ──────────────────────────────────────────────────────────────────────────
client_max_body_size 20M; # Max upload size
# Gzip compression
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml;
}