Docker Nextcloud & nginx -> your instance is generating insecure URLs

Support intro

hi!

The Overview - Administration settings - Nextcloud page shows: You are accessing your instance over a secure connection, however your instance is generating insecure URLs. This most likely means that you are behind a reverse proxy and the overwrite config variables are not set correctly.

Where can I see these insecure URLs? What do they look like? My Nextcloud instance seems to be working correctly.

Nextcloud is behind a nginx reverse proxy.

I am using the official Nextcloud Docker image and have not changed anything in it. Nextcloud shows the correct client IP address in the logs. I have tried setting TRUSTED_PROXIES to the IP address of the proxy with --env TRUSTED_PROXIES=192.168.42.2 but that didn’t remove the warning.

thanks for reading my message!

Nextcloud version: Nextcloud Hub 5 (27.0.2)
Operating system and version : Flatcar Container Linux by Kinvolk stable 3510.2.6
Apache or nginx version: nginx/1.17.10
Official Docker Image: Nextcloud 27.0.2

The issue you are facing:

The Overview page shows: You are accessing your instance over a secure connection, however your instance is generating insecure URLs. This most likely means that you are behind a reverse proxy and the overwrite config variables are not set correctly.

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

Steps to replicate it:

  1. install ngnix using docker
  2. install Nextcloud using docker
  3. look at system overview

Nginx config for Netxcloud:

server {
	server_name nextcloud.pook.it;
	client_max_body_size 512M;
	include /etc/nginx/snippets/ssl-server.conf;

	location /.well-known/carddav {
	    return 301 $scheme://$host/remote.php/dav;
	}
	location /.well-known/caldav {
		return 301 $scheme://$host/remote.php/dav;
	}

	location / {
		resolver           127.0.0.11 valid=37s;
		set                $upstream nextcloud;
		proxy_pass         http://$upstream:80;
		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;

		add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
	}
}

Nextcloud start command:

w=nextcloud
version=27 # only increase versions one at a time
drop="--cap-add=dac_override --cap-add=chown"
docker pull $w:$version
docker run \
	--detach \
	--cap-drop=all \
	$drop \
	--cap-add net_bind_service \
	--cap-add=dac_override \
	--cap-add setgid \
	--cap-add setuid \
	--volume nextcloud_app2:/var/www/html \
	--volume nextcloud_apps2:/var/www/html/custom_apps \
	--volume nextcloud_config2:/var/www/html/config \
	--volume nextcloud_data2:/var/www/html/data \
	--network postgresql \
	--name $w \
	--env POSTGRES_DB=nextcloud \
	--env POSTGRES_USER=nextcloud \
	--env POSTGRES_PASSWORD="${POSTGRES_PASSWORD=?}" \
	--env POSTGRES_HOST=postgresql \
	--env NEXTCLOUD_ADMIN_USER=slmin \
	--env NEXTCLOUD_ADMIN_PASSWORD="${NEXTCLOUD_ADMIN_PASSWORD?}" \
        --memory 2048M \
        --memory-swap 2048M \
	--restart always \
	$w:$version

The output of your Apache/nginx/system log in /var/log/____:

=> Searching for scripts (*.sh) to run, located in the folder: /docker-entrypoint-hooks.d/before-starting
==> but the hook folder "before-starting" is empty, so nothing to do
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.20.0.3. Set the 'ServerName' directive globally to suppress this message
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.20.0.3. Set the 'ServerName' directive globally to suppress this message
[Sat Aug 19 21:28:11.847949 2023] [mpm_prefork:notice] [pid 1] AH00163: Apache/2.4.57 (Debian) PHP/8.2.9 configured -- resuming normal operations
[Sat Aug 19 21:28:11.850134 2023] [core:notice] [pid 1] AH00094: Command line: 'apache2 -D FOREGROUND'
78.193.22.110 - stuart [19/Aug/2023:21:28:16 +0000] "REPORT /remote.php/dav/calendars/stuart/days-off-work/ HTTP/1.0" 207 1999 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.11.0"

I added --hostname to the docker run command. That got rid of the startup warning but I still have You are accessing your instance over a secure connection, however your instance is generating insecure URLs. This most likely means that you are behind a reverse proxy and the overwrite config variables are not set correctly. How to Set up Nextcloud Docker with Nginx Reverse Proxy gave me some hints on how to configure nginx but I guess that I haven’t got it 100% right.

