nrjdalal
(Neeraj Dalal)
March 3, 2022, 10:11pm
1
I have a project with urls like
localhost:3000/alpha/admin
localhost:3000/beta/admin
localhost:3000/charlie/admin
Where {alpha,beta,charlie} are the username identifier, as after that all functionality is same
I want a single rule that conveys
localhost:3000/{identifier} ~ {identifier}.example.com
something in order of -
subdomain.example.com {
reverse_proxy localhost:3000/subdomain
}
where subdomain is variable
or to simplify it even more
a rule that conveys
localhost:3000/first_subdirectory_before_slash is same as first_subdirectory_before_slash.example.com
Do you mean to perform a path rewrite , or do you want a redirect ? Those are two distinct things in the context of HTTP.
A redirect is when the server responds with the Location
header, telling the client “try again, but at this URL instead”.
A rewrite is an internal manipulation of the request path, before continuing to handle the request.
Caddy’s reverse_proxy
doesn’t perform rewrites itself, if that’s what you’re trying to do. You need to use the rewrite
directive instead.
If you need to redirect, then you can use the redir
directive.
2 Likes
JnAlu
(Jonardhan Aluguda)
March 4, 2022, 3:24am
3
I believe he wants to rewrite without having to repeatedly type out the rewrite rule.
So, for example for each of:
localhost:3000/alpha/admin
localhost:3000/beta/admin
localhost:3000/charlie/admin
he wants
<each>.example.com {
reverse_proxy localhost:3000/<each>
}
Such that
alpha.example.com {
reverse_proxy localhost:3000/alpha/
}
without having to actually write that down explicitly
2 Likes
nrjdalal
(Neeraj Dalal)
March 4, 2022, 3:37am
4
yes I want a rule as you described
In that case, that would be a rewrite , not a redirect . But again, it needs to be done with the rewrite
directive.
You could try this:
*.example.com {
rewrite {labels.2}{uri}
reverse_proxy localhost:3000
}
Where the {labels.2}
placeholder is the subdomain (index starting at 0 from the right-most label).
This uses a wildcard label though, which means Caddy would attempt to get a wildcard cert. That requires setting up the DNS challenge to prove to ACME issuers that you own the entire zone. You’d need a build of Caddy with the appropriate DNS plugin for your DNS provider:
Or you could set up On-Demand TLS, which doesn’t require building Caddy with a plugin, but you need to set up an ask
endpoint to prevent abuse.
3 Likes
JnAlu
(Jonardhan Aluguda)
March 4, 2022, 3:53am
6
If we know apriori that only the following subdomains are allowed:
alpha
beta
charlie
Would it be possible to serve the “ask” endpoint, say as a static file server, from within caddy itself, to satisfy the ask endpoint?
Failing which, is it possible to have an “ask” endpoint, that always returns true (for development only - while the actual “ask” endpoint is being built)?
Is there an example of how this “ask” endpoint should behave? (On-Demand TLS questions )
matt
(Matt Holt)
March 4, 2022, 4:07am
7
JnAlu:
Would it be possible to serve the “ask” endpoint, say as a static file server, from within caddy itself, to satisfy the ask endpoint?
Yes, there’s one company I know of that does this. Just create another route in your config and set the ask
endpoint to hit it.
1 Like
matt
(Matt Holt)
March 4, 2022, 4:12am
9
Yep. A matcher can help. You can also be clever with the map
directive. There are several ways to do it, likely involving placeholders since you have to read the query string’s domain
key.
1 Like
Or you could just do this:
alpha.example.com, beta.example.com, charlie.example.com {
rewrite {labels.2}{uri}
reverse_proxy localhost:3000
}
If the domains are directly listed in your config, Caddy will manage certificates for those.
Simpler and safer than On-Demand TLS, if you know the exact domains you need up-front.
2 Likes
nrjdalal
(Neeraj Dalal)
March 4, 2022, 5:42am
11
@francislavoie thank you for your suggestion
*.example.com {
rewrite {labels.2}{uri}
reverse_proxy localhost:3000
}
— end of suggestion —
does this still work if localhost:3000 has sub-directory depth like
<each>.example.com {
localhost:3000/<each>/a/b/c
}
where <each>
are the user identifiers, so a and b and c are kind of common pages but different data for them
such as if I visit alpha.example.com/a/b/c , behind the scenes it just means
localhost:3000/alpha/a/b/c
localhost:3000/caddy/caddy-is-awesome?try=it
static files are always served from localhost:3000 nonetheless
Yes, {uri}
is the entire original URI of the incoming request, including the path and query.
Btw for correctness, it should be:
rewrite /{labels.2}{uri}
With the leading slash since the label doesn’t have one, but {uri}
includes a leading slash.
No, in this case all requests would be rewritten and proxied, with that config.
1 Like
nrjdalal
(Neeraj Dalal)
March 4, 2022, 7:29am
13
Here is my Caddyfile as suggested by @francislavoie
xamyr.com {
reverse_proxy localhost:3000
}
*.xamyr.com {
rewrite {label.2}{uri}
reverse_proxy localhost:3000
}
You can try and visit (everything works here) -
https://xamyr.com/alpha/admin ~ responds with alpha
https://xamyr.com/beta/admin ~ responds with beta
https://xamyr.com/charlie/admin ~ responts with charlie
But visiting it like https://{alpha|beta|charlie}.xamyr.com/admin
is not working via provided config, one can try via (nothing works here) -
https://alpha.xamyr.com/admin
https://beta.xamyr.com/admin
https://charlie.xamyr.com/admin
*Note it is a Next.js app, and for demo purposes, structure is
/pages/alpha/admin.js
/pages/beta/admin.js
/pages/charlie/admin.js
nrjdalal
(Neeraj Dalal)
March 4, 2022, 7:33am
14
with a leading slash on config -
*.xamyr.com {
rewrite /{labels.2}{uri}
reverse_proxy localhost:3000
}
yeilds -
$ systemctl reload caddy
Job for caddy.service failed.
See "systemctl status caddy.service" and "journalctl -xe" for details.
nrjdalal:
*.xamyr.com
Like I said, this on its own will not work unless you enable the DNS challenge to get a wildcard certificate.
What’s in your logs? See here in the docs for the command to run to see your logs:
1 Like
nrjdalal
(Neeraj Dalal)
March 4, 2022, 7:52am
16
for a single domain -
xamyr.com {
reverse_proxy localhost:3000
}
alpha.xamyr.com {
rewrite {label.2}{uri}
reverse_proxy localhost:3000
}
# rewrite /{label.2}{uri} or /{labels.2}{uri) doesn't work
now site xamyr.com emits same behaviour as alpha.xamyr.com , aka -
https://xamyr.com == https://alpha.xamyr.com
https://xamyr.com/alpha/admin == https://alpha.xamyr.com/alpha/admin
desired case, doesn’t work, i.e. -
https://xamyr.com/alpha/admin != https://alpha.xamyr.com/admin
Again, what’s in your logs?
You can turn on the debug
global option to get more details in your logs. Add this at the top of your Caddyfile:
{
debug
}
1 Like
nrjdalal
(Neeraj Dalal)
March 4, 2022, 8:34am
18
@francislavoie you have been very helpful, just one thing, leaving above issue aside, here is one nginx config, please provide me its caddy equivalent if you can
# nginx.conf
{
listen 80;
server_name blog.example.com;
location / {
proxy_pass http://localhost:3000/blog$uri;
proxy_redirect off;
}
}
# caddyfile
{
... ?
}
What I gave you is the equivalent. Caddy’s reverse_proxy
does not perform rewrites itself, you need to do a separate rewrite before proxying.
1 Like
nrjdalal
(Neeraj Dalal)
March 4, 2022, 9:14am
20
@francislavoie you were right, just a little correction
*.example.com {
rewrite /{labels.2}{uri}
reverse_proxy localhost:3000
}
# yeilds ~ systemctl reload caddy - Job for caddy.service failed.
solution -
*.example.com {
rewrite * /{labels.2}{uri}
reverse_proxy localhost:3000
}
# an asterisk was required after rewrite
let me know if this isn’t the practice, as I’m new to caddy