Need help configuring Caddy with Nextcloud and Notify Push

Support intro

Sorry to hear you’re facing problems. :slightly_frowning_face:

The community help forum (help.nextcloud.com) is for home and non-enterprise users. Support is provided by other community members on a best effort / “as available” basis. All of those responding are volunteering their time to help you.

If you’re using Nextcloud in a business/critical setting, paid and SLA-based support services can be accessed via portal.nextcloud.com where Nextcloud engineers can help ensure your business keeps running smoothly.

Getting help

In order to help you as efficiently (and quickly!) as possible, please fill in as much of the below requested information as you can.

Before clicking submit: Please check if your query is already addressed via the following resources:

(Utilizing these existing resources is typically faster. It also helps reduce the load on our generous volunteers while elevating the signal to noise ratio of the forums otherwise arising from the same queries being posted repeatedly).

Some or all of the below information will be requested if it isn’t supplied; for fastest response please provide as much as you can. :heart:

The Basics

  • Nextcloud Server version (e.g., 29.x.x):
    • 30.0.5
  • Operating system and version (e.g., Ubuntu 24.04):
    • Official Docker FPM image
  • Web server and version (e.g, Apache 2.4.25):
    • Caddy 2
  • Reverse proxy and version _(e.g. nginx 1.27.2)
    • Caddy 2
  • PHP version (e.g, 8.3):
    • 8.2
  • Is this the first time you’ve seen this error? (Yes / No):
    • No
  • When did this problem seem to first start?
    • Ever since I installed Notify Push
  • Installation method (e.g. AlO, NCP, Bare Metal/Archive, etc.)
    • `Docker
  • Are you using CloudfIare, mod_security, or similar? (Yes / No)
    • `No

Summary of the issue you are facing:

This is basically a follow up of my comment in this Notify Push Github issue, because I thought it’s more a support request than a real problem with the app (probably).

I am trying to correctly setup the Notify Push app, so that it can be used by my clients.
Currently it seems to be half working.
If I load the Nextcloud website, it successfully makes a Websockets connection to the notify push server on wss://nc.example.de/push/ws and exchanges a few messages.
I’ve also noticed in the Websockets messages, that e.g. when I create a new file in a directory using the Desktop client, it gets a “notify_file” message.
However, it doesn’t actually reload the file list so that the this new file gets visible, but maybe that’s just how it works.

Also the metrics look fine:

./occ notify_push:metrics
Active connection count: 3
Active user count: 2
Total connection count: 6
Total database query count: 4
Events received: 15
Messages sent: 2

Nevertheless, when I execute occ notify_push:self-test on the Nextcloud container, I get an error message:

./occ notify_push:self-test
✓ redis is configured
✓ push server is receiving redis messages
✓ push server can load mount info from database
✓ push server can connect to the Nextcloud server
🗴 push server is not a trusted proxy by Nextcloud or another proxy in the chain.
  Nextcloud resolved the following client address for the test request: "<my-public-ip>" instead of the expected "1.2.3.4" test value.
  The following trusted proxies are currently configured: "172.19.0.0/16", "127.0.0.1"
  The following x-forwarded-for header was received by Nextcloud: "<my-public-ip>"
    from the following remote: <my-public-ip>

  <my-public-ip> is not a trusted as a reverse proxy by Nextcloud
  See https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/reverse_proxy_configuration.html#defining-trusted-proxies for how to add trusted proxies.

  If you're having issues getting the trusted proxy setup working, you can try bypassing any existing reverse proxy
  in your setup by setting the `NEXTCLOUD_URL` environment variable to point directly to the internal Nextcloud webserver url
  (You will still need the ip address of the push server added as trusted proxy)

My question is, what part of my Caddy/ Nextcloud configuration is wrong, that this self check doesn’t pass and how can I fix it?
And secondary, is it even necessary to fix this, or is this self-check just a false alarm, because the WS connection seems to be working (for public clients).

The problem is, that I don’t really know if I really have a reverse proxy.
Sure, I am using Caddy to proxy all the HTTPS requests to the PHP-FPM app, but it’s more something that I would see as a classical webserver.
In addition, I am using Unix sockets as much as possible, so that I don’t know if it makes sense to add the Nextcloud/ Notify Push Docker container (network 172.19.0.0/16) to my Caddy network (172.23.0.0/16) or the other way around.

