# Openship Main Directory Structure: A Complete Guide to the Monorepo Architecture

> Explore the Openship main directory structure, a pnpm workspace monorepo with apps, packages, and docker layers. Understand its architecture for flexible deployment.

- Repository: [oblien/openship](https://github.com/oblien/openship)
- Tags: architecture
- Published: 2026-07-31

---

**The Openship repository is organized as a pnpm workspace monorepo with three distinct architectural layers—`apps/` for interfaces, `packages/` for shared libraries, and `docker/` for infrastructure services—enabling both bare-metal and containerized deployment modes.**

Understanding the **Openship main directory structure** is essential for developers looking to self-host this open-source deployment platform or contribute to its codebase. The repository at `oblien/openship` follows a clean separation of concerns, splitting the control plane, user interfaces, and service stack into logical directories that support zero-config deployment pipelines.

## Architectural Overview of the Repository

The codebase implements a three-layer architecture that maps directly to the directory hierarchy:

### Control Plane Layer (Orchestrator)

The **control plane** handles project detection, container builds, routing configuration, and SSL termination. According to the source code in [`apps/cli/package.json`](https://github.com/oblien/openship/blob/main/apps/cli/package.json), this layer publishes the `openship` command-line interface that serves as the primary entry point for automation and CI/CD workflows. The orchestrator logic is also embedded in the desktop client at [`apps/desktop/src/preload/index.ts`](https://github.com/oblien/openship/blob/main/apps/desktop/src/preload/index.ts), which exposes API functionality to the Electron GUI.

### User-Facing Interface Layer

This layer provides three distinct interaction modes, all consuming the same backend API:

- **`apps/cli/`** – Scriptable commands for automation and continuous integration
- **`apps/desktop/`** – Electron-based GUI for macOS, Windows, and Linux
- **`apps/web/`** – React-based dashboard located in [`apps/web/src/lib/source.ts`](https://github.com/oblien/openship/blob/main/apps/web/src/lib/source.ts), which implements the core client library for browser-based management

### Service Stack Layer

The infrastructure layer defined in [`docker/docker-compose.yml`](https://github.com/oblien/openship/blob/main/docker/docker-compose.yml) provisions the runtime environment, including PostgreSQL, Redis, and an OpenResty edge reverse proxy. This stack supports **Compose mode** (full Docker deployment on Linux) and **Bare mode** (lightweight single process with embedded database for macOS/Windows).

## Openship Main Directory Structure Explained

The monorepo root uses [`package.json`](https://github.com/oblien/openship/blob/main/package.json) to define pnpm workspaces, allowing independent versioning while sharing TypeScript configuration via [`tsconfig.base.json`](https://github.com/oblien/openship/blob/main/tsconfig.base.json).

### Core Application Directories

The `apps/` directory contains the executable components:

```

apps/
├─ cli/              # CLI entry point (openship command)

│  └─ package.json   # Defines CLI dependencies and scripts

├─ desktop/          # Electron application

│  └─ src/preload/index.ts  # Preload script exposing main process API

└─ web/              # Next.js/React dashboard

   └─ src/lib/source.ts     # Core client library for API communication

```

### Shared Package Libraries

The `packages/` directory houses reusable modules consumed by multiple apps:

- **`packages/ui/`** – React component library (`src/components/`) providing cards, buttons, and status indicators used across both web and desktop interfaces
- **`packages/db/`** – Database abstraction layer configured in [`drizzle.config.ts`](https://github.com/oblien/openship/blob/main/drizzle.config.ts) using Drizzle ORM for PostgreSQL interactions
- **`packages/db-email/`** – Email service handling SMTP, DKIM, and SPF configurations

### Infrastructure and Configuration

Key operational files reside outside the application code:

- **[`docker/docker-compose.yml`](https://github.com/oblien/openship/blob/main/docker/docker-compose.yml)** – Defines the self-hosted stack including Postgres, Redis, API server, and the OpenResty edge router
- **[`docker/docker-compose.build.yml`](https://github.com/oblien/openship/blob/main/docker/docker-compose.build.yml)** – Variant for building from source rather than using pre-built images
- **[`scripts/install.sh`](https://github.com/oblien/openship/blob/main/scripts/install.sh)** – Convenience script for CLI installation referenced in the quick-start documentation

## Navigating the Codebase: Practical Examples

To explore the **Openship main directory structure** locally, clone the repository and inspect the workspace configuration:

```bash

# Clone the monorepo

git clone https://github.com/oblien/openship.git && cd openship

# Verify pnpm workspace structure

cat package.json | grep -A 10 "workspaces"

```

Installing dependencies across all workspace packages:

```bash

# Install root dependencies and link workspace packages

pnpm install

# Build the shared UI components

pnpm --filter @openship/ui build

# Run the CLI in development mode

pnpm --filter @openship/cli dev

```

Launching the complete service stack requires the Docker configuration files:

```bash

# Copy environment template

cp .env.example .env

# Start the full stack (Postgres, Redis, Edge router, API)

docker compose -f docker/docker-compose.yml up -d

```

Accessing the database layer programmatically:

```typescript
// Located in packages/db/drizzle.config.ts
import { drizzle } from 'drizzle-orm/postgres-js';
import postgres from 'postgres';

const client = postgres(process.env.DATABASE_URL);
const db = drizzle(client);

```

## Summary

- **The Openship main directory structure** follows a pnpm workspace monorepo pattern with logical separation between `apps/` (interfaces), `packages/` (libraries), and `docker/` (infrastructure).
- **Key entry points** include [`apps/cli/package.json`](https://github.com/oblien/openship/blob/main/apps/cli/package.json) for command-line operations and [`apps/web/src/lib/source.ts`](https://github.com/oblien/openship/blob/main/apps/web/src/lib/source.ts) for the web dashboard client library.
- **Database configuration** is centralized in [`packages/db/drizzle.config.ts`](https://github.com/oblien/openship/blob/main/packages/db/drizzle.config.ts), ensuring consistent ORM usage across the control plane and interface layers.
- **Deployment flexibility** is achieved through [`docker/docker-compose.yml`](https://github.com/oblien/openship/blob/main/docker/docker-compose.yml) (Compose mode) and bare-metal execution via the desktop and CLI applications.
- **Code reuse** is maximized through the `packages/ui/` component library, shared TypeScript configurations, and unified API client implementations.

## Frequently Asked Questions

### Where is the main CLI entry point located in the Openship repository?

The CLI entry point is defined in [`apps/cli/package.json`](https://github.com/oblien/openship/blob/main/apps/cli/package.json), which configures the `openship` command executable. The package exports binary commands for `openship` and `openship-dev` (development mode), with the core orchestration logic implemented in TypeScript files within the same directory.

### How does the web dashboard communicate with the backend services?

The web dashboard uses the client library implemented in [`apps/web/src/lib/source.ts`](https://github.com/oblien/openship/blob/main/apps/web/src/lib/source.ts) to communicate with the Openship API. This library handles authentication, project management, and deployment triggers, consuming the same REST endpoints exposed by the control plane layer that serves the CLI and desktop applications.

### What is the purpose of the `packages/db` directory in the Openship structure?

The `packages/db/` directory contains the database abstraction layer, including [`drizzle.config.ts`](https://github.com/oblien/openship/blob/main/drizzle.config.ts) for ORM configuration and schema definitions for PostgreSQL. This shared package ensures consistent database access patterns across the CLI, desktop, and web applications, preventing schema drift and centralizing migration logic.

### Can I run Openship without Docker by using only the source code in the `apps/` directory?

Yes, the repository supports **Bare mode** operation through the desktop application (`apps/desktop/`) and CLI (`apps/cli/`), which can run as lightweight processes with embedded databases. While [`docker/docker-compose.yml`](https://github.com/oblien/openship/blob/main/docker/docker-compose.yml) provides the full service stack for Linux servers, the TypeScript applications in `apps/` can execute independently on macOS, Windows, or Linux without containerization.