Docker AIO External NGINX 502 error help requested

Need help with a new installation of Docker AIO behind an external NGINX reverse proxy. I am able to access the master container via DOCKERIP:8080 and all containers show as running. It shows Nextcloud AIO v8.1.0 but when I try to access the domain url I get a 502 HTML error code from NGINX. I pulled a valid certificate using certbot on the NGINX host for the domain URL. I’ve tried multiple “fixes” that I’ve found and also have gone over the reverse proxy guide but I am not sure what is wrong with the configuration. I am not able to access the page at DOCKERIP:11000. Looking to the community for help as I’m not sure what else to try. Including all configs and logs that I know to check but this is my first nextcloud deployment so I’m not sure what else may be needed.

Portainer Docker Stack:

services:
  nextcloud-aio-mastercontainer:
    image: nextcloud/all-in-one:latest
    init: true
    restart: always
    container_name: nextcloud-aio-mastercontainer # This line is not allowed to be changed as otherwise AIO will not work correctly
    volumes:
      - nextcloud_aio_mastercontainer:/mnt/docker-aio-config # This line is not allowed to be changed as otherwise the built-in backup solution will not work
      - /var/run/docker.sock:/var/run/docker.sock:ro # May be changed on macOS, Windows or docker rootless. See the applicable documentation. If adjusting, don't forget to also set 'WATCHTOWER_DOCKER_SOCKET_PATH'!
    ports:
      # - 80:80 # Can be removed when running behind a web server or reverse proxy (like Apache, Nginx, Cloudflare Tunnel and else). See https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md
      - 8085:8080
      # - 8443:8443 # Can be removed when running behind a web server or reverse proxy (like Apache, Nginx, Cloudflare Tunnel and else). See https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md
    environment: # Is needed when using any of the options below
      - AIO_DISABLE_BACKUP_SECTION=false # Setting this to true allows to hide the backup section in the AIO interface. See https://github.com/nextcloud/all-in-one#how-to-disable-the-backup-section
      - SKIP_DOMAIN_VALIDATION=true
      - APACHE_PORT=11000 # Is needed when running behind a web server or reverse proxy (like Apache, Nginx, Cloudflare Tunnel and else). See https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md
      - APACHE_IP_BINDING=0.0.0.0 # Should be set when running behind a web server or reverse proxy (like Apache, Nginx, Cloudflare Tunnel and else) that is running on the same host. See https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md
      - BORG_RETENTION_POLICY=--keep-within=7d --keep-weekly=4 --keep-monthly=6 # Allows to adjust borgs retention policy. See https://github.com/nextcloud/all-in-one#how-to-adjust-borgs-retention-policy
      - COLLABORA_SECCOMP_DISABLED=true # Setting this to true allows to disable Collabora's Seccomp feature. See https://github.com/nextcloud/all-in-one#how-to-disable-collaboras-seccomp-feature
      - NEXTCLOUD_DATADIR=/nextcloud/ncdata # Allows to set the host directory for Nextcloud's datadir. ⚠️⚠️⚠️ Warning: do not set or adjust this value after the initial Nextcloud installation is done! See https://github.com/nextcloud/all-in-one#how-to-change-the-default-location-of-nextclouds-datadir
      - NEXTCLOUD_MOUNT=/nextcloud/extstor # Allows the Nextcloud container to access the chosen directory on the host. See https://github.com/nextcloud/all-in-one#how-to-allow-the-nextcloud-container-to-access-directories-on-the-host
      - NEXTCLOUD_UPLOAD_LIMIT=100G # Can be adjusted if you need more. See https://github.com/nextcloud/all-in-one#how-to-adjust-the-upload-limit-for-nextcloud
      - NEXTCLOUD_MAX_TIME=3600 # Can be adjusted if you need more. See https://github.com/nextcloud/all-in-one#how-to-adjust-the-max-execution-time-for-nextcloud
      - NEXTCLOUD_MEMORY_LIMIT=2048M # Can be adjusted if you need more. See https://github.com/nextcloud/all-in-one#how-to-adjust-the-php-memory-limit-for-nextcloud
      # - NEXTCLOUD_TRUSTED_CACERTS_DIR=/path/to/my/cacerts # CA certificates in this directory will be trusted by the OS of the nexcloud container (Useful e.g. for LDAPS) See See https://github.com/nextcloud/all-in-one#how-to-trust-user-defined-certification-authorities-ca
      # - NEXTCLOUD_STARTUP_APPS=deck twofactor_totp tasks calendar contacts notes # Allows to modify the Nextcloud apps that are installed on starting AIO the first time. See https://github.com/nextcloud/all-in-one#how-to-change-the-nextcloud-apps-that-are-installed-on-the-first-startup
      - NEXTCLOUD_ADDITIONAL_APKS=imagemagick # This allows to add additional packages to the Nextcloud container permanently. Default is imagemagick but can be overwritten by modifying this value. See https://github.com/nextcloud/all-in-one#how-to-add-os-packages-permanently-to-the-nextcloud-container
      - NEXTCLOUD_ADDITIONAL_PHP_EXTENSIONS=imagick # This allows to add additional php extensions to the Nextcloud container permanently. Default is imagick but can be overwritten by modifying this value. See https://github.com/nextcloud/all-in-one#how-to-add-php-extensions-permanently-to-the-nextcloud-container
      # - NEXTCLOUD_ENABLE_DRI_DEVICE=true # This allows to enable the /dev/dri device in the Nextcloud container. ⚠️⚠️⚠️ Warning: this only works if the '/dev/dri' device is present on the host! If it should not exist on your host, don't set this to true as otherwise the Nextcloud container will fail to start! See https://github.com/nextcloud/all-in-one#how-to-enable-hardware-transcoding-for-nextcloud
      # - NEXTCLOUD_KEEP_DISABLED_APPS=false # Setting this to true will keep Nextcloud apps that are disabled in the AIO interface and not uninstall them if they should be installed. See https://github.com/nextcloud/all-in-one#how-to-keep-disabled-apps
      - TALK_PORT=3478 # This allows to adjust the port that the talk container is using. See https://github.com/nextcloud/all-in-one#how-to-adjust-the-talk-port
      - WATCHTOWER_DOCKER_SOCKET_PATH=/var/run/docker.sock # Needs to be specified if the docker socket on the host is not located in the default '/var/run/docker.sock'. Otherwise mastercontainer updates will fail. For macos it needs to be '/var/run/docker.sock'
    networks: # Is needed when you want to create the nextcloud-aio network with ipv6-support using this file, see the network config at the bottom of the file
      - nextcloud-aio # Is needed when you want to create the nextcloud-aio network with ipv6-support using this file, see the network config at the bottom of the file
    # # Uncomment the following line when using SELinux
    # security_opt: ["label:disable"]