Do I need to configure trusted proxies at all in my Nextcloud / Caddy configuration?
Do I need to add/ modify the “X-Forwarded-For” header in the Caddy configuration at all? IIRC it should add/forward one by default, if the IP is in the range of trusted_proxies.

Any help would be greatly appreciated, since this issue is bothering me for a really long time already.
If you are missing some logs/ configuration, feel free to ask.

Steps to replicate it (hint: details matter!):

  1. execute occ notify_push:self-test on the Nextcloud container

Web server / Reverse Proxy

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

2025/01/27 22:24:30	INFO	http.log.access	handled request	{"request": {"remote_ip": "<my-public-ip>", "remote_port": "30813", "client_ip": "<my-public-ip>", "proto": "HTTP/3.0", "method": "POST", "host": "nc.example.de", "uri": "/apps/notify_push/pre_auth", "headers": {"Accept": ["application/json, text/plain, */*"], "Accept-Encoding": ["gzip, deflate, br, zstd"], "X-Requested-With": ["XMLHttpRequest, XMLHttpRequest"], "Dnt": ["1"], "Cookie": ["REDACTED"], "Accept-Language": ["de,en-US;q=0.7,en;q=0.3"], "Origin": ["https://nc.example.de"], "Sec-Fetch-Dest": ["empty"], "Sec-Fetch-Mode": ["cors"], "User-Agent": ["Mozilla/5.0 (X11; Linux x86_64; rv:134.0) Gecko/20100101 Firefox/134.0"], "Requesttoken": ["Ko+PMsbegTHWqF+HDP741/jp+uv3+8E6TtCkHjQnHws=:GtjcZ4f1wGiy3yyxRJKpo9O7tarcrYh3YaOSe1Jzb38="], "Content-Length": ["0"], "Sec-Fetch-Site": ["same-origin"], "Alt-Used": ["nc.example.de"]}, "tls": {"resumed": false, "version": 772, "cipher_suite": 4867, "proto": "h3", "server_name": "nc.example.de"}}, "bytes_read": 0, "user_id": "", "duration": 0.054048284, "size": 32, "status": 200, "resp_headers": {"Referrer-Policy": ["no-referrer"], "Server": ["Caddy"], "Content-Disposition": ["inline; filename=\"\""], "Content-Length": ["32"], "X-Xss-Protection": ["1; mode=block"], "Strict-Transport-Security": ["max-age=31536000"], "X-Content-Type-Options": ["nosniff"], "X-Frame-Options": ["SAMEORIGIN"], "Content-Security-Policy": ["default-src 'none';base-uri 'none';manifest-src 'self';frame-ancestors 'none'"], "X-Robots-Tag": ["noindex, nofollow"], "X-Permitted-Cross-Domain-Policies": ["none"], "Date": ["Mon, 27 Jan 2025 22:24:30 GMT"], "Permissions-Policy": ["interest-cohort=()"], "Content-Type": ["text/html; charset=UTF-8"], "X-Request-Id": ["fjjrbVhtSYjtQOBEvEoO"], "Cache-Control": ["no-cache, no-store, must-revalidate"], "Feature-Policy": ["autoplay 'none';camera 'none';fullscreen 'none';geolocation 'none';microphone 'none';payment 'none'"]}}
2025/01/27 22:25:36	INFO	http.log.access	handled request	{"request": {"remote_ip": "<my-public-ip>", "remote_port": "38474", "client_ip": "<my-public-ip>", "proto": "HTTP/1.1", "method": "GET", "host": "nc.example.de", "uri": "/index.php/apps/notify_push/uid", "headers": {"Authorization": ["REDACTED"], "X-Forwarded-For": ["<my-public-ip>"], "Accept": ["*/*"]}, "tls": {"resumed": true, "version": 772, "cipher_suite": 4867, "proto": "http/1.1", "server_name": "nc.example.de"}}, "bytes_read": 0, "user_id": "", "duration": 0.065548934, "size": 16, "status": 200, "resp_headers": {"Content-Disposition": ["inline; filename=\"\""], "X-Content-Type-Options": ["nosniff"], "Cache-Control": ["no-cache, no-store, must-revalidate"], "Content-Length": ["16"], "X-Request-Id": ["Nj6um7boc1EttfCTuhcl"], "X-Frame-Options": ["SAMEORIGIN"], "X-Xss-Protection": ["1; mode=block"], "Referrer-Policy": ["no-referrer"], "Alt-Svc": ["h3=\":443\"; ma=2592000"], "Feature-Policy": ["autoplay 'none';camera 'none';fullscreen 'none';geolocation 'none';microphone 'none';payment 'none'"], "Strict-Transport-Security": ["max-age=31536000"], "X-Permitted-Cross-Domain-Policies": ["none"], "Server": ["Caddy"], "Content-Type": ["text/html; charset=UTF-8"], "Content-Security-Policy": ["default-src 'none';base-uri 'none';manifest-src 'self';frame-ancestors 'none'"], "X-Robots-Tag": ["noindex, nofollow"], "Set-Cookie": ["REDACTED"], "Permissions-Policy": ["interest-cohort=()"]}}
2025/01/27 22:30:50	INFO	http.log.access	handled request	{"request": {"remote_ip": "<my-public-ip>", "remote_port": "30810", "client_ip": "<my-public-ip>", "proto": "HTTP/3.0", "method": "POST", "host": "nc.example.de", "uri": "/apps/notify_push/pre_auth", "headers": {"Accept-Language": ["de,en-US;q=0.7,en;q=0.3"], "X-Requested-With": ["XMLHttpRequest, XMLHttpRequest"], "Requesttoken": ["nwYQgJc2O6gUY+nzvQsxI1ymSoEBc+gHR1X5Wyr9HTs=:r1FD1dYdevFwFJrF9WdgV3f0BcAqJaFKaCbPPkypbU8="], "Sec-Fetch-Mode": ["cors"], "Sec-Fetch-Site": ["same-origin"], "User-Agent": ["Mozilla/5.0 (X11; Linux x86_64; rv:134.0) Gecko/20100101 Firefox/134.0"], "Accept-Encoding": ["gzip, deflate, br, zstd"], "Accept": ["application/json, text/plain, */*"], "Dnt": ["1"], "Alt-Used": ["nc.example.de"], "Cookie": ["REDACTED"], "Content-Length": ["0"], "Origin": ["https://nc.example.de"], "Sec-Fetch-Dest": ["empty"]}, "tls": {"resumed": true, "version": 772, "cipher_suite": 4867, "proto": "h3", "server_name": "nc.example.de"}}, "bytes_read": 0, "user_id": "", "duration": 0.054329857, "size": 32, "status": 200, "resp_headers": {"X-Content-Type-Options": ["nosniff"], "Date": ["Mon, 27 Jan 2025 22:30:50 GMT"], "Content-Security-Policy": ["default-src 'none';base-uri 'none';manifest-src 'self';frame-ancestors 'none'"], "Content-Length": ["32"], "Content-Type": ["text/html; charset=UTF-8"], "Feature-Policy": ["autoplay 'none';camera 'none';fullscreen 'none';geolocation 'none';microphone 'none';payment 'none'"], "Permissions-Policy": ["interest-cohort=()"], "X-Permitted-Cross-Domain-Policies": ["none"], "Referrer-Policy": ["no-referrer"], "Server": ["Caddy"], "Content-Disposition": ["inline; filename=\"\""], "X-Request-Id": ["yB6f0dprEw98kXjxSfNo"], "Cache-Control": ["no-cache, no-store, must-revalidate"], "X-Frame-Options": ["SAMEORIGIN"], "X-Robots-Tag": ["noindex, nofollow"], "Strict-Transport-Security": ["max-age=31536000"], "X-Xss-Protection": ["1; mode=block"]}}
2025/01/27 22:37:08	INFO	http.log.access	handled request	{"request": {"remote_ip": "<my-public-ip>", "remote_port": "39326", "client_ip": "<my-public-ip>", "proto": "HTTP/1.1", "method": "GET", "host": "nc.example.de", "uri": "/index.php/apps/notify_push/test/remote", "headers": {"X-Forwarded-For": ["1.2.3.4"], "Accept": ["*/*"]}, "tls": {"resumed": true, "version": 772, "cipher_suite": 4867, "proto": "http/1.1", "server_name": "nc.example.de"}}, "bytes_read": 0, "user_id": "", "duration": 0.02161757, "size": 14, "status": 200, "resp_headers": {"X-Xss-Protection": ["1; mode=block"], "Feature-Policy": ["autoplay 'none';camera 'none';fullscreen 'none';geolocation 'none';microphone 'none';payment 'none'"], "Content-Length": ["14"], "Content-Type": ["text/html; charset=UTF-8"], "Cache-Control": ["no-cache, no-store, must-revalidate"], "Content-Disposition": ["inline; filename=\"\""], "X-Permitted-Cross-Domain-Policies": ["none"], "Permissions-Policy": ["interest-cohort=()"], "X-Robots-Tag": ["noindex, nofollow"], "Alt-Svc": ["h3=\":443\"; ma=2592000"], "Set-Cookie": ["REDACTED"], "X-Request-Id": ["GNJyVnB6SPP6FNuYynTZ"], "Referrer-Policy": ["no-referrer"], "Strict-Transport-Security": ["max-age=31536000"], "X-Frame-Options": ["SAMEORIGIN"], "Server": ["Caddy"], "Content-Security-Policy": ["default-src 'none';base-uri 'none';manifest-src 'self';frame-ancestors 'none'"], "X-Content-Type-Options": ["nosniff"]}}
2025/01/27 22:37:08	INFO	http.log.access	handled request	{"request": {"remote_ip": "<my-public-ip>", "remote_port": "39326", "client_ip": "<my-public-ip>", "proto": "HTTP/1.1", "method": "GET", "host": "nc.example.de", "uri": "/index.php/apps/notify_push/test/cookie", "headers": {"Accept": ["*/*"]}, "tls": {"resumed": true, "version": 772, "cipher_suite": 4867, "proto": "http/1.1", "server_name": "nc.example.de"}}, "bytes_read": 0, "user_id": "", "duration": 0.047174252, "size": 10, "status": 200, "resp_headers": {"Feature-Policy": ["autoplay 'none';camera 'none';fullscreen 'none';geolocation 'none';microphone 'none';payment 'none'"], "Cache-Control": ["no-cache, no-store, must-revalidate"], "Content-Type": ["application/json; charset=utf-8"], "Strict-Transport-Security": ["max-age=31536000"], "X-Content-Type-Options": ["nosniff"], "Set-Cookie": ["REDACTED"], "X-Robots-Tag": ["noindex, nofollow"], "Server": ["Caddy"], "Content-Security-Policy": ["default-src 'none';base-uri 'none';manifest-src 'self';frame-ancestors 'none'"], "X-Request-Id": ["djuNNblpkbA8agSJtX9q"], "X-Frame-Options": ["SAMEORIGIN"], "X-Permitted-Cross-Domain-Policies": ["none"], "X-Xss-Protection": ["1; mode=block"], "Referrer-Policy": ["no-referrer"], "Alt-Svc": ["h3=\":443\"; ma=2592000"], "Content-Length": ["10"], "Permissions-Policy": ["interest-cohort=()"]}}