version=27 # only increase versions one at a time
# may need to add cap ac_override chown when upgrading
#drop="--cap-add=dac_override --cap-add=chown"
docker pull $w:$version
docker run \
	--hostname nextcloud.pook.it \
	--detach \
	--cap-drop=all \
	$drop \
	--cap-add net_bind_service \
	--cap-add=dac_override \
	--cap-add setgid \
	--cap-add setuid \
	--volume nextcloud_app2:/var/www/html \
	--volume nextcloud_apps2:/var/www/html/custom_apps \
	--volume nextcloud_config2:/var/www/html/config \
	--volume nextcloud_data2:/var/www/html/data \
	--network postgresql \
	--name $w \
	--env POSTGRES_DB=nextcloud \
	--env POSTGRES_USER=nextcloud \
	--env POSTGRES_PASSWORD="${POSTGRES_PASSWORD=?}" \
	--env POSTGRES_HOST=postgresql \
	--env NEXTCLOUD_ADMIN_USER=slmin \
	--env NEXTCLOUD_ADMIN_PASSWORD="${NEXTCLOUD_ADMIN_PASSWORD?}" \
        --memory 2048M \
        --memory-swap 2048M \
	--restart always \
	$w:$version
+ docker logs --follow nextcloud
=> Searching for scripts (*.sh) to run, located in the folder: /docker-entrypoint-hooks.d/before-starting
==> but the hook folder "before-starting" is empty, so nothing to do
[Sun Aug 20 09:58:31.010404 2023] [mpm_prefork:notice] [pid 1] AH00163: Apache/2.4.57 (Debian) PHP/8.2.9 configured -- resuming normal operations
[Sun Aug 20 09:58:31.011572 2023] [core:notice] [pid 1] AH00094: Command line: 'apache2 -D FOREGROUND'
78.193.22.110 - - [20/Aug/2023:09:58:42 +0000] "PUT /ocs/v2.php/apps/user_status/api/v1/heartbeat?format=json HTTP/1.0" 401 1337 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/116.0"
78.193.22.110 - stuart [20/Aug/2023:09:58:41 +0000] "PROPFIND /remote.php/dav/files/stuart/ HTTP/1.0" 207 1547 "-" "Mozilla/5.0 (Linux) mirall/3.7.3git (Nextcloud, debian-6.1.0-9-amd64 ClientArchitecture: x86_64 OsArchitecture: x86_64)"

Please take a look at the official reverse proxy. As you are running behind reverse proxy you need to configure “trusted_proxies” or/and “overwrite*” parameters

I have read Nextcloud configuration Reverse proxy many times. I have also read Using the apache image behind a reverse proxy and auto configure server host and protocol but cannot eliminate the message: You are accessing your instance over a secure connection, however your instance is generating insecure URLs. This most likely means that you are behind a reverse proxy and the overwrite config variables are not set correctly. I am using a reverse proxy and I am trying to set the overwrite variables correctly. Which one is wrong?

My nginx configuration:

server {
	server_name nextcloud.pook.it;
	client_max_body_size 512M;
	include /etc/nginx/snippets/ssl-server.conf;

	location /.well-known/carddav {
	    return 301 $scheme://$host/remote.php/dav;
	}
	location /.well-known/caldav {
		return 301 $scheme://$host/remote.php/dav;
	}

	location / {
		resolver           127.0.0.11 valid=37s;
		set                $upstream nextcloud;
		proxy_pass         http://$upstream:80;
		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;

		add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
	}
}

and my docker run command:

