Caddy: v2: Caddyfile examples, reverse proxy udpate

Created on 21 Feb 2020  路  12Comments  路  Source: caddyserver/caddy

Reverse proxy example should have more services

yourdomain.com, www.yourdomain.com

reverse_proxy / {
    to 192.101.153.159:8080 192.118.109.166:8080
    health_path /health
    health_status 200
    transport http {
        read_buffer 4096
    }
}

it tells me, a dumb fuck, not enough to feel comfortable trying it and point nextcloud.yourdomain.com and bookstack.yourdomain.com to some IPs where their services are run

documentation

Most helpful comment

It sounds like, then, a correct and minimal config you are looking for is:

a.yourdomain.com {
    reverse_proxy 10.0.19.5:80
}

b.yourdomain.com {
    reverse_proxy 10.0.19.6:8080
}

We have very good (IMO) docs about all this: https://caddyserver.com/docs/caddyfile

On the directives page, we even describe the syntax descriptions (so meta!):

Syntax

The syntax of each directive will look something like this:

directive [<matcher>] <args...> {
  subdirective [<args...>]
}

The indicate tokens to be substituted by actual values.

The[brackets] indicate optional parameters.

The ellipses ... indicates a continuation, i.e. one or more parameters or lines.

Subdirectives are always optional unless documented otherwise, even though they don't appear in [brackets].

And the syntax of the reverse_proxy directive is also spelled out pretty clearly, with several examples! (We can add more, sure, but they should each teach a different principle.)

