Nginx reverse proxy on different host NSURLErrorDomain

Nextcloud version (eg, 20.0.5): 25.0.6
Operating system and version (eg, Ubuntu 20.04): Debian GNU/Linux 11 (bullseye)
Apache or nginx version (eg, Apache 2.4.25): Apache/2.4.56 (Debian)
PHP version (eg, 7.4): 7.4.33

The issue you are facing:
I have Nextcloud installed in Container1 on my Proxmox server, and nginx reverse proxy set up in Container2. I want to route requests to my Nextcloud subdomain (i.e. nextcloud.example.com) through my reverse proxy. My nginx host controls ports 80 and 443 on my router. I have read through many guides but haven’t found an answer that works for me. Could someone look through my setup below and let me know what I’ve done wrong?

For context, currently I can access Nextcloud via local IP only while connected to my local network. When attempting to access nextcloud.example.com from my iOS Firefox browser, I get NSURLErrorDomain on regardless of which network I am connected to. Interestingly, Windows computers on my local network can access Nextcloud via subdomain and local IP.

Domain name (changed from actual): nextcloud.example.com
Container1 (Nextcloud): 10.0.0.117
Container2 (Nginx): 10.0.0.10

Is this the first time you’ve seen this error? (Y/N): Y

The output of my config.php file in /var/www/nextcloud/config/config.php:

<?php
$CONFIG = array (
  'passwordsalt' => 'xxx',
  'secret' => 'yyy',
  'trusted_domains' => 
  array (
    0 => 'localhost',
    1 => '10.0.0.117',
    2 => 'nextcloud.example.com',
    3 => '10.0.0.10',
  ),
  'trusted_proxies' => 
  array (
    0 => '10.0.0.10',
  ),
  'datadirectory' => '/var/www/nextcloud-data',
  'dbtype' => 'mysql',
  'version' => '25.0.3.2',
  'overwritehost' => 'nextcloud.example.com',
  'overwritewebroot' => '/',
  'overwrite.cli.url' => 'https://nextcloud.example.com',
  'overwriteprotocol' => 'https',
  'overwritecondaddr' => '^10\.0\.0\.10$',
  'forwarded-for-headers' =>
  array (
    0 => 'HTTP_X_FORWARDED',
    1 => 'HTTP_FORWARDED_FOR',
  ),
  'htaccess.RewriteBase' => '/',
  'dbname' => 'nextcloud',
  [...removed the rest for brevity]
);

The output of my Apache config in /etc/apache2/sites-available/nextcloud.conf:

ServerName localhost

<VirtualHost *:80>
    UseCanonicalName Off
    ServerAdmin webmaster@localhost

  DocumentRoot /var/www/nextcloud/
  <IfModule mod_dav.c>
    Dav off
  </IfModule>
  SetEnv HOME /var/www/nextcloud
  SetEnv HTTP_HOME /var/www/nextcloud

    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteCond %{REQUEST_URI} !^/.well-known
    RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</VirtualHost>

<VirtualHost *:443>
    SSLEngine on
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/nextcloud/

    <IfModule mod_headers.c>
        Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains"
    </IfModule>
</VirtualHost>

<Directory /var/www/nextcloud/>
    Options +FollowSymLinks
    AllowOverride All
    Require all granted
</Directory>

The output of my Nginx config in Container2 (ngnix reverse proxy dedicated host):

server {
    listen 80;
        server_name nextcloud.example.com;

        return 301 https://$server_name$request_uri;
}

server {
        listen 443 ssl;
        server_name nextcloud.example.com;

        access_log /var/log/nginx/cloud.example.com.access.log;
        error_log /var/log/nginx/cloud.example.com.error.log;

        client_max_body_size 0;
        underscores_in_headers on;

        # Let's Encrypt SSL
        include /etc/nginx/conf.d/include/letsencrypt-acme-challenge.conf;
        include /etc/nginx/conf.d/include/ssl-ciphers.conf;
        ssl_certificate /etc/letsencrypt/live/npm-1/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/npm-1/privkey.pem;

        location / {
                proxy_headers_hash_max_size 512;
                proxy_headers_hash_bucket_size 64;
                proxy_set_header Host $host;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

                add_header Front-End-Https on;
                proxy_pass https://10.0.0.117;
        }
}

And finally, here is the output of the curl command run on my a different machine:

$ curl -i https://nextcloud.example.com
curl: (7) Failed to connect to nextcloud.example.com port 443 after 21044 ms: Connection refused

Thanks!

Need to specify the location in your Nginx configuration. Something like this:
server {
listen 443 ssl;
server_name nextcloud.example.com
ssl_certificate /etc/letsencrypt/live/nextcloud.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/nextcloud.example.comprivkey.pem;
access_log /var/log/nextcloud.access.log;

location / {
    proxy_pass http://10.0.0.117:internal port you using;
    include /etc/nginx/proxy_params;
    include /etc/nginx/fastcgi_params;
}

}

Hope this helps.

