Caddy 1.0.4 | Nextcloud(nginx) | /nextcloud/ subfolder | leads to 502 Bad Gateway

1. My Caddy version (caddy -version):

1.0.4

2. How I run Caddy:

a. System environment:

Debian 10 Buster (RaspberryPi 4 4GB)

b. Command:

caddy -ca https://acme-staging-v02.api.letsencrypt.org/directory --conf /etc/caddy/Caddyfile

Info: letsencrypt Staging used for testing purposes till it works.

c. Service/unit/compose file:

paste full file contents here

d. My complete Caddyfile:

nextcloud.mydomain.com {
    tls    my@email.com
	root   /var/www/nextcloud
	log    /var/log/nextcloud_access.log
	errors /var/log/nextcloud_errors.log

	fastcgi / 127.0.0.1:9000 php {
		env PATH /bin
		env modHeadersAvailable true
		env front_controller_active true
		connect_timeout 60s
		read_timeout 3600s
		send_timeout 300s
	}

	header / {
		Strict-Transport-Security		"max-age=15768000;"
		X-Content-Type-Options			"nosniff"
		X-XSS-Protection			"1; mode=block"
		X-Robots-Tag				"none"
		X-Download-Options			"noopen"
		X-Permitted-Cross-Domain-Policies	"none"
		Referrer-Policy				"no-referrer"
	}

	header /core/fonts {
		Cache-Control				"max-age=604800"
	}

	# checks for images
	rewrite {
		ext .png .html .ttf .ico .jpg .jpeg .css .js .woff .woff2 .svg .gif .map
		r ^/index.php/.*$
		to /{1} /index.php?{query}
	}
	
	rewrite {
                r ^/\.well-known/host-meta$
                to /public.php?service=host-meta&{query}
        }
	rewrite {
                r ^/\.well-known/host-meta\.json$
                to /public.php?service=host-meta-json&{query}
        }
	rewrite {
                r ^/\.well-known/webfinger$
                to /public.php?service=webfinger&{query}
        }

	rewrite {
		r ^/index.php/.*$
		to /index.php?{query}
	}

	rewrite / {
		if {path} not_starts_with /remote.php
		if {path} not_starts_with /public.php
		ext .png .html .ttf .ico .jpg .jpeg .css .js .woff .woff2 .svg .gif .map .html .ttf 
		r ^/(.*)$
		to /{1} /index.php{uri}
	}

	rewrite / {
		if {path} not /core/img/favicon.ico
		if {path} not /core/img/manifest.json
		if {path} not_starts_with /remote.php
		if {path} not_starts_with /public.php
		if {path} not_starts_with /cron.php
		if {path} not_starts_with /core/ajax/update.php
		if {path} not_starts_with /status.php
		if {path} not_starts_with /ocs/v1.php
		if {path} not_starts_with /ocs/v2.php
		if {path} not /robots.txt
		if {path} not_starts_with /updater/
		if {path} not_starts_with /ocs-provider/
		if {path} not_starts_with /ocm-provider/ 
		if {path} not_starts_with /.well-known/
		to /index.php{uri}
	}

	# client support (e.g. os x calendar / contacts)
	redir /.well-known/carddav /remote.php/carddav 301
	redir /.well-known/caldav /remote.php/caldav 301

	# remove trailing / as it causes errors with php-fpm
	rewrite {
		r ^/remote.php/(webdav|caldav|carddav|dav)(\/?)(\/?)$
		to /remote.php/{1}
	}

	rewrite {
		r ^/remote.php/(webdav|caldav|carddav|dav)/(.+?)(\/?)(\/?)$
		to /remote.php/{1}/{2}
	}

	rewrite {
		r ^/public.php/(dav|webdav|caldav|carddav)(\/?)(\/?)$
		to /public.php/{1}
	}

	rewrite {
		r ^/public.php/(dav|webdav|caldav|carddav)/(.+)(\/?)(\/?)$
		to /public.php/{1}/{2}
	}

	# .htaccess / data / config / ... shouldn't be accessible from outside
	status 404 {
		/.htaccess
		/data
		/config
		/db_structure
		/.xml
		/README
		/3rdparty
		/lib
		/templates
		/occ
		/console.php
	}

}

3. The problem I’m having:

Hi there caddy community.

I’m in the process of setting up some services on my Server where some of them should be offered to the “interwebs”.

