Other host NGINX reverse proxy cannot reach docker NextCloud

The Basics

  • Nextcloud Server version:
    • Nextcloud Hub 9 (30.0.5) (Docker)
  • Operating system and version:
    • Ubuntu 24.04
  • Reverse proxy and version _(e.g. nginx 1.27.2)
    • nginx 1.24.0
  • PHP version (e.g, 8.3):
    • 8.2.27
  • Installation method (e.g. AlO, NCP, Bare Metal/Archive, etc.)

Summary of the issue you are facing:

After fresh installing the dockerized NextCloud, I am able to access the web panel via the Docker host IP address and port configured, but cannot access through my NGINX reverse proxy.

I previously had a standard installation on another Ubuntu VM and am re-using the reverse proxy configuration that was used then.

I have tried a few environment switches like disabling APACHE_DISABLE_REWRITE_IP and configuring OVERWRITE options, but did not work either.

Hoping some smarter people than me can have a look and tell me if I missed something.

Configurations

Docker Compose YAML (Host: 10.0.0.15)

nextcloud_db:
    image: mariadb:10.6
    restart: always
    command: --transaction-isolation=READ-COMMITTED --log-bin=binlog --binlog-format=ROW
    volumes:
      - /path/to/nextcloud/db:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=PASSWORD
      - MYSQL_PASSWORD=PASSWORD
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
  nextcloud:
    image: nextcloud
    restart: always
    ports:
      - 80:80
    links:
      - nextcloud_db
    volumes:
      - /data/nextcloud:/var/www/html
    environment:
      - NEXTCLOUD_ADMIN_USER=USER
      - NEXTCLOUD_ADMIN_PASSWORD=PASSWORD
      - MYSQL_PASSWORD=PASSWORD
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
      - MYSQL_HOST=nextcloud_db
      - TRUSTED_PROXIES=10.0.0.20
      - NEXTCLOUD_TRUSTED_DOMAINS= localhost 10.0.0.15 my.domain.com

Nextcloud config.php (Host: 10.0.0.15)

<?php
$CONFIG = array (
  'htaccess.RewriteBase' => '/',
  'memcache.local' => '\\OC\\Memcache\\APCu',
  'apps_paths' =>
  array (
    0 =>
    array (
      'path' => '/var/www/html/apps',
      'url' => '/apps',
      'writable' => false,
    ),
    1 =>
    array (
      'path' => '/var/www/html/custom_apps',
      'url' => '/custom_apps',
      'writable' => true,
    ),
  ),
  'trusted_proxies' =>
  array (
    0 => '10.0.0.20',
  ),
  'upgrade.disable-web' => true,
  'passwordsalt' => 'SALT',
  'secret' => 'SECRET',
  'trusted_domains' =>
  array (
    0 => 'localhost',
    1 => 'localhost',
    2 => '10.0.0.15',
    3 => 'my.domain.com',
  ),
  'datadirectory' => '/var/www/html/data',
  'dbtype' => 'mysql',
  'version' => '30.0.5.1',
  'overwrite.cli.url' => 'http://localhost',
  'dbname' => 'nextcloud',
  'dbhost' => 'nextcloud_db',
  'dbport' => '',
  'dbtableprefix' => 'oc_',
  'mysql.utf8mb4' => true,
  'dbuser' => 'nextcloud',
  'dbpassword' => 'PASSWORD',
  'installed' => true,
  'instanceid' => 'INSTANCE',
);

NGINX Reverse Proxy Config (Host: 10.0.0.20)

Passes nginx -t

map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}

server {
    listen 80;
    if ($scheme = "http") {
        return 301 https://$host$request_uri;
    }
    if ($http_x_forwarded_proto = "http") {
        return 301 https://$host$request_uri;
    }

    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    proxy_buffering off;
    proxy_request_buffering off;
    client_max_body_size 0;
    client_body_buffer_size 512k;
    proxy_read_timeout 86400s;

    server_name my.domain.com;

    location / {
        proxy_pass http://10.0.0.15:80$request_uri
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Port $server_port;
        proxy_set_header X-Forwarded-Scheme $scheme;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $host;
        proxy_set_header Early-Data $ssl_early_data;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
    }
    ssl_certificate /etc/letsencrypt/live/tomfr.ca-0001/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/tomfr.ca-0001/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}