Comments (17)
Sockets can have names attached (so the user can name them http
and https
for example, or api
and metrics
), and we could add a syntax to refer to them via these names in Caddyfile
. I could say I want a http server on sd-listen:http
, which would then expect a listener named http
to be passed to caddy.
All these passed FDs also give you a net.Listener
interface, so even without explicit config caddy could still check the properties of it and apply some heuristics too (detect port 80 and 443 if you got two unnamed TCP sockets), if we want to apply some out-of-the-box behaviour in these scenarios. But getting the basic support for it (using an externally-passed FD by its name/index) and defining the syntax for it would be a nice first step.
You can play around with this through systemd-socket-activate -l 8088 -l 8089 --fdname=foo:bar -- /path/to-caddy
, which will give you two TCP sockets listening on the two ports, named foo
and bar
.
from caddy.
@flokli So that means you're fine with mixing passing FD and current binding behavior? And since you will use bind
explicitly, it's an error to bind to an non existent FD.
The problem with names is that one name can map to many sockets with different addresses, how do you think caddy handle this situation?
from caddy.
for those that just care about binding to ports <1024 AND not running Caddy as root,
There was never a need to run Caddy as root on Linux. Our standard systemd unit file is shipped with CAP_NET_BIND_SERVICE
which allows the service to run without root. The SocketBindAllow
and SocketBindDeny
allows further restriction to specific ports rather than any port below 1024.
from caddy.
Are you looking for the bind
directive? https://caddyserver.com/docs/caddyfile/directives/bind
And see https://caddyserver.com/docs/conventions#network-addresses, you can use unix sockets in reverse_proxy
upstreams.
I'm not sure what you're asking for if not that.
from caddy.
It sounds like what is being asked for is graceful upgrades/restarts.
Caddy 1 had this feature, and I quite liked how it worked: pass the socket directly to the next process. It worked on all Unix systems without relying on a separate system service, and it was smart enough to understand Caddy configuration: if the new config didn't use a socket, it wouldn't be kept; rather than blindly moving all the sockets over.
I'd probably rather bring the implementation from Caddy 1 into Caddy 2.
from caddy.
It sounds like what is being asked for is graceful upgrades/restarts.
No, getting this for free is only one side-effect of supporting socket-activation.
socket-activation will also cause caddy to get started lazily whenever the first connection to the (externally configured) socket address happens, which simplifies declaring service dependencies too.
The article linked from my link elaborates a bit more on this.
Caddy 1 had this feature, and I quite liked how it worked: pass the socket directly to the next process.
This still requires caddy to do manual coordination with its new process and pass it around explicitly. The point of simply taking the FDs passed by the service manager is that caddy does not have to be aware of whether it's the first process being started on the system, or you start a new version with another config. caddy simply gets an FD, where new connections will appear on.
from caddy.
Ah yes, and because caddy just takes FDs, it doesn't need to bind()
on its own, which allows applying stronger sandboxing from the outside.
from caddy.
This still requires caddy to do manual coordination with its new process and pass it around explicitly. The point of simply taking the FDs passed by the service manager is that caddy does not have to be aware of whether it's the first process being started on the system, or you start a new version with another config. caddy simply gets an FD, where new connections will appear on.
But what is Caddy supposed to do with that socket? How does it know the configuration associated with it? You can't just hand a server a socket and expect it to know what to do with it, without any configuration... maybe I am missing something about how it works.
from caddy.
Oh I see, so you'd still have your Caddy config, you'd just specify a different network name for the listener address, and Caddy will then get it from the service manager rather than binding a new socket.
from caddy.
Yes! Or well, I don't want caddy to do any bind on its own at all, but pass in every socket via this mechanism.
from caddy.
In that case you can use bind
in your site blocks to get the socket from the service manager. We'd just need to implement a package that calls caddy.RegisterNetwork()
. For example the caddy-tailscale
package does this so that Tailscale can provide a listener.
Anyone is welcome to pick this up.
from caddy.
@mholt I did some experiments with registering custom network, it's too much trouble to be worth it. Every site block needs an explicit bind
and that includes http port and http3 udp socket.
@flokli I'm thinking on unix, we can try preferring socket activation but fallback to the old behavior. What do you think of it? Or should caddy just exit unsuccessfully if socket activation environments variables are found but not sockets matching listening critertia are found? Or if some warning logs are emitted?
As mentioned above, you are responsible to pass every socket yourself, including 80 tcp and 443 udp if auto http->https and http3 are enabled respectively. And admin socket if enabled as well. Assuming you restart caddy instead of reload it.
from caddy.
I would really see it happen and it can greatly reduce my network stack complexity.
Currently, I am have two caddy
in front of server
and I face a lot of instability because of podman
networking.
I change to using socket
to see if it works better (no more DNS resolution).
flowchart TD
A[Caddy] -->|Reverse Proxy| B{Container Network}
B -->|Serve Frontend| C[Caddy]
C -->|Reverse Proxy| D[Server]
When socket activation
becomes a thing, it can also reduce resources usage. Because the middle caddy
can be terminated when no one connected for some time. If the outer one can be socket activated
, it will directly pass the socket to inner one and benefit of direct network connection.
from caddy.
@mholt I did some experiments with registering custom network, it's too much trouble to be worth it. Every site block needs an explicit
bind
and that includes http port and http3 udp socket.@flokli I'm thinking on unix, we can try preferring socket activation but fallback to the old behavior. What do you think of it? Or should caddy just exit unsuccessfully if socket activation environments variables are found but not sockets matching listening critertia are found? Or if some warning logs are emitted?
I think ti makes sense to first land the feature with explicit configuration, which might mean explicit bind
statements, and once that's in, think about having more opinionated defaults in case we are in a socket-activated environment.
The good thing is, it's pretty safe to detect whether caddy is running in a socket-activated environment or not, so we are able to change defaults in this case, without breaking existing usecases.
from caddy.
Until this is implemented: for those that just care about binding to ports <1024 AND not running Caddy as root, can use systemd's SocketBindAllow= (available since systemd 249)
from caddy.
Related Issues (20)
- reverse_proxy: how to prevent stripping of headers with underscores / _ ? HOT 8
- Is fallback on a reverse_proxy's lb_policy being parsed properly? HOT 4
- Missing byte in first websocket message HOT 7
- `reverse_proxy` leads to duplicate `Server` headers HOT 6
- Unable to configure to Host: agnostic and port agnostic. HOT 2
- CADDY_ADMIN cannot be used to disable the admin interface HOT 1
- A placeholder cannot be used to disable the admin interface HOT 5
- CA/Browser Forum declared OCSP as optional HOT 4
- Unexpected need of execute permissions HOT 2
- Docker build hangs HOT 1
- Intermittent “panic: runtime error: invalid memory address or nil pointer dereference” HOT 6
- (2.8.0-beta.1) CEL expressions in Caddyfile not processed properly HOT 5
- Caddy PKI without Root key HOT 11
- Reverse Proxy active health checks should not follow redirects by default
- Problems with reverse proxied server sent events and compression HOT 3
- Caddy on_demand_tls asking ask endpoint for self IP when no FQDN/SNI is used HOT 18
- Caddy log file permissions HOT 8
- Certificate renewal checks only using ipv6 dns even if it times out. HOT 6
- Proxy protocol v2, as declared in reverse_proxy / transport http, fails due to unitialized command byte
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from caddy.