For the sake of Security I want to run a reverse Proxy in front of all services running on the same machine where all the services (natively and also in docker containers) are running.

I am running nextcloud over nginx at port 8080 because the reverse proxy, in this case caddy, needs the port 80 and 443. Nextcloud is accessed internally through http://192.168.1.100:8080/nextcloud. On the system nextcloud is installed under /var/www/nextcloud/ .

Now I want the following:
Accessing the internal nextcloud over nextcloud.mydomain.com .

I installed the caddy service with following command:
curl https://getcaddy.com | bash -s personal http.cache,http.cgi,http.forwardproxy,http.ipfilter,http.nobots,http.permission,http.realip

I have found a nextcloud Caddyfile Configuration example here:
https://github.com/caddyserver/examples/tree/master/nextcloud

So my Caddyfile looks like shown above.

I then run caddy with the Caddyfile but then when I access nextcloud.mydomain.com I always get 502 Bad Gateway .

Other services accessed directly by a Port (and no “subfolder/path” because they are running their own webserver) are accessible through caddy through the various subdomains I’ve set up.

I also tried it with traefik, had gone through many tutorials and configuration iterations but traefik isn’t routing propperly and it didn’t gave me consistent results. So thats because I searched for an alternative which handles also the LetsEncrypt certificates and that lead me to caddy.

I am running caddy 1.0.4.

I browsed here in the Forums for any hints which could lead to resolve my issue but nothing found wich could have helped.

Would be really glad to get it going. Any help is welcome.

Thank you very much in advance and have a nice weekend! :wink:

4. Error messages and/or full log output:

502 Bad Gateway (when trying to load nextcloud.mydomain.com)

5. What I already tried:

I tried to formward/route to othe services which are running on the server baremetal and also in docker containers accessed directly over the corresponding Port (without any subfolder like with nextcloud) of the services and they are routed correctly over caddy. Only nextcloud with its subfolder is not running propperly.

6. Links to relevant resources:

Nextcloud Caddyfile Example: https://github.com/caddyserver/examples/tree/master/nextcloud
Tutorial I’ve followed: https://www.addictivetips.com/ubuntu-linux-tips/install-the-caddy-web-server-on-linux/
Installation Comand: curl https://getcaddy.com | bash -s personal http.cache,http.cgi,http.forwardproxy,http.ipfilter,http.nobots,http.permission,http.realip
Run Command:caddy -ca https://acme-staging-v02.api.letsencrypt.org/directory --conf /etc/caddy/Caddyfile

1 Like

I think you issue in particular is this:

fastcgi / 127.0.0.1:9000 php

I think the 502s are happening because Caddy can’t connect to PHP-FPM on port 9000.

Do you know if you’re running PHP-FPM on your server?

2 Likes

The error is where francislavoie said. The fastcgi line makes caddy act as a fastcgi webserver. But that is already handled by nginx in your case.
Either remove nginx (then you also need the php-fpm version of docker) or change the fastcgi line to proxy / nginx:80

1 Like

Hi there!

Thank you very much vor your help.
Indeed when I list all listening ports on the server there is no fastcgi listening on Port 9000. One look at phpinfo.php shows that PHP-FPM/fcgi is active/enabled and used, but not over any port. As @besendorf said, this is most likely handled by nginx.

I replaced then the fastcgi block in the caddy file with the line proxy / nginx:8080 as @besendorf (scheint wohl ein ein ziemlich sauberes Dorf zu sein! :slight_smile: ) suggested but I have the same issue with bad gateway.

I looked then in /var/log/nextcloud_errors.log for any errors and this is what I get:

root@DietPi4:~# cat /var/log/nextcloud_errors.log 
2020/01/31 11:20:46 [ERROR 502 /index.php/] dial tcp: lookup nginx on 192.168.5.1:53: no such host
2020/01/31 11:20:46 [ERROR 502 /index.php/favicon.ico] dial tcp: lookup nginx on 192.168.5.1:53: no such host
2020/01/31 11:22:53 [ERROR 502 /index.php/] dial tcp: lookup nginx on 192.168.5.1:53: no such host
2020/01/31 11:22:53 [ERROR 502 /index.php/favicon.ico] dial tcp: lookup nginx on 192.168.5.1:53: no such host

.

So it seems that caddy is trying to reach nginx on Port 53 on my Gateway/Router instead on the server itself.

