## Summary - Add `nixpkgs-services` flake input pinned to a specific nixpkgs commit, with an overlay that pulls `forgejo-runner`, `snowflake`, and `k3s` from it instead of the rolling `nixpkgs` - Dagger `flake-update` pipeline now excludes `nixpkgs-services` via `--exclude` - Fix stale nix-container-builder version in service-versions.yaml (was 12.6.4, actually running 12.7.2) - Add k3s and minikube to service-versions.yaml tracking - Document the pinning approach in review-services how-to and ringtail reference ## Motivation During service review, discovered that flake updates had silently upgraded forgejo-runner from 12.6.4 → 12.7.2 without updating service-versions.yaml. This "sneak-in upgrade" bypasses the service review process. The overlay ensures these three services only change versions deliberately. ## Test plan - [ ] Verify `nix flake update` from `nixos/ringtail/` does not change `nixpkgs-services` lock entry - [ ] Verify `mise run provision-ringtail` builds successfully with the overlay - [ ] Confirm running service versions unchanged after deploy 🤖 Generated with [Claude Code](https://claude.com/claude-code) Reviewed-on: #321
67 lines
1.7 KiB
Django/Jinja
67 lines
1.7 KiB
Django/Jinja
# Caddy reverse proxy for blumeops services
|
|
# Managed by ansible - do not edit manually
|
|
#
|
|
# All *.{{ caddy_domain }} requests are proxied to backend services.
|
|
# TLS certificates are obtained via ACME DNS-01 challenge using Gandi.
|
|
|
|
{
|
|
# Global options
|
|
admin off
|
|
|
|
{% if caddy_tcp_services %}
|
|
# Layer 4 (TCP) routing
|
|
layer4 {
|
|
{% for tcp_svc in caddy_tcp_services %}
|
|
:{{ tcp_svc.port }} {
|
|
route {
|
|
proxy {{ tcp_svc.backend }}
|
|
}
|
|
}
|
|
{% endfor %}
|
|
}
|
|
{% endif %}
|
|
}
|
|
|
|
# Wildcard certificate for all services
|
|
*.{{ caddy_domain }}:{{ caddy_https_port }} {
|
|
tls {
|
|
dns gandi {env.GANDI_BEARER_TOKEN}
|
|
}
|
|
|
|
{% for service in caddy_services %}
|
|
@{{ service.name }} host {{ service.host }}
|
|
handle @{{ service.name }} {
|
|
{% if service.cache_policy | default('') == 'spa' %}
|
|
# SPA cache policy: hashed static assets are immutable, HTML must revalidate.
|
|
# Prevents stale HTML from referencing chunk hashes that no longer exist.
|
|
@{{ service.name }}_static path /static/dist/*
|
|
header @{{ service.name }}_static Cache-Control "public, max-age=31536000, immutable"
|
|
@{{ service.name }}_html path /if/*
|
|
header @{{ service.name }}_html Cache-Control "no-cache"
|
|
{% endif %}
|
|
{% if service.backend.startswith('https://') %}
|
|
reverse_proxy {{ service.backend }} {
|
|
# Caddy v2.11+ rewrites Host to upstream for HTTPS backends.
|
|
# Preserve the original Host so services see *.ops.eblu.me.
|
|
header_up Host {http.request.host}
|
|
}
|
|
{% else %}
|
|
reverse_proxy {{ service.backend }}
|
|
{% endif %}
|
|
}
|
|
|
|
{% endfor %}
|
|
# Fallback for unknown hosts
|
|
handle {
|
|
respond "Unknown service" 404
|
|
}
|
|
}
|
|
|
|
# Base domain (ops.eblu.me)
|
|
{{ caddy_domain }}:{{ caddy_https_port }} {
|
|
tls {
|
|
dns gandi {env.GANDI_BEARER_TOKEN}
|
|
}
|
|
|
|
respond "blumeops services - use a subdomain (e.g., forge.{{ caddy_domain }})"
|
|
}
|