Solved NodeJS app logs do not show IP address of clients
I am using the morgan console logger module for my custom NodeJS app. I have set it up as a middleware and it is working fine. Except all request logs show the same IP i.e. 172.18.0.1. This is the same as the IP for the cloudron health checks.
How can I make this logger show the IP of the actual clients of the webapp?
This is showing the reverse proxy ip and seems to be expected. According to https://github.com/expressjs/morgan/issues/76 you have to configure express with:
app.set('trust proxy', true);
Note: It took me a minute to put this together while @nebulon was responding and I got pulled onto something else for a minute, but I think the detailed writeup is worth having for posterity, so I'll post it anyway.
So what's going on here is that the app in question isn't reading the "right" headers to find the remote address. Basically, the inbound requests come in and hit the box-level nginx reverse proxy, which forwards the request on with the original inbound IP in the
X-Forwarded-Forheader. Since from the sound of it, you're just routing straight to your app in the container, you'll want to either reconfigure your logging library to use the forwarded IP header as the client IP or drop nginx or similar as a reverse proxy in front of your app and configure it to rearrange the incoming headers as your app needs.
Sounds like you can just adjust a configuration so that this (your existing flow) works nicely:
Basically, here, the headers are adjusted in the "Step 1" processing as they reach the Cloudron so when they reach your app, the proxied headers have already gone into place. Again, this configuration should be fine with the configuration that @nebulon mentioned going in, since that should reconfigure your framework to read these adjusted headers correctly.
Failing that, or for apps with more complex setup or which aren't able to read those headers on their own by configuration, the solution is to further proxy those requests, by adding nginx or similar to take over the "Step 3" handoff and smooth out any specific details (like re-adjusting headers) for the app, and having it proxy those requests down to your app, all in-container, so that the logging and such in your app will all match up with expectations/reality. The whole point of the second reverse proxy when it's added it to make the world appear as it needs to for the app and/or its components inside the container.