Setting up Paperless-NGX with dual reverse proxy configuration

Hi everyone!

I’m trying to set up a secure connection setup for my home network and running into some issues. I have Paperless-NGX running and want everything to use HTTPS.

My current setup:

  • Caddy proxy in Docker handles local SSL: docs.local:8443 forwards to localhost:3000 (paperless instance)
  • Nginx Proxy Manager on my server creates external access: documents.mydomain.com should forward to docs.local:8443

The main page loads fine, but CSS files and other static resources don’t load properly.

Here’s my current NPM configuration:

location / {
    proxy_pass https://docs.local:8443;
    proxy_ssl_verify off;
    proxy_ssl_server_name on;
    proxy_set_header Host $server;
    proxy_set_header X-Real-IP 10.0.1.150;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $forward_scheme;
}

Reverse proxy settings: documents.mydomain.com → https → target: docs.local → port: 8443

I’ve tried different combinations in my Docker environment variables with all three URLs (localhost, docs.local, documents.mydomain.com) for the PAPERLESS_URL setting.

Is there a way to make this work or should I configure SSL directly in Paperless instead of using Caddy?

Any help would be great!

had the same headaches with paperless and double proxies. try adding proxy_set_header X-Forwarded-Host $host; to your npm config - paperless needs the original hostname for asset URLs. also check if Caddy’s rewriting URLs and breaking paths. worst case, ditch Caddy and handle SSL termination directly in npm. way less complexity.

That hardcoded X-Real-IP header is probably messing with how Paperless sees the request origin. Just remove it and let NPM handle real IP detection on its own. Also check if Caddy’s adding any conflicting headers that might break static asset serving. I’ve dealt with this before - having both proxies modify headers creates conflicts. Try setting PAPERLESS_STATIC_URL to your external domain so Paperless knows where to serve static files from. If you’re still stuck, temporarily bypass Caddy and point NPM straight to the Paperless container on port 8000. That’ll tell you if it’s the double proxy setup or something else.

I’ve hit this exact problem with static resources in double proxy setups. Your CSS files are probably loading with wrong URLs or protocols. Pop open your browser’s dev tools and check what URLs the CSS is actually trying to hit - bet they’re still pointing to HTTP or the wrong domain. For Paperless-NGX, set PAPERLESS_URL to your final external URL (documents.mydomain.com) and throw in PAPERLESS_FORCE_SCRIPT_NAME=“/” if you haven’t. Also, change that proxy_set_header Host to $host instead of $server so it passes the original domain through properly. Double proxy works but it’s way more finicky than just doing SSL termination at one spot.