NGINX reverse proxy discussion

Hi everyone

The official NGINX reverse proxy documentation is rather sparse.
The AIO reverse proxy documentation is more detailed, but could need some fine tuning.
I am a little bit surprised that there are basically two documentations for the same thing, and why the official doc not only links to the AIO doc. Either way, I want to discuss the AIO documentation.

First off, I am not an NGINX expert. I just read up on settings and think there is stuff than can be done differently. I might very well be the case, that I am suffering from the Dunning Kruger effect when it comes to NGINX proxy! If that is the case, I am sorry for wasting your time.

I wrote @szaimen in private if he likes GH issues or a forum post, and he went for the forum post here :slight_smile:

The very first thing I struggle with the doc, is that we at first have examples for NGINX and many more but then have a section on how about a NGINX-Proxy isn’t working.

Am I missing something, because I am not a Docker user? Does this “NGINX not working” only apply to Docker? Is there anything that hinders a AIO user from running Nextcloud in Docker and the NGINX reverse proxy not in docker?

Short answer:

NGINX ≠ NGINX-Proxy

Longer answer:

As I understand it, the Nginx, Freenginx, OpenResty, Angie section is meant to work with plain NGINX or one of the mentioned distributions or forks (Freenginx, OpenResty, Angie).

The NGINX-Proxy section is most likely referring to this project, and it seems to be listed mainly to warn users not to use it.

Then there are also instructions for NGINX Proxy Manager and NPM Plus, the latter being a fork of the former. Both of these use NGINX under the hood, and provide a web UI to manage proxy hosts.

1 Like

Ahh got it. I tried to google it, but of course did only find other stuff.
I think with that out of the way, we can start our discussion :slightly_smiling_face:

The setting proxy_read_timeout is by default 60 seconds. It is changed to
proxy_read_timeout 86400s;

AFAIK that is not really needed to be that high. This is only how long it will wait for a response, not how long a transmission is taking. That is why I think we can ditch that setting completely (so it defaults back to 60 seconds) or at least set it to something more realistic like 120 seconds. If Nextcloud does not answer for 120s, I think something is severely wrong and the connection should be closed.

Again, maybe I am on mount stupid on the dunning kruger scale. If you disagree or are also not sure, I am happy to run some test on that theory. But if I am wrong with my assumption, my next question would be, why we set only a read and not also a write timeout?

I’m not a developer and don’t have in-depth knowledge of how WebSocket connections or WebDAV actually work. But yes, I think you’re right that a transmission generally shouldn’t be interrupted before it’s completed, even if it takes longer than 60 seconds. In practice, though, it’s probably more complicated, because complex web applications like Nextcloud using WebDAV and other long-running APIs don’t always stream continuously. Uploads or downloads can pause, for example, while the backend processes chunks, handles encryption, or waits on slow PHP execution.

However, even with that in mind, I also doubt that it really needs to be set as high as 86,400 seconds (i.e., 24 hours), which effectively disables the timeout. Still, 60 or 120 seconds might be too short in some situations.

If I had to guess, I’d say that such a high value is probably just a way of playing it safe. Or maybe Nextcloud does indeed some ‘special’ things that actually require it, e.g. during updates via the WebUI? Although even those tasks don’t take 24 hours, and they certainly shouldn’t time out for that long, otherwise, I agree, that there would be more fundamental problems to solve. :wink:

But yeah, at the end of the day, I’m not really sure what the actual reasoning is behind setting such a high value in the example config.

1 Like

That could very well be the case, but by that logic there would also a need for a timeout for writing, right?

And I am also not sure if a high timeout could have negative side effects. Like if there is a bug and multiple “wrong” connections are created and instead of them getting closed after a minute, they are kept open for a day, that might overload the NGINX server?

I can only explain this in a very amateurish way, but in Nextcloud there’s a lot going on beyond normal website requests or file uploads/downloads.

In addition to standard web traffic (HTML, JavaScript, WebDAV), there can be WebSocket connections to backends like Notify_Push, Collabora, Whiteboard etc, which means asynchronous traffic is happening all the time.

At this point, I must admit that I am not enough of an expert, and someone with deeper knowledge of NGINX, Nextcloud, and long-running connections would need to explain this in detail.

However, If I had to guess, such an expert would probably say that 86400s is overkill, and in the worst case could lead to resource problems or even security concerns?

But as I said, this is just my (not so) educated guess. :slight_smile:

The short answer is: It depends on your specific situation.

The purpose of proxy_read_timeout is much like fastcgi_read_timeout. For a reverse proxy, it prevents 504 timeouts from happening when the backend server is taking a long time to respond. For instance, if you’re dealing with a large file upload where the final assembly is slow or the backend’s disk I/O is a bottleneck, this timeout can be critical.

A setting of 86400 seconds (24 hours) is likely overkill. But using a more generous value at the start can make for a smoother deployment, as it helps you avoid initial problems that are hard to distinguish from other potential issues. After all, you have several other timeout values across different layers that all have to work together.

Once everything is running smoothly, you can gradually decrease specific timeout values until you trigger an issue. This lets you more easily track down the cause of a new problem.

In most cases, a setting of 180 to 300 seconds is probably a good balance. But Nextcloud has a wide audience of users. People do crazy stuff like try to upload 1TB files to their Raspberry Pi connected to an external USB 2.0/HS HDD. :wink:

3 Likes

I think we mostly got that point solved.

My next question would be, why this is missing:

location /.well-known/carddav {

return 301 $scheme://$host/remote.php/dav;

}

location /.well-known/caldav {

return 301 $scheme://$host/remote.php/dav;

}

location ^\~ /.well-known {

return 301 $scheme://$host/index.php$uri;

}