# Openship Platform Factory Runtime Configuration: How the Control-Plane Boots Across Deployment Targets

> Explore Openship Platform factory runtime configuration. Learn how the control-plane boots across cloud, selfhosted, and desktop targets with Docker or bare modes.

- Repository: [oblien/openship](https://github.com/oblien/openship)
- Tags: internals
- Published: 2026-08-19

---

**The Openship Platform factory runtime configuration uses a tree-shakable `createPlatform()` factory in [`platform.ts`](https://github.com/oblien/openship/blob/main/platform.ts) to compose a concrete `Platform` instance—bundling Runtime, Routing, SSL, System, and Executor layers—based on the deployment target (`cloud`, `selfhosted`, or `desktop`) and runtime mode (`docker` or `bare`).**

The **Openship** control-plane from the `oblien/openship` repository relies on a sophisticated factory pattern to handle diverse deployment scenarios. Understanding the Openship Platform factory runtime configuration is essential for developers extending the platform or debugging startup behavior, as it determines how the system initializes Docker containers, manages SSL certificates, and executes commands across cloud, self-hosted, and desktop environments.

## How the Factory Works

The factory implementation in [`packages/adapters/src/platform.ts`](https://github.com/oblien/openship/blob/main/packages/adapters/src/platform.ts) serves as the single entry point for platform initialization. It reads a configuration object and assembles the appropriate concrete implementations for the target environment.

### Configuration Input (PlatformConfig)

The factory expects a **`PlatformConfig`** object that specifies the deployment characteristics. According to the type definition at lines 56‑84 of [`platform.ts`](https://github.com/oblien/openship/blob/main/platform.ts), this includes:

- **`target`** (`cloud` | `selfhosted` | `desktop`) – Determines the overall deployment model
- **`runtime`** (`docker` | `bare`) – Optional, only applicable for `selfhosted` targets
- **Connection details** – Docker socket paths, SSH credentials, Nginx options, or cloud API tokens

This configuration drives the conditional instantiation logic throughout the factory.

### Target Selection Logic

At lines 28‑38 of [`platform.ts`](https://github.com/oblien/openship/blob/main/platform.ts), the `createPlatform()` function uses a switch statement to branch into specialized factory functions:

```typescript
switch (config.target) {
  case "cloud":    return createCloudPlatform(config);
  case "desktop":  return createDesktopPlatform(config);
  default:         return createSelfHostedPlatform(config);
}

```

Each branch returns a fully configured `Platform` object tailored to the target environment.

### Self-Hosted Path Details

The `createSelfHostedPlatform()` function handles the most complex initialization sequence. It determines whether the control-plane runs **locally** or remotely via **SSH**, then instantiates the appropriate **command executor** (`LocalExecutor` or pooled `SshExecutor`) through `createExecutor()`.

At lines 70‑79, the factory selects the runtime implementation:

```typescript
// Runtime selection (platform.ts lines 70-79)
const runtime = config.runtime === "docker"
  ? await DockerRuntime.create(config, executor)
  : new BareRuntime(config, executor);

```

Following runtime creation, lines 91‑98 invoke **`createInfraProvider`** to assemble routing and SSL handling, typically using `TraefikProvider` for Docker environments or Nginx configurations for bare-metal setups. The factory also instantiates a **`SystemManager`** to perform prerequisite checks and install required dependencies (Docker, Git, Node.js) unless running in Docker-edge mode.

### Cloud and Desktop Paths

For **cloud** deployments, the factory returns lightweight stubs: `CloudRuntime` paired with `CloudInfraProvider`, which delegates infrastructure management to the Oblien API rather than manipulating local systems. **Desktop** targets use `BareRuntime` with a `NoopInfraProvider`, as local development requires no reverse-proxy or SSL provisioning.

### Singleton Caching Mechanism

After creation, the platform instance is stored in a module-level variable **`_platform`** (lines 81‑93). The system exposes a synchronous **`getPlatform()`** accessor for the rest of the codebase to retrieve the initialized instance without async overhead. For testing scenarios, **`resetPlatform()`** clears the cache to allow re-initialization (lines 95‑105).

## Platform Layers and Responsibilities

The Openship Platform factory runtime configuration composes five distinct layers, selecting concrete implementations based on the deployment matrix:

| Layer | Responsibility | Self-Hosted (Docker) | Self-Hosted (Bare) | Cloud | Desktop |
|-------|---------------|---------------------|-------------------|-------|---------|
| **Runtime** | Build, deploy, and lifecycle management | `DockerRuntime` (Dockerode, socket/SSH/TLS) | `BareRuntime` (local/SSH executor) | `CloudRuntime` (Oblien API) | `BareRuntime` (local executor) |
| **Routing** | Reverse-proxy configuration | `TraefikProvider` (writes YAML via executor) | `TraefikProvider` | `CloudInfraProvider` (API) | `NoopInfraProvider` |
| **SSL** | TLS provisioning | `TraefikProvider` (ACME) | `TraefikProvider` | `CloudInfraProvider` | `NoopInfraProvider` |
| **System** | Prerequisite checks and installers | `SystemManager` (docker, git, node) | `SystemManager` | *none* | *none* |
| **Executor** | Command execution on target host | `LocalExecutor` or `SshExecutor` | `LocalExecutor` | *none* | *none* |

The factory is **tree-shakable**, meaning only the code paths required for the selected target are imported into the final bundle. This keeps server startup times minimal and reduces memory footprint across different deployment scenarios.

## Implementation Example: Initializing and Using the Platform

The following pattern demonstrates how to initialize the Openship Platform factory runtime configuration and interact with the composed platform instance:

```typescript
// 1️⃣ Initialise the platform on server start (once)
import { initPlatform } from "@repo/adapters";

await initPlatform({
  target: "selfhosted",      // or "cloud"/"desktop"
  runtime: "docker",        // only for self‑hosted
  docker: { socketPath: "/var/run/docker.sock" },
  nginx: { /* Nginx options */ },
  // Optional SSH config for remote self‑hosted boxes
  // ssh: { host: "my.server", user: "root", privateKey: "..."}
});

// 2️⃣ Obtain the cached platform anywhere in the codebase
import { getPlatform } from "@repo/adapters";

const { runtime, routing, ssl, system, executor } = getPlatform();

// 3️⃣ Build a project (example from the CLI)
await runtime.build(buildConfig, (msg) => console.log(msg));

// 4️⃣ Register a reverse‑proxy route
await routing.registerRoute({
  domain: "app.example.com",
  targetUrl: "http://127.0.0.1:3000",
  tls: true,
});

// 5️⃣ Provision an TLS certificate (ACME via Traefik/OpenResty)
await ssl.provisionCert("app.example.com");

// 6️⃣ Run a one‑off command on the target host (e.g. git pull)
if (executor) {
  const result = await executor.exec("git -C /srv/app pull");
  console.log(result);
}

```

This code works identically across Docker-based, Bare-runtime, Cloud, or Desktop deployments because the factory abstracts the concrete implementations behind stable interfaces.

## Key Source Files

Understanding the Openship Platform factory runtime configuration requires familiarity with these specific modules:

- **[`packages/adapters/src/platform.ts`](https://github.com/oblien/openship/blob/main/packages/adapters/src/platform.ts)** – Contains the factory implementation (`createPlatform`, `initPlatform`, `getPlatform`), the `Platform` type definition, and the singleton cache logic
- **[`packages/adapters/src/runtime/docker.ts`](https://github.com/oblien/openship/blob/main/packages/adapters/src/runtime/docker.ts)** – Implements `DockerRuntime` with methods for building images, deploying containers, and executing health checks via Dockerode
- **[`packages/adapters/src/runtime/bare.ts`](https://github.com/oblien/openship/blob/main/packages/adapters/src/runtime/bare.ts)** – Implements `BareRuntime` for executor-based process management on host systems without containerization
- **[`packages/adapters/src/infra/traefik.ts`](https://github.com/oblien/openship/blob/main/packages/adapters/src/infra/traefik.ts)** – Defines `TraefikProvider`, which writes YAML configuration files to the target host via the executor to manage reverse-proxy rules
- **[`packages/adapters/docs/ARCHITECTURE.md`](https://github.com/oblien/openship/blob/main/packages/adapters/docs/ARCHITECTURE.md)** – High-level architectural overview mapping the relationship between factory components
- **[`apps/api/src/lib/deployment-runtime.ts`](https://github.com/oblien/openship/blob/main/apps/api/src/lib/deployment-runtime.ts)** – Reference implementation showing how the API layer consumes the platform instance

## Summary

- The **Openship Platform factory runtime configuration** centers on the `createPlatform()` factory function in [`packages/adapters/src/platform.ts`](https://github.com/oblien/openship/blob/main/packages/adapters/src/platform.ts), which switches between `cloud`, `desktop`, and `selfhosted` initialization paths.
- **`PlatformConfig`** drives the composition of five layers: Runtime, Routing, SSL, System, and Executor, with implementations ranging from `DockerRuntime` to `BareRuntime` and `TraefikProvider` to `NoopInfraProvider`.
- The factory instantiates either a **`LocalExecutor`** or **`SshExecutor`** for self-hosted targets to handle remote command execution, while cloud deployments use API-based providers.
- After async initialization, **`getPlatform()`** provides synchronous access to the cached platform instance throughout the application lifecycle.
- The architecture is **tree-shakable**, ensuring that only the code necessary for the specific deployment target is loaded into memory.

## Frequently Asked Questions

### What is the role of `createPlatform()` in Openship?

`createPlatform()` is the central factory function exported from [`packages/adapters/src/platform.ts`](https://github.com/oblien/openship/blob/main/packages/adapters/src/platform.ts) (lines 28‑38). It examines the `target` property of the `PlatformConfig` object and delegates to specialized creators like `createCloudPlatform()`, `createDesktopPlatform()`, or `createSelfHostedPlatform()` to assemble the correct combination of runtime, routing, and executor components for the deployment environment.

### How does Openship handle different deployment targets?

Openship handles targets through conditional instantiation. For **`selfhosted`**, it constructs either a `DockerRuntime` or `BareRuntime` paired with a `SystemManager` and `TraefikProvider`. For **`cloud`**, it returns `CloudRuntime` and `CloudInfraProvider` stubs that communicate with the Oblien API. For **`desktop`**, it uses `BareRuntime` with a `NoopInfraProvider` since no reverse-proxy or system management is required locally.

### What is the difference between `DockerRuntime` and `BareRuntime`?

**`DockerRuntime`**, defined in [`packages/adapters/src/runtime/docker.ts`](https://github.com/oblien/openship/blob/main/packages/adapters/src/runtime/docker.ts), uses Dockerode to interact with Docker sockets or remote daemons over SSH/TLS for containerized builds and deployments. **`BareRuntime`**, from [`packages/adapters/src/runtime/bare.ts`](https://github.com/oblien/openship/blob/main/packages/adapters/src/runtime/bare.ts), executes commands directly on the host system using a configured executor (local or SSH) without containerization, suitable for legacy servers or desktop environments.

### How do I access the platform instance after initialization?

Call the synchronous **`getPlatform()`** function imported from `@repo/adapters`. This retrieves the module-level singleton created by the initial `initPlatform()` call. If you need to reinitialize—for example, during integration testing—use **`resetPlatform()`** to clear the internal `_platform` cache before calling `initPlatform()` again with new configuration.