Hi, thanks for responding so quickly! I updated my nginx config to the below based on yours, but I am still getting the same error.

server {
    listen 80;
        server_name nextcloud.example.com;

        return 301 https://$server_name$request_uri;
}

server {
        listen 443 ssl;
        server_name nextcloud.example.com;

        access_log /var/log/nginx/nextcloud.access.log;
        error_log /var/log/nginx/nextcloud.error.log;

        client_max_body_size 0;
        underscores_in_headers on;

        # Let's Encrypt SSL
        include /etc/nginx/conf.d/include/letsencrypt-acme-challenge.conf;
        include /etc/nginx/conf.d/include/ssl-ciphers.conf;
        ssl_certificate /etc/letsencrypt/live/npm-1/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/npm-1/privkey.pem;

        location / {
                proxy_headers_hash_max_size 512;
                proxy_headers_hash_bucket_size 64;
                proxy_set_header Host $host;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

                add_header Front-End-Https on;
                proxy_pass https://10.0.0.117:443;
                include /etc/nginx/conf/fastcgi_params;
        }
}

My question is, should my nginx host be communicating with my Nextcloud host over port 443 (HTTPS) or port 80 (HTTP)? I’ve tried changing all instances of https to http in my nextcloud config.php to see, but that made it so I couldn’t access my server locally anymore (502 Bad Gateway).

Also, what should overwritehost be set to in Nextcloud’s config.php? The IP of my reverse proxy, the IP of my Nextcloud host, or my subdomain? The documentation says it should be my proxy’s IP (10.0.0.10), but I’ve seen other threads use different things.

it depends on your config. both is possible… personally I prefer https connection behind reverse proxy for the sake of simplicity… otherwise you have to manage two different TLS certs/implementations… but there are reasons to have backend connection secured as well

  1. review docs - understanding the issue helps much more than try&error approach
  2. use the search - lot of issues have been discussed already…

After some tinkering I managed to get Nextcloud working over HTTP. For any others who are experiencing similar problems to me, here are my changes:

Nextcloud /var/www/nextcloud/config/config.php (10.0.0.117):

<?php
$CONFIG = array (
  'passwordsalt' => 'xxx',
  'secret' => 'yyy',
  'trusted_domains' => 
  array (
    0 => 'localhost',
    1 => '10.0.0.117',
    2 => 'nextcloud.example.com',
    3 => '10.0.0.10',
  ),
  'trusted_proxies' => 
  array (
    0 => '10.0.0.10',
  ),
  'datadirectory' => '/var/www/nextcloud-data',
  'dbtype' => 'mysql',
  'version' => '25.0.3.2',
  'overwritehost' => 'nextcloud.example.com',
  'overwritewebroot' => '/',
  'overwrite.cli.url' => 'https://nextcloud.example.com',
  'overwriteprotocol' => 'http',
  'overwritecondaddr' => '^10\\.0\\.0\\.10$',
  'forwarded_for_headers' => ['HTTP_X_FORWARDED', 'HTTP_FORWARDED_FOR'],
  'htaccess.RewriteBase' => '/',
  'dbname' => 'nextcloud',
  [...removed the rest]
}

Nginx config for Nextcloud connection in other Container (10.0.0.10):

server {
    listen 80;
        server_name nextcloud.example.com;

        return 301 https://$server_name$request_uri;
}

server {
        listen 443 ssl http2;
        server_name nextcloud.example.com;

        access_log /var/log/nginx/nextcloud.access.log;
        error_log /var/log/nginx/nextcloud.error.log;

        client_max_body_size 0;
        underscores_in_headers on;

        # Let's Encrypt SSL
        ssl on;
        include /etc/nginx/conf.d/include/letsencrypt-acme-challenge.conf;
        include /etc/nginx/conf.d/include/ssl-ciphers.conf;
        ssl_certificate /etc/letsencrypt/live/npm-1/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/npm-1/privkey.pem;

        ssl_stapling on;
        ssl_stapling_verify on;

        location / {
                proxy_headers_hash_max_size 512;
                proxy_headers_hash_bucket_size 64;
                proxy_set_header Host $host;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

                proxy_set_header X-Forwarded-Host $server_name;
                proxy_set_header X-Forwarded-Ssl on;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
                proxy_http_version 1.1;

                add_header Front-End-Https on;
                proxy_pass http://10.0.0.117;
                include /etc/nginx/conf/fastcgi_params;
        }
}

It would be nice to get this working over HTTPS, but honestly I’ve spent way too much time on this to keep going. If anyone has any tips based on my configuration, let me know.

I suggest removing the ‘http2’ from your Nginx file. The http2 protocol is not widely supported yet. Restart Nginx and try connecting again with https.

Of course, it is widely supported. Virtually every web server and web browser has supported it for years.

Also HTTP2 has nothing to do with HTTPS, well at least not directly. In theory HTTP2 can be used with both HTTPS (h2) and HTTP (h2c). However, most browsers only support h2, so there are not many practical use cases for h2c.