runner: Caddy service for cache HTTPS frontend (router-PAT-friendly ports)
This commit is contained in:
3
runner/.gitignore
vendored
3
runner/.gitignore
vendored
@@ -6,3 +6,6 @@ result
|
||||
# committed; the public key is regenerated per deployment too
|
||||
# (`nix-store --generate-binary-cache-key`).
|
||||
cache/
|
||||
|
||||
# Caddy state: ACME account + issued certs + on-disk config tree.
|
||||
caddy/
|
||||
|
||||
43
runner/Caddyfile
Normal file
43
runner/Caddyfile
Normal file
@@ -0,0 +1,43 @@
|
||||
# Caddy config for the cargoxx binary cache.
|
||||
#
|
||||
# The router does PAT (port forwarding) so the *external* world reaches
|
||||
# us at the standard 80/443 but the *internal* ports are different.
|
||||
# `http_port` and `https_port` below must match the internal ports the
|
||||
# router forwards to. Override via runner/.env:
|
||||
#
|
||||
# CADDY_HTTP_PORT=8080
|
||||
# CADDY_HTTPS_PORT=8443
|
||||
#
|
||||
# (Those env vars are picked up by compose.yml to publish the ports
|
||||
# AND injected into this Caddyfile via the {$VAR:default} substitution
|
||||
# below — Caddy expands env vars natively.)
|
||||
{
|
||||
# Internal ports — must equal whatever the router forwards 80/443 to.
|
||||
http_port {$CADDY_HTTP_PORT:8080}
|
||||
https_port {$CADDY_HTTPS_PORT:8443}
|
||||
# ACME's HTTP-01 challenge probe still arrives at host:80 → router
|
||||
# → :8080; Caddy answers it on the internal port. Auto cert works
|
||||
# as long as the PAT maps 80 → CADDY_HTTP_PORT and 443 → CADDY_HTTPS_PORT.
|
||||
email vorontsov@amadey.xyz
|
||||
}
|
||||
|
||||
cache.cargoxx.amadey.xyz {
|
||||
root * /srv/cache
|
||||
file_server
|
||||
|
||||
# narinfo / nar are immutable per content hash → cache aggressively.
|
||||
@cache_immutable path *.narinfo *.nar.xz *.nar
|
||||
header @cache_immutable Cache-Control "public, immutable, max-age=31536000"
|
||||
|
||||
# Substituter probe; short cache so new entries land quickly.
|
||||
@cache_info path /nix-cache-info
|
||||
header @cache_info Cache-Control "public, max-age=300"
|
||||
|
||||
log {
|
||||
output file /data/access.log {
|
||||
roll_size 50MiB
|
||||
roll_keep 5
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -61,20 +61,28 @@ Self-hosted Gitea Actions runner that validates package PRs.
|
||||
The `cache/` directory is gitignored. Both keys live alongside
|
||||
`compose.yml`; the named volume binds use `${PWD}/cache/...`.
|
||||
|
||||
5. **(optional) Front the store with Caddy** so substituters can read it.
|
||||
A ready-to-edit `Caddyfile.example` ships in this directory — copy
|
||||
into `/etc/caddy/Caddyfile` (or `import` it) and reload:
|
||||
5. **Pick the Caddy ports.** `compose.yml` runs Caddy alongside the
|
||||
runner to HTTPS-front the cache. Because the router does PAT, the
|
||||
*internal* ports Caddy listens on must equal whatever 80/443 are
|
||||
forwarded to. Add to `.env`:
|
||||
|
||||
```sh
|
||||
sudo install -m644 Caddyfile.example /etc/caddy/conf.d/cargoxx-cache
|
||||
sudo systemctl reload caddy
|
||||
```env
|
||||
CADDY_HTTP_PORT=8080
|
||||
CADDY_HTTPS_PORT=8443
|
||||
```
|
||||
|
||||
Caddy auto-provisions a Let's Encrypt cert. Consumers later need
|
||||
`substituters = https://cache.cargoxx.<your-domain>` and
|
||||
`trusted-public-keys = <contents of cache.pub>` in their nix config
|
||||
— those go into the cargoxx wrapper (`cargoxx`'s own `flake.nix`),
|
||||
so any user installing the bundled cargoxx picks them up.
|
||||
Both compose.yml and the Caddyfile pick those up. The Caddyfile
|
||||
already targets `cache.cargoxx.amadey.xyz` and the e-mail
|
||||
`vorontsov@amadey.xyz`; edit if you're deploying somewhere else.
|
||||
|
||||
ACME provisioning works as long as the router forwards 80 →
|
||||
CADDY_HTTP_PORT and 443 → CADDY_HTTPS_PORT, so Let's Encrypt's
|
||||
HTTP-01 challenge reaches Caddy.
|
||||
|
||||
Consumers' substituter config (`substituters = https://cache.<domain>`,
|
||||
`trusted-public-keys = <cache.pub>`) is baked into cargoxx's own
|
||||
wrapper (`cargoxx/flake.nix:cargoxxNixConfig`), so any installed
|
||||
`cargoxx` binary picks them up — no per-user setup needed.
|
||||
|
||||
6. **Start the runner**:
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
# Runs the act_runner that listens to Gitea and spawns one job
|
||||
# container per workflow run. The job image (cargoxx-runner-job:latest)
|
||||
# is built reproducibly from runner/flake.nix — run `nix run .#load-image`
|
||||
# in this directory to load it into the host's Docker daemon before
|
||||
# starting the runner.
|
||||
version: "3.8"
|
||||
# Runs two services on the host:
|
||||
# - act_runner — polls Gitea, spawns one job container per workflow
|
||||
# run via the host docker socket. Job image built reproducibly from
|
||||
# runner/flake.nix (`nix run .#load-image`).
|
||||
# - caddy — HTTPS-fronts the binary cache (./cache/store) so
|
||||
# consumers' substituter config can read it. Custom ports because
|
||||
# the router does PAT (port-forwarding 80→CADDY_HTTP_PORT,
|
||||
# 443→CADDY_HTTPS_PORT). Set those in .env.
|
||||
services:
|
||||
runner:
|
||||
image: docker.io/gitea/act_runner:nightly
|
||||
@@ -20,12 +22,26 @@ services:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
# Binary cache — `validate-pr.yml`'s push step writes `$out` NAR
|
||||
# archives here. Named volumes (defined below) make the same
|
||||
# storage reachable from both this runner container AND every
|
||||
# job container act_runner spawns. nginx (on the host) serves
|
||||
# ./cache/store over HTTPS for consumers' substituter config.
|
||||
# storage reachable from this runner container AND every job
|
||||
# container act_runner spawns AND the caddy frontend below.
|
||||
- cargoxx-cache-store:/srv/cargoxx-cache/store
|
||||
- cargoxx-cache-keys:/srv/cargoxx-cache/keys:ro
|
||||
|
||||
caddy:
|
||||
image: docker.io/caddy:2
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "${CADDY_HTTP_PORT:-8080}:${CADDY_HTTP_PORT:-8080}"
|
||||
- "${CADDY_HTTPS_PORT:-8443}:${CADDY_HTTPS_PORT:-8443}"
|
||||
environment:
|
||||
CADDY_HTTP_PORT: "${CADDY_HTTP_PORT:-8080}"
|
||||
CADDY_HTTPS_PORT: "${CADDY_HTTPS_PORT:-8443}"
|
||||
volumes:
|
||||
- ./Caddyfile:/etc/caddy/Caddyfile:ro
|
||||
- cargoxx-cache-store:/srv/cache:ro
|
||||
- caddy-data:/data
|
||||
- caddy-config:/config
|
||||
|
||||
volumes:
|
||||
cargoxx-cache-store:
|
||||
# Explicit name disables compose's project-prefix so spawned job
|
||||
@@ -44,3 +60,19 @@ volumes:
|
||||
type: none
|
||||
o: bind
|
||||
device: "${PWD}/cache/keys"
|
||||
caddy-data:
|
||||
# Caddy's own state: ACME account, issued certificates, OCSP
|
||||
# staples. Persist so we don't re-issue certs every restart.
|
||||
name: caddy-data
|
||||
driver: local
|
||||
driver_opts:
|
||||
type: none
|
||||
o: bind
|
||||
device: "${PWD}/caddy/data"
|
||||
caddy-config:
|
||||
name: caddy-config
|
||||
driver: local
|
||||
driver_opts:
|
||||
type: none
|
||||
o: bind
|
||||
device: "${PWD}/caddy/config"
|
||||
|
||||
Reference in New Issue
Block a user