Skip to content

Instantly share code, notes, and snippets.

@hopeseekr
Created March 29, 2025 15:49
Show Gist options
  • Select an option

  • Save hopeseekr/292f345b01d598a1fd0dfcf70e8f5fcc to your computer and use it in GitHub Desktop.

Select an option

Save hopeseekr/292f345b01d598a1fd0dfcf70e8f5fcc to your computer and use it in GitHub Desktop.
Optimized Calibre-web Nginx reverse proxy
# Prequiste: For security, set Calibre to listen to 127.0.0.4:8383:
# Admin -> Basic Configuration -> Server Settings: Server port 8383.
# Then edit `/etc/systemd/system/multi-user.target.wants/calibre-web.service`:
# Change to `ExecStart=/usr/lib/calibre-web/cps.py -i 127.0.0.4`.
# sudo systemctl daemon-reload
# sudo systemctl restart calibre-web
server {
listen [::]:443 ssl;
listen 443 ssl;
server_name read.your.site;
# SSL Configuration
ssl_certificate /etc/letsencrypt/live/read.your.site/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/read.your.site/privkey.pem; # managed by Certbot
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384;
# Logging
access_log /var/log/nginx/read.your.site.log;
error_log /var/log/nginx/read.your.site.error.log;
# Common proxy settings
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;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_connect_timeout 300s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
location / {
proxy_pass http://127.0.0.4:8383;
}
# Special configuration for upload endpoint
location ~ /(upload|book/add|upload-new) {
# Increased body size limit specifically for book uploads
client_max_body_size 200m;
# SECURITY NOTE: Limiting large uploads to only the necessary routes
# helps prevent resource exhaustion DoS attacks. This mitigates the risk
# of attackers consuming server memory, network bandwidth, and disk space
# by uploading large files to arbitrary endpoints. When large uploads are
# only permitted on specific, monitored routes, the attack surface for
# resource-based DoS attacks is significantly reduced.
proxy_pass http://127.0.0.1:8383;
}
}
@hopeseekr
Copy link
Author

@mwilck
Copy link

mwilck commented Feb 10, 2026

This example would be even more helpful if it contained directives for location rewriting. For example, I am using the location /books/ in the proxy for calibre-web. Not being a web administation expert, it took me several hours to figure out how to make this work.

It looks like this:

location /books/ {
		proxy_pass http://127.0.0.1:8083;
		proxy_set_header Host $http_host;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Scheme $scheme;
		proxy_set_header X-Script-Name /books;
		proxy_set_header X-Forwarded-Host $host;

		# Websockets settings
		proxy_http_version 1.1;
		proxy_set_header Upgrade $http_upgrade;

# The following line requires a "map" block outside the server block
#
# map $http_upgrade $connection_upgrade {
#    default upgrade;
#    ''      close;
# }
#
# A simple "Connection upgrade" may causes the login page (POST) to time out!

 		proxy_set_header Connection $connection_upgrade;
}

X-Script-Name is key here. I'd experimented with proxy_redirect and X-Forwarded-Prefix before, without success, and was about to give up, when I eventually found janeczku/calibre-web#19 which contained the hint to use X-Script-name.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment