Closed zilexa closed 3 years ago
Generally the best approach is to just use a subdomain for each of those apps. Many apps were just not designed to be run in a subpath, and it's not worth going down the rabbithole of trying to replace parts of the responses to work around it.
Also FYI you can use handle_path
instead of route
here, which has implicit strip_prefix
behaviour - saves you a line. https://caddyserver.com/docs/caddyfile/directives/handle_path
Ha, now I have funny behaviour. With 2 containers adjusted:
labels:
caddy: $DOMAIN
caddy.handle_path: /firefoxsync
caddy.reverse_proxy: "{{upstreams 5000}}"
caddy.tls: $EMAIL
and:
labels:
caddy: $DOMAIN
caddy.handle_path: /firefoxsync
caddy.reverse_proxy: "{{upstreams 5000}}"
caddy.tls: $EMAIL
Now when I go to https://$DOMAIN/firefoxsync
I get the Syncthing webUI (fully working though).
It also fully works at https://$DOMAIN/syncthing
.
I tried to isolate caddy configs as in your example caddy_0
for all labels of the first container, caddy_1
for all labels of the second container etc. but now, /syncthing works, all others like /firefoxsync also load syncthing but don't load the full page.
I am trying to switch to subfolders completely from a security perspective: obscuring my exposed services, by not having a public subdomain. Perhaps it's just a nice-to-have, but at least to bot will scan any service, as there is nothing runnning on https://mydomain.tld or subdomains.
You still need the *
on the matcher, and reverse_proxy
needs to be inside of handle_path
.
I am trying to switch to subfolders completely from a security perspective: obscuring my exposed services, by not having a public subdomain. Perhaps it's just a nice-to-have, but at least to bot will scan any service, as there is nothing runnning on mydomain.tld or subdomains.
Frankly, security by obscurity is a bit of a myth. You're not gonna gain much from that. Just make sure people have proper passwords for your services and make sure you keep things updated, and you'll be fine. Don't overcomplicate it.
Thanks, now I have a few working as long as I use a /
at the end:
I see now why everyone just sticks to subdomains!
What is strange though: in Portainer, the log, shows a caddy file that has several labels that belong to one of the services, nested higher in the hierarchy. I am trying to copy the caddyfile from the log to show you.
Thanks, now I have a few working as long as I use a / at the end:
Just use a matcher like /firefoxsync*
Thanks it works without slash now except for syncthing webui. The remaining question I have. With this in my Compose:
Should the Caddy file look like this? Labels for onlyoffice or bitwarden for example are not nested within, this means some labels will be applied to all. This probably makes sense as now I do everything via a single domain:
services:
firefox:
(...)
labels:
caddy_1: $DOMAIN
caddy_1.handle_path: /firefoxsync*
caddy_1.handle_path.reverse_proxy: "{{upstreams 5000}}"
caddy_1.tls: $EMAIL
bitwarden:
(...)
labels:
caddy_2: $DOMAIN
caddy_2.handle_path: /bitwarden*
caddy_2.handle_path.reverse_proxy: "{{upstreams 80}}"
# caddy2.handle_path.reverse_proxy_2: "/notifications/hub/negotiate {{upstreams 80}}"
# caddy2.handle_path.reverse_proxy_3: "/notifications/hub {{upstreams 3012}}"
caddy_2.tls: $EMAIL
caddy_2.encode: gzip
caddy_2.header.X-XSS-Protection: '"1; mode=block;"'
caddy_2.header.X-Frame-Options: "DENY"
caddy_2.header.X-Content-Type-Options: "none"
syncthing:
(...)
labels:
caddy_3: $DOMAIN
caddy_3.handle_path: /syncthing*
caddy_3.handle_path.reverse_proxy: "{{upstreams 8384}}"
caddy_3.tls: $EMAIL
onlyoffice:
(...)
labels:
caddy_5: $DOMAIN
caddy_5.handle_path: /office*
caddy_5.handle_path.reverse_proxy: "{{upstreams 80}}"
caddy_5.tls: $EMAIL
caddy_5.file_server: ""
caddy_5.encode: gzip
caddy_5.header.X-Content-Type-Options: "nosniff"
Caddyfile from log:
mydomain.tld {
encode gzip
file_server
handle_path /bitwarden* {
reverse_proxy 172.26.0.3:80
}
handle_path /firefoxsync* {
reverse_proxy 172.26.0.4:5000
}
handle_path /office* {
reverse_proxy 172.26.0.6:80
}
handle_path /syncthing* {
reverse_proxy 172.26.0.5:8384
}
header {
X-Content-Type-Options none
X-Content-Type-Options nosniff
X-Frame-Options DENY
X-XSS-Protection "1; mode=block;"
}
tls mydomain@mydomain.tld
}
That's correct. If you want header
only for that one site, then you should put them inside handle_path
. And remove file_server
, it's probably not useful for you.
This seems resolved (see https://caddy.community/t/classic-subfolder-issues-i-read-the-wiki/11935), so I'll close it.
The documentation suggests the following to proxy domain path (mydomain.tld/path) to container root:
This works (tested it on firefox-sync server as the container is not very picky, does not have a webUI).
Now I tested other containers: Syncthing webui, OnlyOffice Documentserver and Bitwarden_rs. They do not work.. syncthing gives me a plain text version of the webUI, Bitwarden_rs only shows the plain text word "bitwarden" and onlyoffice redirects from mydomain.tld/office to mydomain.tld/welcome.
These containers probably do not support running from a subfolder. Is there a way to force them to work?
I noticed: Caddy wiki has an article: https://caddy.community/t/the-subfolder-problem-or-why-cant-i-reverse-proxy-my-app-into-a-subfolder/8575 Suggesting the use of
header Location
combined with reverse proxy or to use replace_response. Unfortunately, no examples are provided, documentation is quite limited (I really prefer yours). Can you perhaps point me in the right direction to make this work?