(This reminds me, I think it is on my TODO list for the Caddyfile to accept URLs as to values of a reverse_proxy directive, to conveniently specify protocol and to add a path. But for now, it's just a network address.)

All 12 comments

So, you want more examples added to the docs/wiki?

my opinion:
No need for more examples, but the one there should be better.

Reverse proxy is used when need more than one service/server.
So it should always show how to point to point various subdomains to at least two services, ideally at completely different IP.

In that example I dont see it there at quick glance.
What I see confuses me, I see two IPs - 192.101.153.159 and 192.118.109.166, being pointed to having same port, feels like it is load balancing or something.

Maybe Ishould understand it as yourdomain.com pointing to 192.101.153.159 and www.yourdomain.com points to 192.118.109.166? But by god that is strange as www subdomain almost universally points to same stuff as main domain, no?

I am plying with caddy v1 right now and this is my first caddyfile reverse proxy I googled out from examples. Seems to be working... like right away. Its fucking magic considering I spent dozens of hours wrapping my head around traefik and https http redirects and stuff

here is the config that is obvious to me, understandable

example.org {
  gzip
  proxy / 10.0.19.5:80 {
    transparent
  }
}

test.example.org {
  gzip
  proxy / 10.0.19.5:8080 {
    transparent
  }
}

I would say that if you start from https://caddyserver.com/docs/quick-starts/caddyfile and then visit https://caddyserver.com/docs/quick-starts/reverse-proxy afterwards, that should become obvious, no?

That said, I agree that we could add another example at the end of https://caddyserver.com/docs/caddyfile/directives/reverse_proxy

If you're interested in helping out with documentation, feel free to open a pull request on https://github.com/caddyserver/website

I would say that if you start from https://caddyserver.com/docs/quick-starts/caddyfile and then visit https://caddyserver.com/docs/quick-starts/reverse-proxy afterwards, that should become obvious, no?

Absolutely not!
That is great thing to point out, because I was at that page.

When I want to setup reverse proxy I have 3 information that I need to put somewhere.

  • url, or domain name, or subdomain name or whatever is the correct term for blabla.example.org or whoami.example.org or maybe example.org/plex
  • ip of the server at which the service runs
  • port of the service

example should show how I put these informations that I have in to Caddyfile. And have at least two services to see where exactly brackets go and possible separate settings for one, but no the other.

From examples there I dont even see what is the url being resolved, wtf is it just the name "localhost"?

Again, that thing from caddy v1 was dead simple to look at and immediatly know whats going on

example.org {
  gzip
  proxy / 10.0.19.5:80 {
    transparent
  }
}

test.example.org {
  gzip
  proxy / 10.0.19.5:8080 {
    transparent
  }
}

If you're interested in helping out with documentation, feel free to open a pull request

literally my first day with caddy

url, or domain name, or subdomain name or whatever is the correct term

Caddy uses the term "label" in the docs for that, to encompass the concept of the scheme/domain/IP/port/path combo

to see where exactly brackets go

See https://caddyserver.com/docs/caddyfile/concepts, explains the structure of a Caddyfile for v2.

is it just the name "localhost"?

Caddy follows the same convention as web browsers where if you omit the port, it assumes port 80, unless https:// is specified, in which case it assumes port 443.

literally my first day with caddy

No problem! I often make quick PRs to projects within the first few minutes of looking at them if I find a typo! 馃槢

Anyways - I would say that what you're trying to do specifically is slightly more advanced than the basic use-case, so I don't think it belongs in the quick-start guides. Those are meant as just an introduction. I kinda think it's just a matter of having to spend the time reading through more of the documentation pages, I think all the information is there, albeit possibly a bit scattered depending on what you're looking for. There's always room to add more examples on the relevant pages if you want to propose somewhere you think it would fit.

See https://caddyserver.com/docs/caddyfile/concepts

https://caddyserver.com/resources/images/caddyfile-visual.png

now that thing is great

Caddy follows the same convention as web browsers where if you omit the port, it assumes port 80, unless https:// is specified, in which case it assumes port 443.

Yeap, I am aware, but in examples I would prefer to be as explicit as possible without being too polluting where stuff might seem cryptic. Seeing actual url for me is visually more explicit, same as ports instead of implying 80

Reverse proxy is used when need more than one service/server.

Not necessarily. The examples serve to satisfy the set of features to be illustrated. In that example we have:

  • Two domains have the same configuration of reverse-proxying the requests to 2 upstreams. The requests have equal chance of going to either 192.101.153.159:8080 or 192.118.109.166:8080. Those are 2 servers, and nothing more.

Maybe Ishould understand it as yourdomain.com pointing to 192.101.153.159 and www.yourdomain.com points to 192.118.109.166

No, that's not right. Consider the possibility of such configuration existing somewhere:

yourdomain.com, www.yourdomain.com

reverse_proxy / {
    to 192.101.153.159:8080 192.118.109.166:8080 192.1.23.47:8080
    health_path /health
    health_status 200
    transport http {
        read_buffer 4096
    }
}

By your reasoning, what hostname should the third upstream be bound to?

Reverse proxy is used when need more than one service/server.
feels like it is load balancing or something

Many of reverse-proxying scenarios are intertwined with load-balancing. Reverse-proxy doesn't necessate 1-to-1 mapping between front-facing server and upstream, and there doesn't need to be more than 1 sub-domain/service. The first personal self-hosted service I set up was only 1 sub-domain, with nothing at all hosted on the naked domain nor on www.. I still don't have anything hosted on the naked domain nor www., and the IP address of upstream is all the same except for different ports. So the criteria of:

Reverse proxy is used when need more than one service/server. So it should always show how to point to point various subdomains to at least two services, ideally at completely different IP.

will give examples that don't work for my use-case at all, even though mine is very simple.

But by god that is strange as www subdomain almost universally points to same stuff as main domain, no?

No, it isn't unusual for naked domain to match the content of www. subdomain. This very website (Github) serves the same content for both github.com and www.github.com. The same is followed by Facebook, among numerous others.

Anyway, I understand you're trying to have 2 subdomains pointing to different upstreams without load-balancing. I think you'll need something like this:

nextcloud.yourdomain.com {
    reverse_proxy {
    to {replace this with a series of space-separated IP:PORT of nextcloud upstream}
        health_path /health
        health_status 200
        transport http {
            read_buffer 4096
        }
    }
}

bookstack.yourdomain.com {
    reverse_proxy {
        to {replace this with a series of space-separated IP:PORT of bookstack upstream}
        health_path /health
        health_status 200
        transport http {
            read_buffer 4096
        }
    }
}

Given this, can you guide us to how you'd like the examples to be like?

In that example we have:

IMO that is example of load balancer not a reverse proxy. Maybe its industry standard and much more used feature in deployment, but for me and I feel many in the /r/selfhosting world the sorting of subdomain to services comes way before thinking about load balancing.

Many of reverse-proxying scenarios are intertwined with load-balancing.

but I think since we have a word "load balancing", it should have example of its own. Here is example of reverse proxy, here is example of load balancing.

Reverse-proxy doesn't necessate 1-to-1 mapping between front-facing server and upstream, and there doesn't need to be more than 1 sub-domain/service.

Of course there doesnt need to be, but it is example and if I see two services defined, I know how to define one or two of mine own and see pattern on how to add 3rd and 4th.
New line, starting with address, block...
if the example is for a single service, I am left bit guessing and trying and needing to look for more information

No, it isn't unusual for naked domain to match the content of www. subdomain.

Yeap, that was what I actually meant.

Anyway, I understand you're trying to have 2 subdomains pointing to different upstreams without load-balancing. I think you'll need something like this:

Thanks, but that config gives me errors

Coddyfile

a.yourdomain.com { reverse_proxy { to {10.0.19.5:80} health_path /health health_status 200 transport http { read_buffer 4096 } } } b.yourdomain.com { reverse_proxy { to {10.0.19.6:8080} health_path /health health_status 200 transport http { read_buffer 4096 } } }

Errors

ERROR http.handlers.reverse_proxy.health_checker.active bad network address {"address": "{10.0.19.5:80}", "error": "invalid start port: strconv.ParseUint: parsing \"80}\": invalid syntax"} ERROR http.log.error making dial info: upstream {10.0.19.5:80}: invalid dial address : missing port in address

I am on AUR package with version clamed beta.13-1
though caddy version returns just (devel)

Tried some shenanigens with removing health check, and playing with the position of squiggly brackets but either same thing or a different errors popped up of no upstream available.

Went back to the documentation and doing smalle steps

this one just works:

a.yourdomain.com {
    reverse_proxy 10.0.19.5:80
}

b.yourdomain.com {
    reverse_proxy 10.0.19.6:8080
}

This also works:

a.yourdomain.com {
    reverse_proxy {
        to 10.0.19.5:80
    }
}

b.yourdomain.com {
    reverse_proxy {
        to 10.0.19.6:8080
    }
}

This gives that missing port error when actually trying to access sites

a.yourdomain.com {
    reverse_proxy {
        to {10.0.19.5:80}
    }
}

b.yourdomain.com {
    reverse_proxy {
        to {10.0.19.6:8080}
    }
}

I often use reverse proxying in mixed service node setups, where the app servers use http and the proxy offers https to the outside. Would love to use caddy for this, but do not seem to have enough time and knowledge to fiddle with the specifics of the client servers being proxied. Samples could be jenkins and artifactory OSS edition docker containers, or notebook servers.

This problem seems to fall into the no one cares area between caddy and the projects of the proxied services (nginx and other more established proxies receive more love from these projects I assume).

@DoTheEvo I think you misunderstood, he was meaning for you to replace the {} as well in the arguments to the to subdirective. The error you're seeing is exactly right, having {} brackets there is invalid syntax.

Yeah, I misunderstood -.-
Let me just put squiggly brackets as a notation for variable in a config that uses squiggly brackets for blocks of content, surely no one will spend hour+ playing with it

1452888855836

It sounds like, then, a correct and minimal config you are looking for is:

a.yourdomain.com {
    reverse_proxy 10.0.19.5:80
}

b.yourdomain.com {
    reverse_proxy 10.0.19.6:8080
}

We have very good (IMO) docs about all this: https://caddyserver.com/docs/caddyfile

On the directives page, we even describe the syntax descriptions (so meta!):

Syntax

The syntax of each directive will look something like this:

directive [<matcher>] <args...> {
  subdirective [<args...>]
}

The indicate tokens to be substituted by actual values.

The[brackets] indicate optional parameters.

The ellipses ... indicates a continuation, i.e. one or more parameters or lines.

Subdirectives are always optional unless documented otherwise, even though they don't appear in [brackets].

And the syntax of the reverse_proxy directive is also spelled out pretty clearly, with several examples! (We can add more, sure, but they should each teach a different principle.)

(This reminds me, I think it is on my TODO list for the Caddyfile to accept URLs as to values of a reverse_proxy directive, to conveniently specify protocol and to add a path. But for now, it's just a network address.)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mholt picture mholt  路  3Comments

mschneider82 picture mschneider82  路  3Comments

treviser picture treviser  路  3Comments

wayneashleyberry picture wayneashleyberry  路  3Comments

ericmdantas picture ericmdantas  路  3Comments