v1.19.0
[1.19.0] — 2026-08-13
Adds iblai infra spa — run a customised copy of a deployed SPA alongside the original, on its own port and its own domain, without touching the one the platform depends on.
iblai infra spa clone <name> # prompts for source, name, domain
iblai infra spa list <name> # what's deployed, with ports
iblai infra spa remove <name> --spa <clone>Also reachable from iblai infra configure <name>. Only the tagged Ansible role re-runs — no re-provisioning, no secret rotation.
Added
iblai infra spa clone <name>— picks the source from what is actually deployed on the server, allocates the next free port from 5060 (the stock SPAs hold 5000-5009), asks for the domain, and shows the whole plan before doing anything.--from,--as,--domainand--portskip the prompts.iblai infra spa list <name>— what is deployed, with ports, marking which are stock and which are clones.iblai infra spa remove <name> --spa <clone>— removes the containers, the nginx block and the directory. Refuses the platform's own SPAs, since the same role pointed atmentororauthwould delete the real one.- The clone copies the source's running environment file, not a re-render from
config.yml, so it starts identical to what the source is actually serving including anything hand-edited on the box.PORTis then rewritten to the clone's own port — written rather than substituted, because deployments older than the template that introducedPORThave no line to replace, and a missingPORTleaves the clone listening on the source's port while compose publishes a different one: up, healthy-looking, and serving nothing. The clone is probed on its own port before the run is called a success. - Server blocks go in
/etc/nginx/conf.d/custom_domains/, which the platform's proxy sync already excludes, so they surviveibl global-proxyregenerating everything else. The stocknginx.confincludesconf.d/*.confwithout recursing, so the include for that subdirectory is added idempotently.nginx -truns before every reload, since this happens against a live server. - Served over HTTP; put the domain behind whatever already terminates TLS for the environment.
- Names and domains are checked against an allowlist before they are used. Both names become filesystem paths that the role acts on with elevated privileges, and the domain is written into an nginx server block, so a name has to be lowercase letters, numbers, hyphens and underscores, and a domain has to be a plain hostname. The same checks are asserted inside the roles, so they hold regardless of the caller.
Upgrading
No migration. Existing projects are unaffected — the two new roles are gated off and inert during a normal setup.
uv tool upgrade iblai-infra # or: uv tool install --force git+https://github.com/iblai/infra-cli
iblai --version # iblai v1.19.0Test count: 894 passing.
Full changelog: v1.18.1...v1.19.0