Configuration

Nextcloud

The output of occ config:list system or similar is best, but, if not possible, the contents of your config.php file from /path/to/nextcloud is fine (make sure to remove any identifiable information!):

{
    "system": {
        "maintenance": false,
        "datadirectory": "***REMOVED SENSITIVE VALUE***",
        "htaccess.RewriteBase": "\/",
        "memcache.local": "\\OC\\Memcache\\APCu",
        "apps_paths": [
            {
                "path": "\/var\/www\/html\/apps",
                "url": "\/apps",
                "writable": false
            },
            {
                "path": "\/var\/www\/html\/custom_apps",
                "url": "\/custom_apps",
                "writable": true
            }
        ],
        "instanceid": "***REMOVED SENSITIVE VALUE***",
        "passwordsalt": "***REMOVED SENSITIVE VALUE***",
        "secret": "***REMOVED SENSITIVE VALUE***",
        "trusted_domains": [
            "nc.example.de",
        ],
        "trusted_proxies": array (
              0 => '172.19.0.0/16', # actually no idea what value would make sense here
              1 => '127.0.0.1',
            ),
        "overwrite.cli.url": "https:\/\/nc.example.de",
        "overwriteprotocol": "https",
        "dbtype": "mysql",
        "version": "30.0.5.1",
        "dbname": "***REMOVED SENSITIVE VALUE***",
        "dbhost": "***REMOVED SENSITIVE VALUE***",
        "dbtableprefix": "oc_",
        "mysql.utf8mb4": true,
        "dbuser": "***REMOVED SENSITIVE VALUE***",
        "dbpassword": "***REMOVED SENSITIVE VALUE***",
        "installed": true,
        "mail_smtpmode": "smtp",
        "mail_sendmailmode": "smtp",
        "mail_smtphost": "***REMOVED SENSITIVE VALUE***",
        "mail_smtpport": "587",
        "mail_from_address": "***REMOVED SENSITIVE VALUE***",
        "mail_domain": "***REMOVED SENSITIVE VALUE***",
        "mail_smtpauth": 1,
        "mail_smtpauthtype": "PLAIN",
        "mail_smtpname": "***REMOVED SENSITIVE VALUE***",
        "mail_smtppassword": "***REMOVED SENSITIVE VALUE***",
        "enable_previews": true,
        "preview_max_memory": 512,
        "enabledPreviewProviders": [
            "OC\\Preview\\PNG",
            "OC\\Preview\\JPEG",
            "OC\\Preview\\GIF",
            "OC\\Preview\\BMP",
            "OC\\Preview\\XBitmap",
            "OC\\Preview\\MP3",
            "OC\\Preview\\TXT",
            "OC\\Preview\\MarkDown",
            "OC\\Preview\\OpenDocument",
            "OC\\Preview\\Krita",
            "OC\\Preview\\Imaginary",
            "OC\\Preview\\HEIC",
            "OC\\Preview\\PDF",
            "OC\\Preview\\SVG",
            "OC\\Preview\\Movie",
            "OC\\Preview\\MKV",
            "OC\\Preview\\MP4",
            "OC\\Preview\\AVI"
        ],
        "preview_imaginary_url": "***REMOVED SENSITIVE VALUE***",
        "memcache.locking": "\\OC\\Memcache\\Redis",
        "memcache.distributed": "\\OC\\Memcache\\Redis",
        "redis": {
            "host": "***REMOVED SENSITIVE VALUE***",
            "port": 6379,
            "password": "***REMOVED SENSITIVE VALUE***"
        },
        "loglevel": 2,
        "theme": "",
        "onlyoffice": {
            "verify_peer_off": true
        },
        "activity_use_cached_mountpoints": true,
        "defaultapp": "files",
        "simpleSignUpLink.shown": false,
        "default_phone_region": "DE",
        "app_install_overwrite": [
            "imageconverter",
            "previewgenerator"
        ],
        "jpeg_quality": 60,
        "preview_max_x": 2048,
        "preview_max_y": 2048,
        "log_type": "errorlog",
        "memories.vod.ffmpeg": "\/usr\/bin\/ffmpeg",
        "memories.vod.ffprobe": "\/usr\/bin\/ffprobe",
        "memories.vod.disable": false,
        "memories.vod.external": true,
        "memories.vod.bind": "",
        "memories.vod.connect": "10.26.3.12:47788",
        "memories.vod.path": "\/var\/www\/html\/custom_apps\/memories\/bin-ext\/go-vod-amd64",
        "memories.exiftool_no_local": true,
        "memories.exiftool": "\/var\/www\/html\/custom_apps\/memories\/bin-ext\/exiftool-amd64-glibc",
        "memories.vod.qf": 25,
        "maintenance_window_start": 0,
        "memories.gis_type": 1,
        "memories.db.triggers.fcu": true,
        "memories.vod.vaapi.low_power": true,
        "memories.vod.vaapi": true,
        "memories.vod.use_transpose": true
    }
}

