I’m trying to understand the rationale behind Frappe’s default Nginx setup, and I’m just curious if there’s a reason it’s done this way.
From what I understand, Frappe typically serves public files under the /files prefix. In the standard config, though, Nginx is set up to try serving any URI directly from the site’s public folder first, and only falls back to the backend if the file isn’t found:
location / {
try_files /$host/public/$uri @webserver;
}
So for something like https://erpnext-yes.com/files/star.png, Nginx would try /$host/public/files/star.png first, and only forward to the backend if it doesn’t exist.
Would it be cleaner (or is there a downside) to making the intent more explicit - i.e., only handling /files/* as static public files, and proxying everything else straight to the Frappe backend?
Something like:
location ~ ^/files/(.*) {
try_files /$host/public/files/$1 =404;
}
location / {
proxy_pass http://backend-server;
...
}
In other words:
- If the URI starts with
/files/, serve it frompublic/files(and return 404 if missing) - Otherwise, forward to the backend
Would a structure like this be acceptable in practice, and does it improve readability/maintainability? Or does the default try_files /$host/public/$uri approach provide some benefit that I’m missing?
For example, would something like the below be considered “cleaner,” or is there a reason Frappe avoids it?
server {
listen 80;
server_name super-erpnext.com;
root /home/frappe/frappe-bench/sites;
# Serve asset
location /assets {
try_files $uri =404;
}
# Serve private files (via X-Accel-Redirect only)
location ~ ^/protected/(.*) {
internal;
try_files /$host/$1 =404;
}
# Serve public files
location ~ ^/files/(.*) {
try_files /$host/public/files/$1 =404;
}
# Proxy to socket.io
location /socket.io {
...
proxy_pass http://socketio-server;
}
# Proxy to backend-server
location / {
...
proxy_pass http://backend-server;
}
}
Reference:
- bench/bench/config/templates/nginx.conf at f0a08c383900f83c58332f7b53abbe0255e3269a · frappe/bench · GitHub
- bench/bench/config/templates/bench_manager_nginx.conf at f0a08c383900f83c58332f7b53abbe0255e3269a · frappe/bench · GitHub
- frappe_docker/resources/core/nginx/nginx-template.conf at d56cd8851eb51129881ada6017f91c1e36064c1c · frappe/frappe_docker · GitHub
Updates:
- I did tryout with this nginx config and things works as it should.