volumes: # If you want to store the data on a different drive, see https://github.com/nextcloud/all-in-one#how-to-store-the-filesinstallation-on-a-separate-drive
  nextcloud_aio_mastercontainer:
    name: nextcloud_aio_mastercontainer # This line is not allowed to be changed as otherwise the built-in backup solution will not work

# # Optional: If you need ipv6, follow step 1 and 2 of https://github.com/nextcloud/all-in-one/blob/main/docker-ipv6-support.md first and then uncomment the below config in order to activate ipv6 for the internal nextcloud-aio network.
# # Please make sure to uncomment also the networking lines of the mastercontainer above in order to actually create the network with docker-compose
networks:
  nextcloud-aio:
    name: nextcloud-aio # This line is not allowed to be changed as otherwise the created network will not be used by the other containers of AIO
    driver: bridge
    enable_ipv6: true
    ipam:
      driver: default
      config:
        - subnet: fd12:3456:789a:2::/64 # IPv6 subnet to use

Docker logs:
nextcloud-aio-nextcloud

System config value overwrite.cli.url set to string https://cloud.domain.com/
System config value htaccess.RewriteBase set to string /
.htaccess has been updated
System config value dbpersistent set to boolean false
System config value files_external_allow_create_new_local set to boolean true
System config value trusted_proxies => 0 set to string 127.0.0.1
System config value trusted_proxies => 1 set to string ::1
Config value base_endpoint for app notify_push set to https://cloud.domain.com/push
+ echo nextcloud-aio-collabora
+ grep -q 'nextcloud-.*-collabora'
+ COLLABORA_HOST=cloud.domain.com
+ set +x
Config value wopi_url for app richdocuments set to https://cloud.domain.com/
Config value wopi_allowlist for app richdocuments set to 10.1.1.80,127.0.0.1/8,192.168.0.0/16,172.16.0.0/12,10.0.0.0/8,fd00::/8,::1,2606:4700:3032::ac43:8e0c
Connection to nextcloud-aio-talk-recording (172.21.0.9) 1234 port [tcp/*] succeeded!
Config value recording_servers for app spreed set to {"servers":[{"server":"http://nextcloud-aio-talk-recording:1234/","verify":true}],"secret":"02028ce5c522c07529d5d3663bc746b8c01697cdf6445b7c"}
Connection to nextcloud-aio-clamav (172.21.0.7) 3310 port [tcp/*] succeeded!
Config value av_mode for app files_antivirus set to daemon
Config value av_port for app files_antivirus set to 3310
Config value av_host for app files_antivirus set to nextcloud-aio-clamav
Config value av_stream_max_length for app files_antivirus set to 104857600
Config value av_max_file_size for app files_antivirus set to 104857600
Config value av_infected_action for app files_antivirus set to only_log
System config value enabledPreviewProviders => 0 set to string OC\Preview\Imaginary
System config value preview_imaginary_url set to string http://nextcloud-aio-imaginary:9000
System config value preview_imaginary_key set to string 7ca4689a09ef26896e784758cbc6bb152fb366996a1742cb
Connection to nextcloud-aio-fulltextsearch (172.21.0.8) 9200 port [tcp/*] succeeded!
{
    "search_platform": "OCA\\FullTextSearch_Elasticsearch\\Platform\\ElasticSearchPlatform",
    "app_navigation": "0",
    "provider_indexed": "",
    "cron_err_reset": "1713381501",
    "tick_ttl": "1800",
    "collection_indexing_list": "50",
    "migration_24": "1",
    "collection_internal": "local"
}
{
    "elastic_host": "http:\/\/elastic:5e5f915a4e50e494d4285a58aafda877699c0fd52a1b5038@nextcloud-aio-fulltextsearch:9200",
    "elastic_index": "nextcloud-aio",
    "fields_limit": "10000",
    "es_ver_below66": "0",
    "elastic_logger_enabled": "1",
    "analyzer_tokenizer": "standard",
    "allow_self_signed_cert": "false"
}
{
    "files_local": "1",
    "files_external": "0",
    "files_group_folders": "0",
    "files_encrypted": "0",
    "files_federated": "0",
    "files_size": "20",
    "files_pdf": "1",
    "files_office": "1",
    "files_image": "0",
    "files_audio": "0",
    "files_chunk_size": "2"
}
+ '[' true = true ']'
+ '[' 11000 = 443 ']'
+ '[' 127.0.0.1 = 127.0.0.1 ']'
++ dig nextcloud-aio-apache A +short +search
++ grep '^[0-9.]\+$'
++ sort
++ head -n1
+ IPv4_ADDRESS_APACHE=172.21.0.13
++ dig nextcloud-aio-apache AAAA +short +search
++ grep '^[0-9a-f:]\+$'
++ sort
++ head -n1
+ IPv6_ADDRESS_APACHE=fd12:3456:789a:2::d
++ dig nextcloud-aio-mastercontainer A +short +search
++ grep '^[0-9.]\+$'
++ sort
++ head -n1
+ IPv4_ADDRESS_MASTERCONTAINER=172.21.0.2
++ dig nextcloud-aio-mastercontainer AAAA +short +search
++ grep '^[0-9a-f:]\+$'
++ sort
++ head -n1
+ IPv6_ADDRESS_MASTERCONTAINER=fd12:3456:789a:2::2
+ sed -i 's|^;listen.allowed_clients|listen.allowed_clients|' /usr/local/etc/php-fpm.d/www.conf
+ sed -i 's|listen.allowed_clients.*|listen.allowed_clients = 127.0.0.1,::1,172.21.0.13,fd12:3456:789a:2::d,172.21.0.2,fd12:3456:789a:2::2|' /usr/local/etc/php-fpm.d/www.conf
+ sed -i '/^listen.allowed_clients/s/,,/,/g' /usr/local/etc/php-fpm.d/www.conf
+ sed -i '/^listen.allowed_clients/s/,$//' /usr/local/etc/php-fpm.d/www.conf
+ grep listen.allowed_clients /usr/local/etc/php-fpm.d/www.conf
listen.allowed_clients = 127.0.0.1,::1,172.21.0.13,fd12:3456:789a:2::d,172.21.0.2,fd12:3456:789a:2::2
+ set +x
[19-Apr-2024 23:32:23] NOTICE: fpm is running, pid 514
[19-Apr-2024 23:32:23] NOTICE: ready to handle connections
Activating Collabora config...
✓ Reset callback url autodetect
Checking configuration
🛈 Configured WOPI URL: https://cloud.domain.com/
🛈 Configured public WOPI URL: https://cloud.domain.com/
🛈 Configured callback URL: 
Failed to fetch discovery endpoint from https://cloud.domain.com/
cURL error 60: SSL certificate problem: unable to get local issuer certificate (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) for https://cloud.domain.com/hosting/discovery

nextcloud-aio-apache

Waiting for Nextcloud to start...
Connection to nextcloud-aio-nextcloud (172.21.0.11) 9000 port [tcp/*] succeeded!
[Fri Apr 19 23:28:07.924789 2024] [mpm_event:notice] [pid 79:tid 140448252300040] AH00489: Apache/2.4.58 (Unix) configured -- resuming normal operations
[Fri Apr 19 23:28:07.925029 2024] [core:notice] [pid 79:tid 140448252300040] AH00094: Command line: '/usr/local/apache2/bin/httpd -D FOREGROUND'
INF INF INF INF INF INF INF INF ts=1713583687.935424 INF INF INF INF INF INF INF INF ts=1713583687.935424 msg=using provided configuration INF INF INF INF INF INF INF INF ts=1713583687.935424 INF INF INF INF INF INF INF INF ts=1713583687.935424 msg=using provided configuration config_file=/tmp/Caddyfile INF INF INF INF INF INF INF INF ts=1713583687.935424 INF INF INF INF INF INF INF INF ts=1713583687.935424 msg=using provided configuration INF INF INF INF INF INF INF INF ts=1713583687.935424 INF INF INF INF INF INF INF INF ts=1713583687.935424 msg=using provided configuration config_file=/tmp/Caddyfile config_adapter=

NGINX Config
cloud.nginx

# ------------------------------------------------------------
# cloud.domain.com
# ------------------------------------------------------------
upstream php-handler {
    server unix:/run/php/php8.2-fpm.sock;
}
##
# Connection header for WebSocket reverse proxy
##
map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}
server {
    set $forward_scheme http;
    set $server "10.1.1.32";
    set $port 11000;
    listen 80;
    listen [::]:80;
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name cloud.domain.com;
    # Let's Encrypt SSL
    ssl_certificate /nas/letsencrypt/archive/cloud.domain.com/cert1.pem;
    ssl_certificate_key /nas/letsencrypt/archive/cloud.domain.com/privkey1.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    include mime.types;
    types {
        text/javascript js mjs;
	application/wasm wasm;
    }    
    # Asset Caching
    # include assets.conf;
    # Block Exploits
    # include security.conf;
    #HSTS (ngx_http_headers_module is required) (63072000 seconds = 2 years)
    # add_header Strict-Transport-Security "max-age=63072000;includeSubDomains; preload" always;
    # Force SSL
    include force-ssl.conf;
    access_log /var/log/nginx/proxy-cloud.domain.com_access.log,facility=local7,tag=nginx,severity=info;
    error_log /var/log/nginx/proxy-cloud.domain.com_error.log,facility=local7,tag=nginx,severity=warn;
    gzip off;
    location / {
        # Web sockets
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_http_version 1.1;
        # Proxy config
        include proxy.conf;
        client_body_buffer_size 512k;
        proxy_read_timeout 86400s;
        client_max_body_size 0;
        proxy_ssl_certificate     /nas/letsencrypt/archive/cloud.domain.com/fullchain1.pem;
        proxy_ssl_certificate_key /nas/letsencrypt/archive/cloud.domain.com/privkey1.pem;
        proxy_ssl_session_reuse on;
    }
    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        fastcgi_index index.php;
        include fastcgi.conf;
    }
}

proxy.conf

add_header       X-Served-By $host;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Scheme $scheme;
proxy_set_header X-Forwarded-Proto  $scheme;
proxy_set_header X-Forwarded-For    $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP          $remote_addr;
proxy_pass       $forward_scheme://$server:$port$request_uri;

nginx.conf

user www-data;
worker_processes auto;
pid /run/nginx.pid;
error_log /var/log/nginx/error.log;
include /etc/nginx/modules-enabled/*.conf;
events {
	worker_connections 768;
	# multi_accept on;
}
http {
	##
	# Basic Settings
	##
	server_tokens                 off;
	tcp_nodelay                   on;
	client_body_temp_path         /tmp/body 1 2;
	keepalive_timeout             90s;
	proxy_connect_timeout         90s;
	proxy_send_timeout            90s;
	proxy_read_timeout            90s;
	proxy_ignore_client_abort     off;
	client_max_body_size          2000m;
	proxy_http_version            1.1;
	proxy_set_header              X-Forwarded-Scheme $scheme;
	proxy_set_header              X-Forwarded-For $proxy_add_x_forwarded_for;
	proxy_set_header              Accept-Encoding "";
	# Set cache zone size
    proxy_cache_path /tmp/nginxcache levels=1:2 keys_zone=nginxcache:10m max_size=10g inactive=60m;
	# proxy_cache                   off;
	# proxy_cache_path              /var/lib/nginx/cache/public  levels=1:2 keys_zone=public-cache:30m max_size=1024m;
	# proxy_cache_path              /var/lib/nginx/cache/private levels=1:2 keys_zone=private-cache:5m max_size=1024m;
	log_format proxy '[$time_local] $upstream_cache_status $upstream_status $status - $request_method $scheme $host "$request_uri" [Client $remote_addr] [Length $body_bytes_sent] [Gzip $gzip_ratio] "$http_user_agent" "$http_referer"';
	log_format standard '[$time_local] $status - $request_method $scheme $host "$request_uri" [Client $remote_addr] [Length $body_bytes_sent] [Gzip $gzip_ratio] "$http_user_agent" "$http_referer"';
	sendfile on;
	tcp_nopush on;
	types_hash_max_size 2048;
	# server_tokens off;
	server_names_hash_bucket_size 64;
	# server_name_in_redirect off;
	include /etc/nginx/mime.types;
	default_type application/octet-stream;
	##
	# SSL Settings
	##
	ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
	ssl_prefer_server_ciphers on;
	##
	# Logging Settings
	##
	access_log /var/log/nginx/access.log;
	##
	# Gzip Settings
	##
	gzip on;
	# gzip_vary on;
	# gzip_proxied any;
	# gzip_comp_level 6;
	# gzip_buffers 16 8k;
	# gzip_http_version 1.1;
	# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
	##
	# Virtual Host Configs
	##
	include /etc/nginx/conf.d/*.conf;
	include /etc/nginx/sites-enabled/*;
	# Default upstream scheme
	map $host $forward_scheme {
		default http;
	}
	# Real IP Determination
	# Local subnets:
	set_real_ip_from 10.0.0.0/8;
	set_real_ip_from 172.16.0.0/12; # Includes Docker subnet
	set_real_ip_from 192.168.0.0/16;        
	proxy_set_header X-Forwarded-Port $server_port;
	# NPM generated CDN ip ranges:
	include ip_ranges.conf;
	# always put the following 2 lines after ip subnets:
	real_ip_header X-Real-IP;
	real_ip_recursive on;
}
stream {
	include /etc/nginx/stream/*.conf;
}
#mail {
#	# See sample authentication script at:
#	# http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
#
#	# auth_http localhost/auth.php;
#	# pop3_capabilities "TOP" "USER";
#	# imap_capabilities "IMAP4rev1" "UIDPLUS";
#
#	server {
#		listen     localhost:110;
#		protocol   pop3;
#		proxy      on;
#	}
#
#	server {
#		listen     localhost:143;
#		protocol   imap;
#		proxy      on;
#	}
#}

NGINX Logs

2024/04/20 11:21:34 [error] 4961#4961: *23915 connect() failed (111: Connection refused) while connecting to upstream, client: 10.2.2.20, server: cloud.domain.com, request: "GET / HTTP/2.0", upstream: "http://10.1.1.32:11000/", host: "cloud.domain.com", referrer: "https://10.1.1.32:8085/"
2024/04/20 11:21:47 [error] 4961#4961: *23923 connect() failed (111: Connection refused) while connecting to upstream, client: 10.1.1.32, server: cloud.domain.com, request: "GET /apps/richdocuments/settings/fonts.json HTTP/1.1", upstream: "http://10.1.1.32:11000/apps/richdocuments/settings/fonts.json", host: "cloud.domain.com"
10.1.1.32 - - [20/Apr/2024:11:19:47 -0400] "GET /apps/richdocuments/settings/fonts.json HTTP/1.1" 502 150 "-" "COOLWSD HTTP Agent 23.05.10.1"
10.1.1.32 - - [20/Apr/2024:11:20:47 -0400] "GET /apps/richdocuments/settings/fonts.json HTTP/1.1" 502 150 "-" "COOLWSD HTTP Agent 23.05.10.1"
10.2.2.20 - - [20/Apr/2024:11:21:34 -0400] "GET / HTTP/2.0" 502 150 "https://10.1.1.32:8085/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:125.0) Gecko/20100101 Firefox/125.0"
10.2.2.20 - - [20/Apr/2024:11:21:34 -0400] "GET /favicon.ico HTTP/2.0" 499 0 "https://cloud.domain.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:125.0) Gecko/20100101 Firefox/125.0"
10.1.1.32 - - [20/Apr/2024:11:21:47 -0400] "GET /apps/richdocuments/settings/fonts.json HTTP/1.1" 502 150 "-" "COOLWSD HTTP Agent 23.05.10.1"
10.1.1.32 - - [20/Apr/2024:11:22:47 -0400] "GET /apps/richdocuments/settings/fonts.json HTTP/1.1" 502 150 "-" "COOLWSD HTTP Agent 23.05.10.1"

Hi, can you follow all-in-one/reverse-proxy.md at main · nextcloud/all-in-one · GitHub?

I’ve followed thevguide but I am not sure why it isn’t working. I am trying to get this working with my external NGINX reverse proxy. The “nextcloud-aio-apache” isn’t reachable via http://DOCKERHOSTIP:11000, should it be normally? I am not using the docker caddy config but I still see this message in the logs from the apache container.

ts=1713583687.935424 msg=using provided configuration config_file=/tmp/Caddyfile