Hello all. New in the forum, though I have a little bit of experience with Caddy.
If using Caddy as a library in an app, could the proxying targets be intercepted and handled by the app? I’d like to be able to target different backends depending on status I’d control in the app.
I’ve only briefly looked through the “Caddy as a library” info I can find and I see it depends on a Caddyfile, so I’m thinking no?
Caddy isn’t anything like a HTTP request router you might commonly find in a Go app. It doesn’t really even behave similarly internally, I believe. So, just spit-balling here, but I see two ways about it depending on your requirements.
If you can determine in advance where the proxy needs to go (i.e. from app state or some external check), you could generate your Caddyfile string in your application and feed it to the Caddy instance each time the requirements change (should be a graceful reload).
If you can’t (i.e. you need to determine the destination from some aspect of the request itself), it’s not going to be pretty, but you could start Caddy and then start up your own localhost listener, proxying everything to yourself, inspecting the request, and proxying it onwards.
The second is a bit of a poor option because your app then needs to talk HTTP(S) anyway, so there’s little difference between this and having your own app without Caddy and just putting Caddy in front separately.
The first option looks promising. I should have considered generating the caddyfile passed. Second option not possible since I’m looking to use the automatic TLS feature of caddy. Thanks very much for the steer.
Second option won’t stop you from using Automatic HTTPS. Your app will still run Caddy at the edge listening to external clients, but it will be using Caddy to proxy to itself on some other port locally so you can do something with that forwarded request.
But yeah, it’s not ideal. Let us know how you go with option 1.
I seem to be missing something basic. How do we load a caddyfile? My idea was to have my app maintain/write the caddyfile rather than build it and inject it dynamically as a string.
I can do it using caddy.CaddyfileFromPipe() but see this is not recommended in a thread I’ve found. But caddy.LoadCaddyfile("http") seems to ignore the caddyfile in same directory as my app and use the default (app starts port 2015)? I’ve also tried to pass -config "path to my caddyfile" but still it starts on port 2015?
Thanks Matt, yes I had seen that - and the wiki example. But I’m still stuck. And i meant `-conf`` that’s what I’ve been using. The error was in my post above.
First thing I noticed, you need only import "github.com/mholt/caddy/caddyhttp" - no need to import "github.com/mholt/caddy/caddyhttp/httpserver" as that is imported for you by the first package.
Ah, I should probably add this to the docs, Caddy doesn’t plug in any Caddyfile loaders by default. We can look into changing that, although I prefer the programmer have complete control over loading the Caddyfile. Short of it is: load it yourself, or register a Caddyfile loader using caddy.RegisterCaddyfileLoader() or caddy.SetDefaultCaddyfileLoader() - you can see how the caddy command does this in run.go.
Just an FYI. I added an example that loads the Caddyfile from same directory to the Wiki on “embedded use”. It also includes the imports. From the forum posts, I could see both these points were stumbling blocks for others, as indeed they were for me