caddy-incus-upstreams/README.md

148 lines
3.7 KiB
Markdown
Raw Permalink Normal View History

2026-07-19 15:31:28 +00:00
**NOTICE**: This repository has been moved to [https://code.adriano.fyi/me/caddy-incus-upstreams](https://code.adriano.fyi/me/caddy-incus-upstreams). Microsoft has shown little interest in stewarding what was once the best and largest open source community. This small act of migration is my way showing that we don't all support Microsoft's disinterest.
2024-12-05 22:11:14 +00:00
# caddy-incus-upstreams
> Status: **HIGHLY experimental**, patches welcome 🚩
2024-12-18 15:05:34 +00:00
[`Incus`](https://linuxcontainers.org/incus/) dynamic upstreams for
[`Caddy`](https://caddyserver.com/docs/) v2+ 🧨
2024-12-05 22:11:14 +00:00
2024-12-18 15:04:11 +00:00
In other words, `Caddy` can automatically pick up your `Incus` instances when
they have 3 config keys attached to them which specify 1. that they want to be
routed 2. which domain should be routed to them 3. which port they'll answer
on. Combined with the lightweight configuration and the Auto-TLS (magic) powers
of Caddy, provisioning `Incus` instances to serve on the web is much more
convenient.
2024-12-05 22:11:14 +00:00
## Usage
2024-12-18 14:54:41 +00:00
Set the following config on your `Incus` instance.
2024-12-05 22:11:14 +00:00
2024-12-12 15:18:53 +00:00
```bash
2024-12-18 14:52:02 +00:00
incus launch images:alpine/3.20 <instance-name>
2024-12-05 22:11:14 +00:00
incus config set <instance-name> user.caddyserver.http.enable=true
incus config set <instance-name> user.caddyserver.http.matchers.host=<domain>
incus config set <instance-name> user.caddyserver.http.upstream.port=<port>
```
2024-12-18 14:54:41 +00:00
Build a fresh `Caddy` with this plugin.
2024-12-05 22:11:14 +00:00
2024-12-12 15:18:53 +00:00
```bash
2024-12-28 23:43:13 +00:00
xcaddy build --with=git.coopcloud.tech/decentral1se/caddy-incus-upstreams
2024-12-05 22:11:14 +00:00
```
2024-12-18 14:54:41 +00:00
Wire up a `Caddyfile` based on this example.
2024-12-05 22:11:14 +00:00
2024-12-12 15:18:53 +00:00
```Caddyfile
2024-12-25 09:11:15 +00:00
<domain> {
2024-12-05 22:11:14 +00:00
reverse_proxy {
dynamic incus
}
}
```
2024-12-18 14:52:02 +00:00
And then make sure everything gets picked up with a `reload`/`restart`.
```
caddy reload
incus restart <instance-name>
```
2024-12-05 22:11:14 +00:00
## Notes
2024-12-18 14:54:41 +00:00
The plugin responds to the following `Incus` events:
2024-12-05 22:11:14 +00:00
* `api.EventLifecycleInstanceCreated`
2024-12-05 22:11:14 +00:00
* `api.EventLifecycleInstanceRestarted`
* `api.EventLifecycleInstanceResumed`
* `api.EventLifecycleInstanceStarted`
2024-12-05 22:11:14 +00:00
2024-12-18 14:37:38 +00:00
There is a rather crude implementation for handling these events. We simply
wire up a few seconds of sleep to allow for the network part of the instance to
2024-12-18 14:54:41 +00:00
come up. Otherwise, there is no network address to retrieve.
2024-12-18 14:37:38 +00:00
We currently *only* match against the upstream ipv4 addresses of instances.
2024-12-05 22:11:14 +00:00
2024-12-18 14:47:48 +00:00
The system user that runs `Caddy` must be `root` or be in the `incus-admin`
group so that it can make queries across projects for different instances.
2024-12-17 19:48:39 +00:00
## FAQ
### Does this support wildcard certificates?
2024-12-18 14:54:41 +00:00
Yes! You'll need to enable a [DNS
plugin](https://caddy.community/t/how-to-use-dns-provider-modules-in-caddy-2/8148j)
and wire up something like this in your `Caddyfile`.
2024-12-17 19:48:39 +00:00
```Caddyfile
{
acme_dns <your-provider-here> <your-token-here>
}
2024-12-25 09:12:08 +00:00
*.<domain> {
2024-12-17 19:48:39 +00:00
reverse_proxy {
dynamic incus
}
}
```
2024-12-05 22:11:14 +00:00
## Hackin'
2024-12-18 15:05:34 +00:00
Install [`xcaddy`](https://github.com/caddyserver/xcaddy) and
[`Incus`](https://linuxcontainers.org/incus/).
2024-12-05 22:11:14 +00:00
2024-12-18 14:54:41 +00:00
Create this `Caddyfile` in the root of the project repository.
2024-12-05 22:11:14 +00:00
```Caddyfile
{
debug
http_port 6565
}
2024-12-12 22:56:41 +00:00
http://foo.localhost {
2024-12-05 22:11:14 +00:00
reverse_proxy {
dynamic incus
}
}
```
2024-12-12 22:56:41 +00:00
Then create a new instance and assign the relevant config.
2024-12-05 22:11:14 +00:00
2024-12-12 15:18:53 +00:00
```bash
2024-12-05 22:11:14 +00:00
incus launch images:alpine/3.20 foo
incus config set foo user.caddyserver.http.enable=true
incus config set foo user.caddyserver.http.matchers.host=foo.localhost
incus config set foo user.caddyserver.http.upstream.port=80
2024-12-12 22:56:41 +00:00
```
Serve something from your instance.
2024-12-05 22:11:14 +00:00
2024-12-12 22:56:41 +00:00
```
incus shell foo
apk add python3
python3 -m http.server 80
```
2024-12-05 22:11:14 +00:00
2024-12-18 14:54:41 +00:00
Run `Caddy` with the plugin baked in.
2024-12-05 22:11:14 +00:00
2024-12-12 22:56:41 +00:00
```
2024-12-05 22:11:14 +00:00
xcaddy run
2024-12-12 22:56:41 +00:00
```
2024-12-05 22:11:14 +00:00
2024-12-18 14:54:41 +00:00
And finally, route a request to the instance via `Caddy`.
2024-12-12 22:56:41 +00:00
```
curl -X GET http://foo.localhost:6565
2024-12-05 22:11:14 +00:00
```
🧨
## ACK
* [`caddy-docker-upstreams`](https://github.com/invzhi/caddy-docker-upstreams)
## License
<a href="https://git.coopcloud.tech/decentral1se/caddy-incus-upstreams/src/branch/main/LICENSE">
<img src="https://www.gnu.org/graphics/gplv3-or-later.png" />
2026-07-19 15:31:28 +00:00
</a>