SteGriff

Blog

Next & Previous

Make Express Sessions work on Docker with a Proxy

I’ve had a bad time trying to get certain software working on any Docker-based host like Fly, DigitalOcean, or Disco… for a year or more. It just switched me off from porting my Node.js projects and I gave up for a while. These things just worked on Glitch thanks to Glitch container magic.

The breakthrough turned out to be setting the ‘trust proxy’ setting in Express to 1. Does that mean “yes”, you might wonder? Not quite! This value can be set to a bool, a number, an IP address string, or a function! Welcome to JAvaSCritp!

// Get NODE_ENV, which defaults to development
// and trust first proxy (pass session cookie) in prod
const isDev = app.get("env") === "development";
if (!isDev) app.set('trust proxy', 1);

I have to thank Bobby Iliev for his helpful answer on the Digital Ocean forum that led me to the solution.

Admittedly, I have confused myself a little bit and I’m still not sure I 100% undertand the solution.

When I was testing this fix in Lingomio, it was by sending Username and Password for login, and there was a separate face-palm-worthy bug extant where I was just not setting the Username/Password values in the web request at all. They were always blank. 🤦‍♂️🐛

I tested using sg-login as a simpler example and this started working when I changed from true to 1.

Now, true should accept all proxies, so why does 1 work?

Seemingly there is a difference in what Express sees as the Client IP at the end of the request chain.

From the docs:

If true, the client’s IP address is understood as the left-most entry in the X-Forwarded-For header.

(If number) Use the address that is at most n number of hops away from the Express application. req.socket.remoteAddress is the first hop

…and so - while I haven’t tested this - I feel like the remoteAddress would be the address of the reverse proxy like Caddy.

Is this why it worked? Dunno. But I feel satisfied that 1 is both a more restrictive solution (than trusting all proxies in the chain) and more effective. And I’m happy with that.

Stay cool 🌇🍃