# Openship Deployment Modes: Compose vs Bare Cloud Runtime

> Explore Openship deployment modes Compose vs Bare Cloud Runtime. Understand how Openship selects the right runtime for your needs based on OS and Docker.

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

---

**Openship supports two distinct deployment modes—Compose (a Docker‑Compose stack with host‑networked edge proxy) and Bare (a single embedded process)—with the CLI automatically selecting the appropriate runtime based on operating system capabilities and Docker availability.**

Openship, the open‑source application deployment platform maintained by **oblien/openship**, provides architectural flexibility through its dual‑mode control plane. Understanding how Openship deployment modes compose bare cloud runtime behavior allows platform engineers to optimize for either containerized density or lightweight portability across Linux, macOS, and Windows environments.

## Two Fundamental Deployment Architectures

Openship’s control plane operates in exactly two mutually exclusive modes, selected before installation begins.

| Mode | Runtime Environment | Database | Host Platform |
|------|---------------------|----------|---------------|
| **Compose** | Docker‑Compose stack (Postgres, Redis, API, dashboard, **OpenResty** edge) | Containerized Postgres | Linux only |
| **Bare** | Single long‑running **process service** | Embedded SQLite or Postgres | Linux, macOS, Windows |

The **Compose** mode provisions a full containerized stack defined in [`docker/docker-compose.yml`](https://github.com/oblien/openship/blob/main/docker/docker-compose.yml), binding privileged ports 80 and 443 directly to the host network. The **Bare** mode generates an OS‑specific service unit—managed by `systemd`, `launchd`, or Windows Scheduled Tasks—that runs the control plane as native processes without Docker.

## How the CLI Selects the Deployment Method

The decision logic resides in [`apps/cli/src/lib/up-plan.ts`](https://github.com/oblien/openship/blob/main/apps/cli/src/lib/up-plan.ts), specifically within the `planMethod` function. This utility evaluates three criteria in strict priority order: explicit user flags, host platform limitations, and Docker availability.

```typescript
// apps/cli/src/lib/up-plan.ts
export function planMethod(
  opts: { bare?: boolean; compose?: boolean },
  dockerUsable: boolean,
): { method: "compose" | "bare"; reason: string } {
  if (opts.bare) return { method: "bare", reason: "--bare was passed" };
  if (opts.compose) return { method: "compose", reason: "--compose was passed" };
  if (process.platform !== "linux") {
    return {
      method: "bare",
      reason: `the compose edge needs host networking, which Docker Desktop on ${process.platform} doesn't provide`,
    };
  }
  return dockerUsable
    ? { method: "compose", reason: "the default on Linux when Docker is usable" }
    : { method: "bare", reason: "Docker isn't usable here, so `up` falls back to the process service" };
}

```

**Priority hierarchy:**
1. **Explicit flags** – `--bare` forces Bare mode; `--compose` forces Compose mode.
2. **Platform constraint** – Non‑Linux systems (macOS, Windows) default to Bare because Docker Desktop lacks host networking required for the edge proxy.
3. **Docker detection** – On Linux, the CLI probes for a functional Docker installation; if absent, it falls back to Bare.

## Compose Mode: Docker‑Native Stack

When `planMethod` returns `"compose"`, the CLI invokes `composePlan` from [`apps/cli/src/lib/compose.ts`](https://github.com/oblien/openship/blob/main/apps/cli/src/lib/compose.ts) to generate the runtime artifacts.

### Stack Generation and Edge Routing

The `composePlan` function writes a [`docker-compose.yml`](https://github.com/oblien/openship/blob/main/docker-compose.yml) and `.env` file to the working directory, configuring:

- **Postgres** and **Redis** containers for state and caching.
- **API and dashboard** containers built from source.
- **OpenResty edge proxy** with host networking on ports 80 and 443.

Before installation, [`apps/cli/src/lib/edge-preflight.ts`](https://github.com/oblien/openship/blob/main/apps/cli/src/lib/edge-preflight.ts) probes the host to verify port availability. If ports 80 or 443 are occupied, the preview output warns of the conflict and suggests migration strategies.

### Installation Flow

The `planUp` implementation (lines 97‑104 of [`up-plan.ts`](https://github.com/oblien/openship/blob/main/up-plan.ts)) orchestrates the following sequence:

```bash
docker compose pull postgres redis
docker compose build   # builds API & edge images