readonly h=nextcloud.pook.it
docker run \
	--hostname $h \
	--detach \
	--cap-drop=all \
	$drop \
	--cap-add net_bind_service \
	--cap-add=dac_override \
	--cap-add setgid \
	--cap-add setuid \
	--volume nextcloud_app2:/var/www/html \
	--volume nextcloud_apps2:/var/www/html/custom_apps \
	--volume nextcloud_config2:/var/www/html/config \
	--volume nextcloud_data2:/var/www/html/data \
	--network postgresql \
	--name nextcloud \
	--env POSTGRES_DB=nextcloud \
	--env POSTGRES_USER=nextcloud \
	--env POSTGRES_PASSWORD="${POSTGRES_PASSWORD=?}" \
	--env POSTGRES_HOST=postgresql \
	--env NEXTCLOUD_ADMIN_USER="$admin" \
	--env NEXTCLOUD_ADMIN_PASSWORD="${NEXTCLOUD_ADMIN_PASSWORD?}" \
	--env TRUSTED_PROXIES='10.0.0.0/8 172.16.0.0/12 192.168.42.2/16' \
	--env OVERWRITEHOST="$h" \
	--env OVERWRITEPROTOCOL=https \
	--env OVERWRITECLIURL="https://$h/" \
	--env OVERWRITEWEBROOT=/ \
        --memory 2048M \
        --memory-swap 2048M \
	--restart always \
	nextcloud:$version

this looks right already. OVERWRITEWEBROOT in not required unless you use specific webroot e.g. https://my.cloud.tld/nextcloud

Please be aware the config is build on the first container start - once you created the config using wrong environment variables changes in container ENV don’t change the config - you must adjust the settings “traditionally” by editing nextcloud_config2/config.php or using occ command e.g. docker exec --user www-data nextcloud php occ config:system:get overwritehost

Here are more details of the script that I use to restart my Nextcloud server. Unless I mistaken I always destroy the container when restarting Nextcloud so the changes to configuration should be taken into account at each restart … unless the configuration is stored in /var/www/html/config! (Which is of course the case and contains a bad overwrite.cli.url.) Should /var/www/html/config be in a persistent volume or can it be regenerated using the environment variable at every container restart?

docker stop nextcloud || true
readonly w=nextcloud
docker rm nextcloud || true
version=27 # only increase versions one at a time
#drop="--cap-add=dac_override --cap-add=chown"
docker pull nextcloud:$version
readonly h=nextcloud.pook.it
docker run \
	--hostname $h \
	--detach \
	--cap-drop=all \
	$drop \
	--cap-add net_bind_service \
	--cap-add=dac_override \
	--cap-add setgid \
	--cap-add setuid \
	--volume nextcloud_app2:/var/www/html \
	--volume nextcloud_apps2:/var/www/html/custom_apps \
	--volume nextcloud_config2:/var/www/html/config \
	--volume nextcloud_data2:/var/www/html/data \
	--network postgresql \
	--name nextcloud \
	--env POSTGRES_DB=nextcloud \
	--env POSTGRES_USER=nextcloud \
	--env POSTGRES_PASSWORD="${POSTGRES_PASSWORD=?}" \
	--env POSTGRES_HOST=postgresql \
	--env NEXTCLOUD_ADMIN_USER="$admin" \
	--env NEXTCLOUD_ADMIN_PASSWORD="${NEXTCLOUD_ADMIN_PASSWORD?}" \
	--env TRUSTED_PROXIES='10.0.0.0/8 172.16.0.0/12 192.168.42.2/16' \
	--env OVERWRITEHOST="$h" \
	--env OVERWRITEPROTOCOL=https \
	--env OVERWRITECLIURL="https://$h/" \
	--env OVERWRITEWEBROOT=/ \
        --memory 2048M \
        --memory-swap 2048M \
	--restart always \
	nextcloud:$version

it depends on your demands. Personally I tend to persist the config as not everything can be configured using ENV variables. AFAIK this is recommended by the docs. I didn’t check but could become catastrophic fail if SECRETs like encryption master keys is stored in config.php which is recreated at some point…

At the moment you persist the config - if you choose to re-create the config from scratch every time please test all you use cases very well.

/var/www/html/config contains things like instanceid, passwordsalt, and secret so they should be persisted I guess. I cannot understand how to use php occ config:system:set to set overwrite.cli.url. Can you please show me the exact command? I have tried

www-data@nextcloud:~/html$ php occ config:system:set 'overwrite.cli.url' https://nextcloud.pook.it
System config value overwrite.cli.url => https://nextcloud.pook.it set to empty string
www-data@nextcloud:~/html$ grep -C 4 overwrite.cli.url  /var/www/html/config/config.php 
  ),
  'datadirectory' => '/var/www/html/data',
  'dbtype' => 'pgsql',
  'version' => '27.0.2.1',
  'overwrite.cli.url' => 
  array (
    'https://nextcloud.pook.it' => '',
  ),
  'dbname' => 'nextcloud',