Apps

Enabled:
  - activity: 3.0.0
  - admin_audit: 1.20.0
  - app_api: 4.0.5
  - calendar: 5.0.9
  - circles: 30.0.0
  - cloud_federation_api: 1.13.0
  - comments: 1.20.1
  - contacts: 6.1.3
  - contactsinteraction: 1.11.0
  - dashboard: 7.10.0
  - dav: 1.31.1
  - federatedfilesharing: 1.20.0
  - federation: 1.20.0
  - files: 2.2.0
  - files_downloadlimit: 3.0.0
  - files_external: 1.22.0
  - files_pdfviewer: 3.0.0
  - files_reminders: 1.3.0
  - files_retention: 1.19.0
  - files_sharing: 1.22.0
  - files_trashbin: 1.20.1
  - files_versions: 1.23.0
  - firstrunwizard: 3.0.0
  - forms: 4.3.5
  - groupfolders: 18.0.9
  - imageconverter: 2.0.4
  - lookup_server_connector: 1.18.0
  - memories: 7.4.1
  - music: 2.1.1
  - nextcloud_announcements: 2.0.0
  - notes: 4.11.0
  - notifications: 3.0.0
  - notify_push: 1.0.0
  - oauth2: 1.18.1
  - onlyoffice: 9.5.0
  - password_policy: 2.0.0
  - polls: 7.2.9
  - previewgenerator: 5.7.0
  - privacy: 2.0.0
  - provisioning_api: 1.20.0
  - qownnotesapi: 24.11.0
  - recommendations: 3.0.0
  - related_resources: 1.5.0
  - serverinfo: 2.0.0
  - settings: 1.13.0
  - sharebymail: 1.20.0
  - snappymail: 2.38.2
  - support: 2.0.0
  - survey_client: 2.0.0
  - systemtags: 1.20.0
  - tasks: 0.16.1
  - text: 4.1.0
  - theming: 2.5.0
  - twofactor_backupcodes: 1.19.0
  - twofactor_nextcloud_notification: 4.0.0
  - twofactor_totp: 12.0.0-dev
  - updatenotification: 1.20.0
  - user_status: 1.10.0
  - viewer: 3.0.0
  - weather_status: 1.10.0
  - webhook_listeners: 1.1.0-dev
  - workflowengine: 2.12.0
