Skip to content

Releases: sireto/custom-domain

0.8.0

Choose a tag to compare

@sireto-dev sireto-dev released this 04 Oct 09:52
6e60f43

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/backup streams a pg_dump. It's off unless you set OPERATOR_BACKUP=true, because a dump holds every application's data.
  • A per-key limit on v1 API requests (#67): V1_REQUESTS_PER_MINUTE caps each API key's requests in any 60 seconds. Over the limit, requests get 429 rate_limited with Retry-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 at GET /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.

The SDK custom-domain-sdk 0.8.0 is released with it, with no changes to its interface.

0.7.0

Choose a tag to compare

@sireto-dev sireto-dev released this 04 Oct 05:58
0dcc462

What's new

  • Operator API (#55). /operator/v1 manages applications, origins and credentials over HTTP, the same as the custom-domain command.
    • It is enabled by OPERATOR_API_TOKEN and limited to OPERATOR_ALLOWED_IPS through the edge.
    • Failed tokens are throttled, and every call is audited.
    • See docs/operator-api.md.
  • Domain limits (#57). MAX_DOMAINS caps live domains per deployment, and max_domains caps 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%.
  • Installer settings (#58). install.sh takes OPERATOR_API_TOKEN, OPERATOR_ALLOWED_IPS and MAX_DOMAINS, so automated installs can set them from the first boot.
  • Operator token rotation (#59). PUT /operator/v1/token replaces the operator token without a restart, and the previous token stops working.
    • custom-domain operator token-status shows which token is in force.
    • custom-domain operator reset-token restores OPERATOR_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

Choose a tag to compare

@sireto-dev sireto-dev released this 27 Sep 17:10
e198c54

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.access audit line and the reconciler's progress; they now reach stderr at LOG_LEVEL (default INFO).
  • The access log names the credential (credential=<id>); the key prefix it logged was masked by the log redactor. Revoke a leaked key with custom-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

Choose a tag to compare

@sireto-dev sireto-dev released this 27 Sep 13:32
0c4ee7b

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 call https://<edge hostname>/v1 with 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 an app.v1.access log 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 gets 429 with Retry-After before 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

Choose a tag to compare

@sireto-dev sireto-dev released this 26 Sep 18:57
02aa829

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.deleted events, and domain purge-tombstones removes it after retention. Deleted applications are listed and readable in the portal and with application 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

Choose a tag to compare

@sireto-dev sireto-dev released this 26 Sep 15:34
cc3ec72

Image: ghcr.io/sireto/custom-domain:0.4.1 · SDK: custom-domain-sdk==0.4.1

Changes since 0.4.0

  • Shared EDGE_ASK_URL across containers (#40). The production Compose file set EDGE_ASK_URL only 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 doctor compares 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

Choose a tag to compare

@sireto-dev sireto-dev released this 26 Sep 14:33
396a92e

One version for the service image and the SDK.

  • Image: ghcr.io/sireto/custom-domain:0.4.0 (also 0.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.yaml at this tag pins CUSTOM_DOMAIN_VERSION=0.4.0; existing installations upgrade with custom-domain upgrade 0.4.0

Changes since 0.3.1

  • Operator portal at /portal of the management API: every custom-domain action 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_IPS exposes the portal at https://<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_HOSTNAME is 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-compose after 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

Choose a tag to compare

@sireto-dev sireto-dev released this 26 Sep 10:24
d5b6093

First release under the unified scheme: one version for the service image and the SDK.

  • Image: ghcr.io/sireto/custom-domain:0.3.1 (also 0.3, latest)
  • SDK: pip install custom-domain-sdk==0.3.1
  • Installer: deploy/cloud-init.yaml at this tag pins CUSTOM_DOMAIN_VERSION=0.3.1

Changes since v0.3.0

  • custom-domain doctor looks 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.toml files 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.