Separate Download and Frontend Servers

My current setup:

  • Nginx is on a cloud VPS.
  • MySQL is on a self-hosted VPS.
  • Storage is set to use S3.
  • VPN hooks the cloud VPS to self-hosted VPS’.

The problem with this setup is that, because the ping between MySQL and Nginx is higher than usual (35ms, versus <1ms for LAN connections), the frontend tends to lag significantly. The downloads themselves, however, are quite speedy. Moving the entire setup to a local VPS isn’t feasible due to Comcast’s sucky upload speed.

What I would like to do is this:

  • Nginx on Cloud VPS – Handles downloads only. Reverse proxy to local VPS for all else.
  • Nginx on local VPS – Handles the front-end and Redis. Should be significantly faster since it’s on the same network as MySQL.

I’m thinking this should be possible. The documentation references multiple Nextcloud servers being possible, even if it doesn’t directly spell out how to set that up. At one point, I managed to actually get it working for a few minutes, but then it seemingly gave up, and now I’m a bit stumped.

I noticed that when downloading, /index.php/webdav/ is used, so I set Cloud Nginx to proxy-pass everything except that directory, where it would run the php itself.

        location / {
                proxy_pass http://192.168.1.51/;
                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;

        }

        location ~ /remote.php/webdav/ {
                fastcgi_split_path_info ^(.+?\.php)(\/.*|)$;
                set $path_info $fastcgi_path_info;
                try_files $fastcgi_script_name =404;
                include fastcgi_params;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_param PATH_INFO $path_info;
                fastcgi_param HTTPS on;
                # Avoid sending the security headers twice
                fastcgi_param modHeadersAvailable true;
                # Enable pretty urls
                fastcgi_param front_controller_active true;
                fastcgi_pass php-handler;
                fastcgi_intercept_errors on;
                fastcgi_request_buffering off;
        }

(I yanked a few other location blocks that don’t affect the end result.)

The Nextcloud directories were cloned between the two servers. The config was set to use the self-hosted VPS as the Redis server.

An LDAP server is used for SSO, but it’s tied to the same port on both machines using an SSH tunnel.

Where I’m at right now: The frontend works perfectly smoothly. But once a download is started, a 401 error occurs, and my web browser requests a username/password (with exception to shared links). The logs on the self-hosted VPS don’t show anything of note. The logs on the cloud VPS show errors similar to:

{"reqId":"<Hidden>","level":1,"time":"2021-06-22T13:25:36+00:00","remoteAddr":"<Hidden>","user":"--","app":"no app in context","method":"GET","url":"/remote.php/webdav/Pictures/Screenshot%20from%202021-06-20%2006-01-29.png?downloadStartSecret=<Hidden>","message":{"Exception":"Symfony\\Component\\Routing\\Exception\\RouteNotFoundException","Message":"Unable to generate a URL for the named route \"tasks.page.index\" as such route does not exist.","Code":0,"Trace":[{"file":"/var/www/nextcloud/lib/private/Route/Router.php","line":372,"function":"generate","class":"Symfony\\Component\\Routing\\Generator\\UrlGenerator","type":"->"},{"file":"/var/www/nextcloud/lib/private/URLGenerator.php","line":83,"function":"generate","class":"OC\\Route\\Router","type":"->"},{"file":"/var/www/nextcloud/lib/private/NavigationManager.php","line":282,"function":"linkToRoute","class":"OC\\URLGenerator","type":"->"},{"file":"/var/www/nextcloud/lib/private/NavigationManager.php","line":108,"function":"init","class":"OC\\NavigationManager","type":"->"},{"file":"/var/www/nextcloud/apps/theming/lib/ThemingDefaults.php","line":183,"function":"getAll","class":"OC\\NavigationManager","type":"->"},{"file":"/var/www/nextcloud/lib/public/Defaults.php","line":160,"function":"getShortFooter","class":"OCA\\Theming\\ThemingDefaults","type":"->"},{"file":"/var/www/nextcloud/lib/private/Template/JSConfigHelper.php","line":291,"function":"getShortFooter","class":"OCP\\Defaults","type":"->"},{"file":"/var/www/nextcloud/lib/private/TemplateLayout.php","line":210,"function":"getConfig","class":"OC\\Template\\JSConfigHelper","type":"->"},{"file":"/var/www/nextcloud/lib/private/legacy/OC_Template.php","line":183,"function":"__construct","class":"OC\\TemplateLayout","type":"->"},{"file":"/var/www/nextcloud/apps/dav/lib/Files/BrowserErrorPagePlugin.php","line":109,"function":"fetchPage","class":"OC_Template","type":"->"},{"file":"/var/www/nextcloud/apps/dav/lib/Files/BrowserErrorPagePlugin.php","line":86,"function":"generateBody","class":"OCA\\DAV\\Files\\BrowserErrorPagePlugin","type":"->"},{"file":"/var/www/nextcloud/3rdparty/sabre/event/lib/WildcardEmitterTrait.php","line":89,"function":"logException","class":"OCA\\DAV\\Files\\BrowserErrorPagePlugin","type":"->"},{"file":"/var/www/nextcloud/3rdparty/sabre/dav/lib/DAV/Server.php","line":254,"function":"emit","class":"Sabre\\DAV\\Server","type":"->"},{"file":"/var/www/nextcloud/3rdparty/sabre/dav/lib/DAV/Server.php","line":319,"function":"start","class":"Sabre\\DAV\\Server","type":"->"},{"file":"/var/www/nextcloud/apps/dav/appinfo/v1/webdav.php","line":84,"function":"exec","class":"Sabre\\DAV\\Server","type":"->"},{"file":"/var/www/nextcloud/remote.php","line":167,"args":["/var/www/nextcloud/apps/dav/appinfo/v1/webdav.php"],"function":"require_once"}],"File":"/var/www/nextcloud/3rdparty/symfony/routing/Generator/UrlGenerator.php","Line":143,"CustomMessage":"--"},"userAgent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.101 Safari/537.36","version":"20.0.8.1"}

At first I was thinking this had to do with the download itself, but I’m starting to think that maybe the cloud VPS is attempting to take over the front-end when it starts it’s download, invoking the error. This is indicated to me by how it’s referencing plugins. I’m a tad stumped as to what I should try next. Any ideas?