www-data@nextcloud:~/html$ php  occ config:system:get 'overwrite.cli.url'
https://nextcloud.pook.it: 

but that does not seem correct as none of the examples I have seen show overwrite.cli.url as an array.

The example 'overwrite.cli.url' => 'https://domain.tld/, in Reverse proxy is missing a quote.

My configuration is getting worse as I now have three errors:

  • Your web server is not yet properly set up to allow file synchronisation, because the WebDAV interface seems to be broken.

  • Please make sure to set the “overwrite.cli.url” option in your config.php file to the URL that your users mainly use to access this Nextcloud. Suggestion: “http://nextcloud.pook.it”. Otherwise there might be problems with the URL generated via cron. (It is possible however that the suggested URL is not the URL that your users mainly use to access this Nextcloud. Best is to double check this just in case.)

  • You are accessing your instance over a secure connection, however your instance is generating insecure URLs. This most likely means that you are behind a reverse proxy and the overwrite config variables are not set correctly. Please read the documentation page about this :arrow_upper_right:.

this is working get/set command for Docker container (adopt container name)

docker exec --user www-data nextcloud-app php occ config:system:get overwrite.cli.url
docker exec --user www-data nextcloud-app php occ config:system:set overwrite.cli.url --value=https://cloud.mydomain

btw: if you persist config files - you can stop containers, edit config files using local editor and start containers again… this is not my preferred way to do so but if I can’t figure out the occ syntax it a good way to go.

I was missing a good read of Config commands. I no longer have any red or yellow warnings under Security & setup warnings. Many thanks for your help.

I do not understand why I need overwriteprotocol. I thought that Nextcloud would use X-Forwarded-Proto from the trusted proxy.

I read Keep in mind that once set, removing these environment variables won’t remove these values from the configuration file, due to how Nextcloud merges configuration files together. I seems to me that these variables are only used when /var/www/html/config is first created. Not only does removing one of these not have any effect, changing one doesn’t either.

I wonder why I have to set trusted_domains given:

www-data@nextcloud:~/html$ hostname
nextcloud.pook.it

My working Netxcloud configuration:

www-data@nextcloud:~/html$ /var/www/html/config/public 
+ sed -e /instanceid/d -e /password/d -e /secret/d /var/www/html/config/config.php
<?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,
    ),
  ),
  'datadirectory' => '/var/www/html/data',
  'dbtype' => 'pgsql',
  'version' => '27.0.2.1',
  'dbname' => 'nextcloud',
  'dbhost' => 'postgresql',
  'dbport' => '',
  'dbtableprefix' => '',
  'dbuser' => 'nextcloud',
  'installed' => true,
  'loglevel' => 2,
  'maintenance' => false,
  'theme' => '',
  'overwrite.cli.url' => 'https://nextcloud.pook.it',
  'trusted_domains' => 
  array (
    0 => 'nextcloud.pook.it',
  ),
  'overwriteprotocol' => 'https',
  'trusted_proxies' => 
  array (
    0 => '192.168.42.2',
  ),
);

and my nginx reverse proxy configuration

$ sed -e 's/#.*//' conf/sites-enabled/nextcloud.conf
server {
	server_name nextcloud.pook.it;
	client_max_body_size 512M;
	include /etc/nginx/snippets/ssl-server.conf;

	location /.well-known/carddav { 
	    return 301 $scheme://$host/remote.php/dav;
	}
	location /.well-known/caldav {
		return 301 $scheme://$host/remote.php/dav;
	}

	location / {
		resolver           127.0.0.11 valid=37s;
		set                $upstream nextcloud;
		proxy_pass         http://$upstream:80;
		proxy_set_header   Host $host;
		proxy_set_header   X-Real-IP $remote_addr;
		proxy_set_header   X-Forwarded-Host $host;
		proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header   X-Forwarded-Proto https;

		add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"; 
	}
}
1 Like

I would expect this as well. but I never find motivation to look why this doesn’t (always) work as documented. “right” config works for me…