docker compose up -d   # starts stack; edge binds :80/:443

```

Running `openship up` without flags on Linux triggers this flow automatically, installing Docker first if missing via `dockerInstallPreview`.

## Bare Mode: Embedded Process Service

When Docker is unavailable or the user specifies `--bare`, the CLI switches to `previewService` in [`apps/cli/src/lib/service.ts`](https://github.com/oblien/openship/blob/main/apps/cli/src/lib/service.ts).

### Service Architecture

**Bare mode** eliminates containerization entirely. The CLI generates platform‑specific service definitions:

- **Linux**: `systemd` user service (`openship.service`).
- **macOS**: `launchd` plist.
- **Windows**: Scheduled Task configuration.

The control plane runs as a single process with an embedded database stored in `DATA_DIR` (SQLite or a local Postgres instance). No host networking configuration is required, and the service starts via the native init system:

```bash

# Example installation step generated by installStepFor(svc.kind)

systemctl --user enable --now openship.service

```

### File System Preparation

The `planUp` function ensures prerequisite files exist before service launch:

- `AUTH_SECRET_FILE` and `INTERNAL_TOKEN_FILE` for API security.
- Database directory initialization.
- Dashboard asset download (skipped only if UI is explicitly disabled with `--no-ui`).

## Practical Usage Examples

### Deploy with Compose on Linux

Preview the installation plan without executing:

```bash
openship up --dry-run

```

Execute the full Docker‑Compose installation:

```bash
openship up

```

### Force Bare Mode on Any Platform

For lightweight deployments or non‑Linux systems:

```bash

# Preview the bare service configuration

openship up --bare --dry-run

# Install the native service

openship up --bare

```

### Manual Docker‑Compose Deployment

Bypass the CLI entirely using the repository’s canonical stack definition:

```bash
git clone https://github.com/oblien/openship.git
cd openship
cp .env.example .env
docker compose --env-file .env -f docker/docker-compose.yml up -d

```

### Project Deployment After Initialization

Once the control plane is operational, deploy applications using standard Openship commands:

```bash
cd my-app
openship init     # Link directory to project

openship deploy   # Build and run according to active mode

```

## Summary

- **Compose mode** provisions a full Docker‑Compose stack with an OpenResty edge proxy requiring Linux and host networking on ports 80/443, managed by [`apps/cli/src/lib/compose.ts`](https://github.com/oblien/openship/blob/main/apps/cli/src/lib/compose.ts).
- **Bare mode** runs the control plane as a single native process with an embedded database, compatible with Linux, macOS, and Windows, configured via [`apps/cli/src/lib/service.ts`](https://github.com/oblien/openship/blob/main/apps/cli/src/lib/service.ts).
- The `planMethod` function in [`apps/cli/src/lib/up-plan.ts`](https://github.com/oblien/openship/blob/main/apps/cli/src/lib/up-plan.ts) automatically selects the appropriate mode based on `--bare`/`--compose` flags, platform type, and Docker availability.
- Use `openship up --dry-run` to preview deployment actions before system modification.

## Frequently Asked Questions

### When should I choose Bare mode over Compose mode?

**Select Bare mode** when running Openship on macOS or Windows, on Linux servers without Docker installed, or when you require a minimal footprint without containerization overhead. **Choose Compose mode** for production Linux environments where you need the built‑in OpenResty edge proxy and prefer containerized isolation for the database and API components.

### Can I run Compose mode on macOS or Windows?

No. Compose mode relies on Docker host networking to bind ports 80 and 443, which Docker Desktop does not support on macOS or Windows. On these platforms, the CLI automatically defaults to Bare mode according to the platform check in `planMethod`.

### What happens if ports 80 or 443 are already occupied?

The `edge-preflight` module in [`apps/cli/src/lib/edge-preflight.ts`](https://github.com/oblien/openship/blob/main/apps/cli/src/lib/edge-preflight.ts) probes these ports during the dry‑run phase. If either port is in use, the preview output reports the conflict and suggests migration options, preventing the installation from proceeding until the port conflict is resolved.

### How does Openship handle Docker installation?

When running `openship up` on Linux without the `--bare` flag, the CLI executes `dockerInstallPreview` to check for Docker availability. If Docker is missing, the installation flow includes automatic Docker installation before pulling the Postgres and Redis images and building the API containers.