Releases: sireto/custom-domain
Release list
0.8.0
Before upgrading
Back up the database first. Migrations 0009 and 0010 run when the api container starts. They only add columns and tables, but take a backup first anyway: see operations.md.
custom-domain upgrade 0.8.0
New
- Database backups over the operator API (#61):
GET /operator/v1/backupstreams apg_dump. It's off unless you setOPERATOR_BACKUP=true, because a dump holds every application's data. - A per-key limit on v1 API requests (#67):
V1_REQUESTS_PER_MINUTEcaps each API key's requests in any 60 seconds. Over the limit, requests get429 rate_limitedwithRetry-After. It's off by default. - Per-application request limits at the edge (#68, #70):
- Cap one application's proxied requests per minute and per second, across all of its hostnames.
- Set them with
custom-domain application set-rate-limit, in the portal (Settings) or through the operator API. - Over the limit, requests get 429 with
Retry-After. Certificates, DNS checks and the v1 API aren't affected. - The edge image now includes Caddy's rate-limit module.
- Upgrade the edge before setting a limit. An older edge can't load the configuration, so every reconcile fails until it's upgraded. Lifting the limit recovers at once.
- Per-application traffic (#69):
- Proxied requests and response bytes per UTC day, shown by
custom-domain application traffic, on the portal's Traffic tab, and atGET /operator/v1/applications/{slug}/traffic. - Bytes are response body bytes: headers and uploads aren't counted.
- Counting starts once the edge runs 0.8.0.
- Proxied requests and response bytes per UTC day, shown by
The SDK custom-domain-sdk 0.8.0 is released with it, with no changes to its interface.
0.7.0
What's new
- Operator API (#55).
/operator/v1manages applications, origins and credentials over HTTP, the same as thecustom-domaincommand.- It is enabled by
OPERATOR_API_TOKENand limited toOPERATOR_ALLOWED_IPSthrough the edge. - Failed tokens are throttled, and every call is audited.
- See docs/operator-api.md.
- It is enabled by
- Domain limits (#57).
MAX_DOMAINScaps live domains per deployment, andmax_domainscaps them per application. Set them from the CLI, the portal or the operator API.- At a limit, a new registration gets
409 domain_limit_reached, and existing domains are never switched off. - The doctor warns at 80%.
- At a limit, a new registration gets
- Installer settings (#58).
install.shtakesOPERATOR_API_TOKEN,OPERATOR_ALLOWED_IPSandMAX_DOMAINS, so automated installs can set them from the first boot. - Operator token rotation (#59).
PUT /operator/v1/tokenreplaces the operator token without a restart, and the previous token stops working.custom-domain operator token-statusshows which token is in force.custom-domain operator reset-tokenrestoresOPERATOR_API_TOKEN.
Upgrading
custom-domain upgrade 0.7.0
- Migrations. The api container applies migrations 0007 and 0008 at start. Both only add things.
- Settings. No new setting is required.
Image: ghcr.io/sireto/custom-domain:0.7.0. SDK: pip install custom-domain-sdk==0.7.0.
0.6.1
Image: ghcr.io/sireto/custom-domain:0.6.1 · SDK: custom-domain-sdk==0.6.1
Fixes found by deploying the cloud templates on AWS, Azure and Google Cloud (#53):
- Service logs are emitted. The containers dropped every INFO record, including 0.6.0's
app.v1.accessaudit line and the reconciler's progress; they now reach stderr atLOG_LEVEL(defaultINFO). - The access log names the credential (
credential=<id>); the key prefix it logged was masked by the log redactor. Revoke a leaked key withcustom-domain credential revoke --application <slug> --id <id>. - Container logs rotate (5 × 10 MB per service). An unmodified Compose file from an earlier release is replaced on upgrade; a customised one stops for a merge.
- The doctor fails on an ACME email Let's Encrypt refuses (a reserved domain such as
example.net, or not an address), which meant no certificate was ever issued while the doctor said OK. - The installer summary behind NAT shows the public address for the A record, and no longer prints the edge hostname twice.
Upgrading
custom-domain upgrade 0.6.1
No database migration. The Compose file changes (log rotation).
0.6.0
Image: ghcr.io/sireto/custom-domain:0.6.0 · SDK: custom-domain-sdk==0.6.0
Changes since 0.5.0
- The v1 API through the edge (#47). With
PUBLIC_API=true, applications callhttps://<edge hostname>/v1with their credential and need no reverse proxy of their own; nothing else of the API is routed, and the configuration gateway accepts the route only in its exact shape. New installations turn it on; upgrades keep it off unless given. Each v1 call writes anapp.v1.accesslog line with the real client address and the key prefix. - Throttled failed authentication (#50). A client may fail v1 authentication 30 times a minute (
V1_AUTH_FAILURES_PER_MINUTE), then gets429withRetry-Afterbefore any database work. Only identifiable clients are limited (the address the edge forwards, or a public direct peer); an operator's own proxy is not. - Fix (#47): migrations no longer disable loggers that were set up before them.
Upgrading
custom-domain upgrade 0.6.0 # keeps the API private
PUBLIC_API=true custom-domain upgrade 0.6.0 # also serves https://<edge hostname>/v1
No new database migration since 0.5.0.
0.5.0
Image: ghcr.io/sireto/custom-domain:0.5.0 · SDK: custom-domain-sdk==0.5.0
Changes since 0.4.1
- Redesigned operator portal (#43). Sidebar navigation, per-application tabs (overview, domains, origins, API keys, webhooks, settings), plain-language statuses, a setup checklist, and DNS status per record for customer hostnames and for the edge's own names, with an on-demand reachability check.
- Management for every object (#43). Rename and delete applications; delete origins, revoked or expired API keys and revoked webhooks; webhook management with delivery replay; hostname and workspace search.
- Deletion keeps the audit trail (#43). A deleted application is archived: its hostnames become 90-day tombstones with their history, its webhooks still receive the
domain.deletedevents, anddomain purge-tombstonesremoves it after retention. Deleted applications are listed and readable in the portal and withapplication list --deleted. - New CLI commands (#43):
application rename,application delete,application list --deleted,origin retire,origin delete,credential delete. - Docs (#42): the one-time installer run for hosts installed before 0.4.0.
Upgrading
custom-domain upgrade 0.5.0
Adds database migration 0006 (two nullable columns on applications), applied by the api container on start. It is backward compatible with 0.4.x containers during the restart.
0.4.1
Image: ghcr.io/sireto/custom-domain:0.4.1 · SDK: custom-domain-sdk==0.4.1
Changes since 0.4.0
- Shared
EDGE_ASK_URLacross containers (#40). The production Compose file setEDGE_ASK_URLonly on the edge, so the api and worker reconcilers proposed a TLS automation block the edge's gateway rejected and the edge served no TLS. The api and worker now carry the same value, and the deploy tests require the gateway-checked settings to agree across the three services. - Doctor edge-config check (#40).
custom-domain doctorcompares the edge's running configuration with what the reconciler wants and names the mismatch when reconciles are being rejected. - Doctor IPv6 handling (#39). A CNAME target address the doctor's host cannot route to is reported as
unverifiable(a warning) instead of a failure; unroutable IPv4 still fails.
Upgrading
custom-domain upgrade 0.4.1
The upgrade refreshes the Compose file; an EDGE_ASK_URL line added to .env as a workaround for #40 can stay or go.
0.4.0
One version for the service image and the SDK.
- Image:
ghcr.io/sireto/custom-domain:0.4.0(also0.4,latest) - SDK:
pip install custom-domain-sdk==0.4.0(no code changes since 0.3.1; the version moves with the service) - Installer:
deploy/cloud-init.yamlat this tag pinsCUSTOM_DOMAIN_VERSION=0.4.0; existing installations upgrade withcustom-domain upgrade 0.4.0
Changes since 0.3.1
- Operator portal at
/portalof the management API: everycustom-domainaction in a browser, behind one operator password with a signed session, CSRF tokens, rate-limited sign-in and secrets shown once (#35). - Allowlisted access through the edge:
PORTAL_ALLOWED_IPSexposes the portal athttps://<edge name>/portal, enforced by Caddy on the real peer and again by the API; the configuration gateway validates the routes against what the API states, so changing the allowlist needs no edge restart (#36). - The edge's own name:
EDGE_HOSTNAMEis the default CNAME target, certified and serving the health path and the portal from the first start; the doctor checks it (#37). - Installer as the upgrade path:
custom-domain upgrade <version>re-runs the installer from a release; the Compose file is refreshed when pristine and a customized one is never overwritten (two checksum baselines,--accept-composeafter a merge); explicit settings win over the cloud-init config file (#37). - Production Compose fix: the api and worker containers carry
EDGE_ASSERT_UPSTREAM, without which the gateway rejected every application route once a domain became ready; the management API is published on the host's loopback for the SSH tunnel (#36).
0.3.1
First release under the unified scheme: one version for the service image and the SDK.
- Image:
ghcr.io/sireto/custom-domain:0.3.1(also0.3,latest) - SDK:
pip install custom-domain-sdk==0.3.1 - Installer:
deploy/cloud-init.yamlat this tag pinsCUSTOM_DOMAIN_VERSION=0.3.1
Changes since v0.3.0
custom-domain doctorlooks CNAME targets up in public DNS instead of the container's resolver (a server named after the edge no longer produces a false failure), probes every published address with the name as SNI, and uses the standard global-address classification (#32).- Former CNAME targets stay monitored and keep their certificates while live claims still name them (#32).
custom-domain application set-cname-target, with optional--reissue-claims(#32).- Release scheme: a bare version tag releases the image and the SDK together; both publish workflows verify the tag against both
pyproject.tomlfiles and the built SDK's runtime version (#34). The SDK version moves from 0.1.0 to 0.3.1 to match the service; no SDK code changes since 0.1.0.