Disabled:
  - bruteforcesettings: 3.0.0 (installed 2.4.0)
  - cms_pico: 1.0.21 (installed 1.0.21)
  - encryption: 2.18.0
  - files_rightclick: 0.15.1 (installed 1.6.0)
  - logreader: 3.0.0 (installed 2.13.0)
  - maps: 1.5.0 (installed 1.5.0)
  - photos: 3.0.2 (installed 2.0.1)
  - suspicious_login: 8.0.0
  - user_ldap: 1.21.0

Caddyfile

# Global settings
{
	log default {
		format console {
			time_format wall
		}
	}
	servers {
		trusted_proxies static private_ranges 172.17.0.0/12 172.19.0.0/16 # Do I need this?
	}

}

nc.example.de {
	log # enables access logs
	encode zstd gzip
	root * /var/www/html

	# Rules here are all from .htaccess
	redir /.well-known/carddav /remote.php/dav 301
	redir /.well-known/caldav /remote.php/dav 301
	redir /.well-known/* /index.php{uri} 301 # Nextcloud front-controller handles routes to /.well-known
	redir /remote/* /remote.php{uri} 301

	# Secure headers, all from .htaccess except Permissions-Policy, STS and X-Powered-By
	header {
		Strict-Transport-Security max-age=31536000
		Permissions-Policy interest-cohort=()
		X-Content-Type-Options nosniff
		X-Frame-Options SAMEORIGIN
		Referrer-Policy no-referrer
		X-XSS-Protection "1; mode=block"
		X-Permitted-Cross-Domain-Policies none
		X-Robots-Tag "noindex, nofollow"
		-X-Powered-By
	}

	# Uncomment this block if you use the high speed files backend: https://github.com/nextcloud/notify_push
	handle_path /push/* {
		reverse_proxy unix//run/notify_push/notify_push.sock
		#reverse_proxy 10.26.3.11:7867
	}

	# Uncomment this block if you use onlyoffice: https://github.com/nextcloud/all-in-one/blob/main/Containers/apache/Caddyfile
	#handle_path /onlyoffice/* {
	#	reverse_proxy {$ONLYOFFICE_IP}:{$ONLYOFFICE_PORT} {
	#		header_up X-Forwarded-Host {host}/onlyoffice
	#	}
	#}

	# PicoCMS route
	#route /sites* {
	#	uri strip_prefix /sites
	#	rewrite * /index.php/apps/cms_pico/pico_proxy/{uri}
	#	reverse_proxy 10.26.3.11:8080
	#}

	# PHP block
	php_fastcgi unix//run/nextcloud/nextcloud.sock {
		root /var/www/html # This is needed because inside the container the root directory is different from the one I put in the "root" directive of this Caddyfile. If you don't change this, php-fpm will not be able to find the files to process.
		env front_controller_active true # Enable pretty urls
		env modHeadersAvailable true # Avoid sending the security headers twice
		#header_up X-Forwarded-For "{remote}, 127.0.0.1" # Do I need this?
	}

	# From .htaccess, deny access to sensible files and directories
	@forbidden {
	path /build/* /tests/* /config/* /lib/* /3rdparty/* /templates/* /data/*
		path /.* /autotest* /occ* /issue* /indie* /db_* /console*
		not path /.well-known/*
	}
	error @forbidden 401
	
	# Redirect Dav Clients
	@davclnt header_regexp User-Agent (?i)^DavClnt
	redir @davclnt /remote.php/webdav{uri} 302

	# From .htaccess, set cache for versioned static files (cache-busting)
	@immutable {
		path *.css *.js *.mjs *.svg *.gif *.png *.jpg *.ico *.wasm *.tflite
		query v=*
	}
	header @immutable Cache-Control "max-age=15778463, immutable"

	# From .htaccess, set cache for normal static files
	@static {
		path *.css *.js *.mjs *.svg *.gif *.png *.jpg *.ico *.wasm *.tflite
		not query v=*
	}
	header @static Cache-Control "max-age=15778463"

	# From .htaccess, cache fonts for 1 week
	@woff2 path *.woff2
	header @woff2 Cache-Control "max-age=604800"

	file_server
}

Caddy Compose file

services:
  caddy:
    command:
      - "caddy"
      - "run"
      - "--config"
      - "/etc/caddy/Caddyfile"
      - "--adapter"
      - "caddyfile"
    container_name: "Caddy"
    image: "caddy:2"
    ports:
      - "443:443/tcp"
      - "443:443/udp"
      - "80:80/tcp"
      - "8071:8071/tcp"
    restart: "unless-stopped"
    user: "1100:1100"
    volumes:
      - "/nfs/freenas/caddy/Caddyfile2:/etc/caddy/Caddyfile"
      - "/nfs/freenas/caddy/caddy2-config:/config"
      - "/nfs/freenas/caddy/caddy2-data:/data"
      - "/nfs/freenas/caddy/nextcloud-unix-socket:/run/nextcloud"
      - "/nfs/freenas/caddy/notify-push-unix-socket:/run/notify_push"
      - "/nfs/freenas/ncfpm:/var/www/html:ro"
    networks:
      - caddy

networks:
  caddy:
    name: caddy-network 

Nextcloud Compose file

version: '3'

services:
    app:
    container_name: nextcloudfpm
    build: 
      context: https://github.com/major-mayer/nextcloud-docker.git
    external_links:
      - Caddy
    depends_on:
      - db
    volumes:
      - /nfs/freenas/ncfpm:/var/www/html
      - /nfs/freenas/dockerfiles/nextcloud/custom-fpm.conf:/usr/local/etc/php-fpm.d/zzz-docker.conf
      - /nfs/freenas/dockerfiles/nextcloud/custom-php.ini:/usr/local/etc/php/conf.d/zzz-docker.ini
      - /nfs/freenas/caddy/nextcloud-unix-socket:/run/nextcloud
      - /nfs/freenas/dockerfiles/nextcloud/redis-session.ini:/usr/local/etc/php/conf.d/redis-session.ini
    restart: always
    user: 1100:1100
    environment:
    - REDIS_HOST=redis
    - MYSQL_HOST=db
    - REDIS_HOST_PASSWORD=XXX
    - PHP_MEMORY_LIMIT=1024M
    tmpfs: /tmp # Required for Recognize app

  notify_push:
    image: icewind1991/notify_push:latest
    container_name: nextcloud_notify_push
    restart: always
    user: 1100:1100
    depends_on:
      - app
    environment:
      - NEXTCLOUD_URL=https://nc.example.de
      - SOCKET_PATH=/run/notify_push/notify_push.sock
    volumes_from:
      - app
    volumes:
      - /nfs/freenas/caddy/notify-push-unix-socket:/run/notify_push
    command: ./notify_push /var/www/html/config/config.php

[more services...]

Nextcloud config

The below (Nextcloud config) should include your Caddy IP address (or CIDR range) since Nextcloud needs to know Caddy is behaving as a reverse proxy for notify_push:

…which I believe is 172.23.0.0/16 from what you’ve stated. It should not include 172.19.0.0/16 since there is no reverse proxy in that network.

The below (Caddyfile entry) should be removed because you do not have any reverse proxies in front of Caddy:

indicates your systems talk to each other over the internet. This is expected in case both are using public FQDN. in this case your caddy must trust your as a trusted proxy.

You could also shortcut the communication inside of your Docker system following the approach I described in Probably DNS help with NC Docker + Collabora + Wireguard tunnel. adding

will make all docker containers in network proxy to access cloud.mydomain.tld without the internet loop.

Maybe How to verify notify_push works correctly? helps with troubleshooting

Thanks a lot for your responses. They were really helpful :heart:

I finally made it, but I’m still not sure if my configuration is optimal right now.

So first I added a static subnet for the caddy-network (172.16.0.0/16) and added replaced this in the trusted_proxies array in the Nextcloud configuration (as @jtr suggested).

I also removed the trusted proxies from the Caddyfile, since I thought, yes, I don’t have any reverse proxies in front of Caddy.

Then I wanted to shortcut the communication between the Notify Push container and Caddy (as @wwe suggested), because talking over the internet when the contains actually are on the same host, indeed seems suboptimal.

My Caddy compose file now:

services:
  caddy:
[...]
    networks:
      caddy:
        aliases:
          - nc.example.com

networks:
  caddy:
    name: caddy-network
    ipam:
      driver: default
      config:
        - subnet: 172.16.0.0/16

BTW I decided to split off the Caddy configuration from my main Nextcloud compose stack, because I have other services apart from Nextcloud that are using this Caddy reverse-proxy as well.

My Nextcloud compose file:

version: '3'

services:
  app (this is the nextcloud container):
[...]
    networks:
      - caddy-network # i can probably remove this one, right?
      - default


  notify_push:
[...]
    environment:
      - NEXTCLOUD_URL=https://nc.example.com
      - SOCKET_PATH=/run/notify_push/notify_push.sock
    networks:
      - caddy-network
      - default

networks:
  caddy-network:
    external : true

I noticed that I have to add the Notify Push (and the Nextcloud?) container to the Caddy network because otherwise the shortcut won’t work.

With the new configuration I tried the self-test again, and it showed a different error message (at least something :wink: )

./occ notify_push:self-test
✓ redis is configured
✓ push server is receiving redis messages
✓ push server can load mount info from database
✓ push server can connect to the Nextcloud server
🗴 push server is not a trusted proxy by Nextcloud or another proxy in the chain.
  Nextcloud resolved the following client address for the test request: "172.16.0.4" instead of the expected "1.2.3.4" test value.
  The following trusted proxies are currently configured: "172.16.0.0/16", "127.0.0.1"
  The following x-forwarded-for header was received by Nextcloud: "172.16.0.4"
    from the following remote: 172.16.0.4

✓ All proxies in the chain appear to be trusted by Nextcloud
  One of the proxies is the chain (probably 172.16.0.4) seems to have stripped the x-forwarded-for header
  Please configure the reverse proxy at 172.16.0.4 to not strip the x-forwarded-for header

  If you're having issues getting the trusted proxy setup working, you can try bypassing any existing reverse proxy
  in your setup by setting the `NEXTCLOUD_URL` environment variable to point directly to the internal Nextcloud webserver url
  (You will still need the ip address of the push server added as trusted proxy)

172.16.0.4 is actually the IP address of the Notify Push container.

Apparently, Caddy by default strips/replaces all X-Forwarded-For headers from the request and only forwards them, if the request comes from an IP range specified in trusted_proxies.

So I added the section that I previously removed again, and et voilá the self test succeeds :partying_face:

./occ notify_push:self-test
✓ redis is configured
✓ push server is receiving redis messages
✓ push server can load mount info from database
✓ push server can connect to the Nextcloud server
✓ push server is a trusted proxy
✓ push server is running the same version as the app

So at least for the case of the self test, it seems to me as Notify Push acts as a reverse proxy in front of Caddy (my real reverse-proxy/ webserver), because the self tests adds X-Forwarded-For headers to the request.

I wonder if the configuration is okay like that?
Maybe all the containers of the Nextcloud compose stack should use the Caddy network?

1 Like

you should only connect containers exposed through Caddy to this network. there is not value to add e.g. database to the caddy network. in opposite keeping this away is more secure in case caddy becomes hacked - attacker still has no access to the DB.

Small hint - you name the caddy-network different in different stacks… while it works as long it remains the same within the stack it could confusing I would recommend use same id everywhere.

Yeah, that makes perfectly sense. Thank you very much for the confirmation and for your help.

And indeed, naming the network caddy and caddy-network is a bit confusion. I will change that.

This topic was automatically closed 8 days after the last reply. New replies are no longer allowed.