Jul 27
2026
A security fix for the edge, migrations that behave like a native repo project, and a batch of routing/reliability fixes.
Security
- Unrouted HTTPS hosts are rejected, not cross-served — the edge now owns a
443default server that refuses any hostname it doesn't route (one you removed, never added, or merely pointed at the box's IP). Before this, such a request fell through to the first-loaded vhost and was served another app's certificate and backend. Applies automatically on the next deploy, on both the bare and containerized edge. Critical — see the in-app advisory.
Migrations
- A migrated project is now a native repo project — a migrated compose stack
redeploys like any repo project: it reclones and rebuilds
build:services and pullsimage:ones, instead of failing on a frozen build tag (404 no such image). The running image is reused only once, at cutover. - The whole compose is the deployment plan — the migrate screen lists every
repo compose service, not just running containers, so a service with no
container (e.g.
redis, or an app that wasn't up) is built/pulled and routed like the rest, with its env and route editable on the card. - Reused databases stay reachable — a reused container is joined to the new
project's network under its service-name alias, so a freshly-built app resolves
postgres:5432by name, exactly like a native deploy. - A migrated service reports the container it really runs as — service state
is read live from the host and matched by identity (label →
openship-<slug>-<svc>name → tracked id → compose labels), so a container Openship adopted in place (its docker labels still name the previous project) no longer shows "Stopped" while it serves traffic. Each run's log now ends with the container, state and match for every service.
Fixes
- Service state is never guessed from the database — Start/Stop/Restart, logs,
terminal, backup/restore and volume sizes resolve the container against the host
first, so a redeploy that replaced it no longer leaves them failing with
no such container— or, on Start, launching a duplicate container beside the running one. A crash-looping container now reads Restarting instead of a green "Running", and an unreachable host reads Unknown instead of echoing the last deploy status. - Removing a route never wrongly demands Openship Cloud — the free-domain gate classifies by hostname, so removing a custom-domain route (or any route) is no longer blocked by an unrelated free subdomain still in the set.
- Deleting a service can't hang — runtime teardown is time-bounded, so a slow or unreachable server no longer strands the delete before the record is removed.