Embed Openship
Create a native installation and deploy through shared platform operations.
Use createShip() when your Node application owns the installation. It creates an isolated worker,
storage, and providers. Native operations call the shared engine without an API HTTP listener.
Create an installation and deploy
Install the SDK, then set OPENSHIP_ENCRYPTION_KEY to a persistent
secret of at least 32 bytes. Keep that key when reopening the database.
import { randomUUID } from "node:crypto";
import { resolve } from "node:path";
import { createShip, type VerifiedIdentity } from "openship/native";
const encryptionKey = process.env.OPENSHIP_ENCRYPTION_KEY;
if (!encryptionKey) throw new Error("Set OPENSHIP_ENCRYPTION_KEY");
const sessions = new Map<string, VerifiedIdentity>();
const stateDirectory = resolve("./ship-state");
const ship = await createShip({
instanceId: "my-product",
stateDirectory,
storage: { driver: "pglite", dataDir: resolve(stateDirectory, "database") },
encryptionKey,
runtime: "bare",
routing: "none",
policy: { allowHostExecution: true },
administration: true,
identity: { resolve: async (assertion: string) => sessions.get(assertion) ?? null },
});
try {
if (!ship.operator) throw new Error("Host administration is required for this example");
const person = await ship.operator.ensureIdentity({
issuer: "my-product",
subject: "customer-123",
email: "[email protected]",
});
const assertion = randomUUID();
sessions.set(assertion, { user: person.user, sessionId: assertion });
await ship.start();
const customer = await ship.scope({
identity: assertion,
organizationId: person.personalOrganizationId,
});
const submitted = await customer.deploy({
name: "generated-app",
source: { type: "files", files: { "index.html": "<h1>Hello</h1>" } },
});
const outcome = await customer
.deployment(submitted.deployment_id)
.wait({ timeoutMs: 60_000 });
if (!outcome.success) throw new Error(outcome.message ?? outcome.status);
console.log(submitted.project_id, outcome.status);
} finally {
await ship.close({ mode: "drain" });
}This uses a demo session map. An embedding application should verify assertions through its own authentication service; see identities and scopes.
Runtime choices
| Choice | Behavior |
|---|---|
bare with routing: "none" | Build and manage local workloads without setting up managed routing. A static release has no public URL. |
bare or docker with managed routing | Use the existing local runtime and edge providers. Host setup requires explicit execution policy. |
| Registered server or Cloud provider | Use configured infrastructure and its capability checks. See compatibility. |
allowHostExecution: true permits host builds. Organization scopes authorize operations; they do not
sandbox generated application code. Choose providers suitable for the workloads your application accepts.
Continue
- Lifecycle and configuration: storage, keys, startup, and shutdown.
- Users and organizations: verified identities and tenant scopes.
- Runnable example: deploy twice, reopen state, and remove the project.
- Operator reference: trusted installation administration.