There is no line in the Caddyfile where I have put the IP of my Router/Gateway in. So it seems that caddy is trying to reach the nginx Server on the DNS-Server Port of my Router. That is some odd behavior. Or did I miss here something?!

Have a nice weekend and thank you very much for your help! :slight_smile:

If nginx is running on the same host, change this to:
proxy / localhost:8080

2 Likes

Thank you @Mohammed90 .

I changed the whole fcgi Block to the line
proxy / localhost:8080
you provided. Now I am not getting a bad gateway error anymore but a 404 Not Found Error from nginx.

The Logs show the following:

# cat /var/log/nextcloud_errors.log 
2020/01/31 12:40:21 [ERROR 499 /index.php/favicon.ico] context canceled
2020/01/31 12:40:57 [ERROR 499 /index.php/favicon.ico] context canceled
2020/01/31 12:41:02 [ERROR 499 /index.php/favicon.ico] context canceled
2020/01/31 12:41:15 [ERROR 499 /index.php/favicon.ico] context canceled
2020/01/31 12:46:46 [ERROR 499 /index.php/favicon.ico] context canceled
# cat /var/log/nextcloud_access.log
2020/01/31 12:39:48 87.122.250.47 - - [31/Jan/2020:12:39:48 +0100] "GET / HTTP/2.0" 404 162
2020/01/31 12:39:48 87.122.250.47 - - [31/Jan/2020:12:39:48 +0100] "GET /favicon.ico HTTP/2.0" 404 162
2020/01/31 12:40:21 87.122.250.47 - - [31/Jan/2020:12:40:21 +0100] "GET / HTTP/2.0" 404 162
2020/01/31 12:40:21 87.122.250.47 - - [31/Jan/2020:12:40:21 +0100] "GET /favicon.ico HTTP/2.0" 499 5
2020/01/31 12:40:57 87.122.250.47 - - [31/Jan/2020:12:40:57 +0100] "GET / HTTP/2.0" 404 162
2020/01/31 12:40:57 87.122.250.47 - - [31/Jan/2020:12:40:57 +0100] "GET /favicon.ico HTTP/2.0" 499 5
2020/01/31 12:41:02 87.122.250.47 - - [31/Jan/2020:12:41:02 +0100] "GET / HTTP/2.0" 404 162
2020/01/31 12:41:02 87.122.250.47 - - [31/Jan/2020:12:41:02 +0100] "GET /favicon.ico HTTP/2.0" 499 5
2020/01/31 12:41:15 87.122.250.47 - - [31/Jan/2020:12:41:15 +0100] "GET / HTTP/2.0" 404 162
2020/01/31 12:41:15 87.122.250.47 - - [31/Jan/2020:12:41:15 +0100] "GET /favicon.ico HTTP/2.0" 499 5
2020/01/31 12:43:01 87.122.250.47 - - [31/Jan/2020:12:43:01 +0100] "GET / HTTP/2.0" 302 0
2020/01/31 12:46:46 87.122.250.47 - - [31/Jan/2020:12:46:46 +0100] "GET / HTTP/2.0" 404 162
2020/01/31 12:46:46 87.122.250.47 - - [31/Jan/2020:12:46:46 +0100] "GET /favicon.ico HTTP/2.0" 499 5

I think we are getting closer to resolving the issue. I think it’s not handling the root folder /var/www/nextcloud/ propperly?!

Thank you again for your kind help. Wish all of you a nice weekend! :slight_smile:

At this point, I don’t think you need root nor all the rewrites and redirs because fastcgi is handled by nginx, not Caddy. Try this:

proxy / localhost:8080 {
    transparent
}
1 Like

Hi there.

Thank you @Mohammed90 for your help. I tried the suggested but I couldn’t get the nextcloud subfolder working with it. nginx was accessible but due to the fact that nextlcoud is in a subfolder in /var/www/ and handled by nginx as such I was not able to use your lines to get it working.

Either I need to configure nginx in such a way that the subfolder is obfuscated through a domain or I need to get caddy working so it is serving the nextcloud through its webserver. Or I have to get fastcgi binding to a Port so it is accessible through the port.

I searched today again through the web regarding caddy serving websites which are accessed through a subfolder in /var/www/ . I found this site: https://raphaelkabo.com/blog/posts/caddy-wordpress-subdirectory/

