`git.gioser.net` y `git.tawasuyu.net` responden **200 con TLS válido desde 2.29.29.217**, `git clone` funciona por HTTPS **y** por SSH:2345, y `gitea` + `caddy` corren supervisados por `arje-zero`. El gitea de gioser está parado. Es el primer servicio real que deja la máquina que se va a borrar. Mudanza INCREMENTAL: los DNS de gioser son casi todos `CNAME → www`, así que mover `www` habría mudado quince dominios cuyos backends siguen allá. Se convirtió sólo `git` (las dos zonas) de CNAME a A propio con TTL 60 — reversible en un minuto. Cinco cosas que sólo se aprenden haciéndolo: · **Parar el origen no es `rc-service gitea stop`**: dice «already stopped» con el proceso vivo, y matarlo no alcanza — lo revive arje-zero, que lo tiene como card `openrc-gitea` con Restart y **9001 reinicios** en el contador. Se paró con `arjectl stop openrc-gitea` (el arjectl que construimos hoy, hablando con el arje de gioser), y para eso hubo que extraer su card del genesis y escribirla en `cards.d` — que es justo el hueco del §6.12. · **El token de `hcloud` también gestiona el DNS** (Cloud API unificada, `/v1/zones`); la API vieja `dns.hetzner.com/api/v1` redirige a la consola web. Y un `PUT` sobre el rrset no puede cambiar el TIPO: hay que DELETE del CNAME y POST del A. · **ACME falló primero contra gioser** (502) porque el challenge salió antes de que propagara el DNS. Con el DNS al día, `arjectl restart caddy` → certificate obtained successfully. · **La identidad SSH se muda con el servicio**: `REMOTE HOST IDENTIFICATION HAS CHANGED` hasta que se copiaron las claves de host de gioser a la caja. Así los clones existentes no notan nada; el precio es limpiar el known_hosts propio del `:22` de administración. · El `sshd` del producto escucha sólo en `:22` ⇒ el git por SSH necesitó `Port 2345` y que el usuario `gitea` tenga shell real (su authorized_keys fuerza `command="gitea serv …"`). `caddy` gana su `[[service]]` (con guarda del Caddyfile, HOME propio para los certificados de ACME —o cada reinicio pediría certificados nuevos y se comería el límite de emisión— y la nota de por qué corre como root) y el perfil lo arranca. Consecuencia para la granja: las 23 recetas que clonan por `https://git.tawasuyu.net/…` **ya apuntan a la caja**. Comprobado: el worker resuelve 2.29.29.217 y `git ls-remote` responde. Revertir, si hiciera falta: `arjectl start openrc-gitea` en gioser y los dos `git` de vuelta a CNAME. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Tf9T4vGzsMoT7eS8YzMFn
61 lines
3.6 KiB
TOML
61 lines
3.6 KiB
TOML
# caddy 2.11.4 — servidor web y proxy inverso. Un binario Go estático, sin dependencias en runtime.
|
|
#
|
|
# ── ESTADO: TERMINADA (2026-09-11). Antes era un import de nix en crudo ────────────────────────
|
|
# La cabecera decía «PUNTO DE PARTIDA, no final» y el `commit` era el TAG FLOTANTE `v2.11.4`, que
|
|
# contradice el ADR 0006: un tag se puede mover, y entonces la misma receta construye otra cosa sin
|
|
# que el hash lo note. Anclado con `takana pin` al SHA inmutable `e2eee6a7…` — el hash se movió a
|
|
# propósito (`b3:d38acaa0…` → nuevo), que es exactamente lo que un anclaje debe hacer.
|
|
#
|
|
# ── POR QUÉ IMPORTA QUE ESTÉ TERMINADA ─────────────────────────────────────────────────────────
|
|
# El `caddy` de gioser **no tiene dueño**: es un binario puesto a mano en `/usr/bin`, sin paquete y
|
|
# sin receta (medido por `scripts/mudanza/censar.py`, que le preguntó a pacman). Se pierde con la
|
|
# máquina. Con esta receta el servidor nuevo lo declara en su perfil y lo reconstruye — que es la
|
|
# diferencia entre mudar un servidor y poder mudarlo otra vez (SDD 29).
|
|
#
|
|
# `link = "static"` y CGO apagado: Go estático no arrastra sonames, así que no repite la fuga del
|
|
# `NEEDED` colgante — el binario corre en la imagen sin el sysroot del lab debajo.
|
|
name = "caddy"
|
|
version = "2.11.4"
|
|
license = "Apache-2.0"
|
|
|
|
[source]
|
|
repo = "https://github.com/caddyserver/caddy"
|
|
commit = "e2eee6a7fce366321294c9c2a79f3146891dcbdf"
|
|
|
|
[build]
|
|
compiler = "zig-cc"
|
|
target = "x86_64-linux-musl"
|
|
link = "static"
|
|
flags = []
|
|
|
|
# `go` es herramienta de BUILD, no dependencia de runtime: el binario sale autocontenido.
|
|
[deps]
|
|
build = ["go"]
|
|
|
|
# ── EL SERVICIO QUE ESTE PAQUETE TRAE (SDD 30) ──────────────────────────────────────────────────
|
|
# Fuera de `hash_inputs`: declarar esto NO re-hashea caddy.
|
|
#
|
|
# Caddy es el que pone la cara al exterior: sin él, un dominio mudado no responde aunque su backend
|
|
# esté vivo. La guarda comprueba el Caddyfile y sale 78 nombrándolo — un caddy sin config **arranca
|
|
# igual** y sirve una página vacía en el 80, que es peor que no arrancar: el dominio parece vivo.
|
|
#
|
|
# ⚠ `HOME` NO es cosmético: ahí guarda las claves y los certificados de ACME
|
|
# (`$HOME/.local/share/caddy`). Con el HOME del padre, un reinicio pediría certificados NUEVOS a
|
|
# Let's Encrypt y se comería el límite de emisión del dominio.
|
|
#
|
|
# Corre como ROOT a propósito: enlaza :80 y :443, que son privilegiados. La alternativa es
|
|
# `setcap cap_net_bind_service`, que no se puede aplicar desde el store (el artefacto es de sólo
|
|
# lectura y los caps no viajan en el hardlink) ⇒ sería estado fuera del árbol, que es justo lo que
|
|
# esta distro evita. Queda anotado como decisión, no como olvido.
|
|
#
|
|
# Rutas ABSOLUTAS: el `sh` de busybox no despacha applets y PID 1 no garantiza `PATH`.
|
|
[[service]]
|
|
label = "caddy"
|
|
id = "01M2EKDA00V4XCPRH5WRSGDAJP"
|
|
exec = "/bin/busybox"
|
|
argv = ["sh", "-c", "test -f /etc/caddy/Caddyfile || { echo 'caddy: falta /etc/caddy/Caddyfile — es config del SITIO' >&2; exit 78; }; /bin/mkdir -p /var/lib/caddy /var/log/caddy; exec /usr/bin/caddy run --config /etc/caddy/Caddyfile --adapter caddyfile"]
|
|
envp = [["PATH", "/usr/bin:/bin"], ["HOME", "/var/lib/caddy"], ["XDG_DATA_HOME", "/var/lib/caddy"]]
|
|
networking = "full"
|
|
cgroup = "arje.slice/caddy"
|
|
restart = { initial_ms = 1000, max_ms = 30000 }
|