Nginx configuration
The core routing logic that makes PutFS work. Nginx decides what to handle itself (reads) and what to proxy to the API (writes, listings).
Routing
Two location blocks are needed to handle PutFS:
# Trailing slash → listing via API
location ~ /$ {
proxy_pass http://api$uri$is_args$args;
}
# Everything else
location / {
# PUT, DELETE → proxy to API
limit_except GET HEAD {
proxy_pass http://api;
}
# GET, HEAD → serve directly from disk
root /data;
try_files $uri =404;
}
How it works:
location ~ /$catches paths ending in/(e.g./my-dataset/) and proxies them to the API, which streams back the key listing.location /catches everything else.limit_except GET HEADmeans: for any method other than GET/HEAD, proxy to the API. GET and HEAD fall through totry_files, which serves the file directly from disk viasendfile– Python is never involved in the read path.
Minimal working config
worker_processes auto;
events {}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
access_log off;
upstream api {
server unix:/run/putfs/putfs.sock;
}
server {
listen 80;
location ~ /$ {
proxy_pass http://api$uri$is_args$args;
}
location / {
limit_except GET HEAD {
proxy_pass http://api;
}
root /data;
try_files $uri =404;
}
}
}
This is unauthenticated. For production, add auth and upload handling – see below.
What to add
| Concern | Where |
|---|---|
| Authentication | Auth – map-based key+secret with path/method scoping, or auth_request |
| Upload size limits | client_max_body_size 0; in the server block (default is 1MB) |
| Upload streaming | proxy_request_buffering off; – avoids double disk I/O |
| Rate limiting | limit_req_zone – see Nginx tuning |
| Timeouts | client_body_timeout 300s; proxy_read_timeout 300s; for large files |
| Performance | Nginx tuning – keepalive, gzip, high-concurrency settings |