There he mentions how to get caddy working with Wordpress in a subfolder. In the config Example he provides fastcgi binds to the php-fpm Socket file.
So I thought this could be my solution. I used the whole Caddy Configuration whic I posted in the first post but instead of using
fastcgi / 127.0.0.1:9000 php i put in the path to the php fpm sock File which in my case is located under /var/run/php/php7.3-fpm.sock . So the caddyfile looks now like this:

nextcloud.mydomain.com {
    tls    my@email.com
	root   /var/www/nextcloud
	log    /var/log/nextcloud_access.log
	errors /var/log/nextcloud_errors.log

	fastcgi / /var/run/php/php7.3-fpm.sock php {
		env PATH /bin
		env modHeadersAvailable true
		env front_controller_active true
		connect_timeout 60s
		read_timeout 3600s
		send_timeout 300s
	}

	header / {
		Strict-Transport-Security		"max-age=15768000;"
		X-Content-Type-Options			"nosniff"
		X-XSS-Protection			"1; mode=block"
		X-Robots-Tag				"none"
		X-Download-Options			"noopen"
		X-Permitted-Cross-Domain-Policies	"none"
		Referrer-Policy				"no-referrer"
	}

	header /core/fonts {
		Cache-Control				"max-age=604800"
	}

	# checks for images
	rewrite {
		ext .png .html .ttf .ico .jpg .jpeg .css .js .woff .woff2 .svg .gif .map
		r ^/index.php/.*$
		to /{1} /index.php?{query}
	}
	
	rewrite {
                r ^/\.well-known/host-meta$
                to /public.php?service=host-meta&{query}
        }
	rewrite {
                r ^/\.well-known/host-meta\.json$
                to /public.php?service=host-meta-json&{query}
        }
	rewrite {
                r ^/\.well-known/webfinger$
                to /public.php?service=webfinger&{query}
        }

	rewrite {
		r ^/index.php/.*$
		to /index.php?{query}
	}

	rewrite / {
		if {path} not_starts_with /remote.php
		if {path} not_starts_with /public.php
		ext .png .html .ttf .ico .jpg .jpeg .css .js .woff .woff2 .svg .gif .map .html .ttf 
		r ^/(.*)$
		to /{1} /index.php{uri}
	}

	rewrite / {
		if {path} not /core/img/favicon.ico
		if {path} not /core/img/manifest.json
		if {path} not_starts_with /remote.php
		if {path} not_starts_with /public.php
		if {path} not_starts_with /cron.php
		if {path} not_starts_with /core/ajax/update.php
		if {path} not_starts_with /status.php
		if {path} not_starts_with /ocs/v1.php
		if {path} not_starts_with /ocs/v2.php
		if {path} not /robots.txt
		if {path} not_starts_with /updater/
		if {path} not_starts_with /ocs-provider/
		if {path} not_starts_with /ocm-provider/ 
		if {path} not_starts_with /.well-known/
		to /index.php{uri}
	}

	# client support (e.g. os x calendar / contacts)
	redir /.well-known/carddav /remote.php/carddav 301
	redir /.well-known/caldav /remote.php/caldav 301

	# remove trailing / as it causes errors with php-fpm
	rewrite {
		r ^/remote.php/(webdav|caldav|carddav|dav)(\/?)(\/?)$
		to /remote.php/{1}
	}

	rewrite {
		r ^/remote.php/(webdav|caldav|carddav|dav)/(.+?)(\/?)(\/?)$
		to /remote.php/{1}/{2}
	}

	rewrite {
		r ^/public.php/(dav|webdav|caldav|carddav)(\/?)(\/?)$
		to /public.php/{1}
	}

	rewrite {
		r ^/public.php/(dav|webdav|caldav|carddav)/(.+)(\/?)(\/?)$
		to /public.php/{1}/{2}
	}

	# .htaccess / data / config / ... shouldn't be accessible from outside
	status 404 {
		/.htaccess
		/data
		/config
		/db_structure
		/.xml
		/README
		/3rdparty
		/lib
		/templates
		/occ
		/console.php
	}

}

And now when accessing nextcloud.mydomain.com the nextcloud Login page loads how it should, I am able to access the files, share the files and also access the nextcloud server through the Smartphone Apps.

Man, I can not thank you enough for pointing out my Problem and help me to get to the solution! Still need to test it thoroughly but for now it seems working propperly!
Now I still need to understand the config in its entirety but its working now.

Hope this helps also others which are struggling getting nextxloud working with caddy which is served through a subfolder.

Thank you very much again and have a nice weekend.

1 Like

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