How to Navigate the Openship Codebase: A Complete Guide to the Monorepo Structure
Openship is a pnpm workspace monorepo organized into apps/ for executables and packages/ for shared libraries, with core business logic residing in packages/core, database schemas in packages/db, and Docker integrations in packages/adapters.
Openship is a self-hostable deployment platform that ships as a TypeScript monorepo. Knowing how to navigate the Openship codebase efficiently is essential for contributing to the web dashboard, CLI, or core service routing logic. This guide maps the repository structure from root configuration to individual source files, helping you locate specific functionality quickly.
Understanding the Monorepo Layout
The repository follows a standard pnpm workspace structure defined in the root package.json.
Root Configuration
The top-level directory contains workspace orchestration and infrastructure definitions. The package.json declares both apps/* and packages/* as workspaces, enabling cross-package imports with @repo/ prefixes.
{
"workspaces": [
"apps/*",
"packages/*"
]
}
The build system uses Turborepo to run commands across workspaces. For example, npm run build triggers turbo run build --filter=@repo/api --filter=@repo/dashboard as defined in the root scripts.
Apps Directory
The apps/ folder contains full-stack executables that run the control plane or user interfaces:
apps/web/– React dashboard served viasource.config.tsapps/desktop/– Electron client with entry atbuild/run.mjsapps/cli/– Command-line interface invoked viabun run --cwd apps/cli cliapps/api/– Express-style REST/MCP server atsrc/index.tsapps/email/– SMTP server for inbound mail routing atsrc/index.ts
Packages Directory
Reusable libraries live under packages/ and implement domain-specific logic:
packages/core/– Platform-wide utilities including service routing and version resolutionpackages/adapters/– Docker, OpenResty, and cloud provider integrationspackages/db/– Drizzle ORM schemas and database configurationpackages/ui/– Shared React components for web and desktoppackages/onboarding/– User setup flows for SSH and API keys
Navigating Core Packages
Understanding the packages/ subdirectory is key to modifying Openship's behavior.
Core Package Architecture
All platform-wide logic exports from packages/core/src/index.ts. Key modules include:
src/service-routing.ts– Resolves how project services map to URLs and reverse-proxy rulessrc/updates/– Handles version resolution, semver checking, and upgrade advisoriessrc/metadata/– Renders deployment metadata for Vercel, Railway, and the internal UI
When tracing how a deployment gets routed, start at packages/core/src/service-routing.ts to see the resolveServiceRouting function implementation.
Adapters and Toolchain
The packages/adapters directory contains concrete infrastructure implementations:
src/toolchain/installer.ts– Builds containers and prepares host environmentstest/*.test.ts– Validates edge routing, TLS handling, and resource limits
This package translates high-level core commands into Docker and OpenResty configurations.
Database Schema
packages/db manages persistence using Drizzle ORM:
src/schema/*– Defines tables for projects, deployments, backups, and notifications (e.g.,src/schema/project.ts)drizzle.config.ts– Configures the migration client
Import schema definitions directly to query the PostgreSQL backend:
import { db } from '@repo/db';
import { project } from '@repo/db/src/schema/project';
const projects = await db.select().from(project);
console.log(projects);
UI and Onboarding Components
Shared presentation logic resides in:
packages/ui/src/lib/cn.ts– Utility functions for component stylingpackages/onboarding/– Flows for project creation and credential setup
Working with Application Entry Points
Each app in apps/ has a distinct entry point that determines its runtime behavior.
| App | Entry File | Purpose |
|---|---|---|
| Web Dashboard | apps/web/source.config.ts |
Serves React UI and proxies API requests |
| Desktop | apps/desktop/build/run.mjs |
Electron wrapper for local control plane |
| CLI | apps/cli/cli |
Node.js binary for deployment commands |
| API | apps/api/src/index.ts |
Orchestrates builds and exposes REST endpoints |
apps/email/src/index.ts |
Processes inbound SMTP traffic |
To run the CLI locally during development, use the command referenced in the source:
bun run --cwd apps/cli cli
Build System and Release Process
The repository uses Turborepo for task running and includes automated release management.
Docker Composition
Self-hosted deployments rely on docker/docker-compose.yml, which defines the complete runtime stack:
services:
postgres: ...
redis: ...
api: ...
dashboard: ...
edge: ...
This file spins up PostgreSQL, Redis, the API server, dashboard, and OpenResty edge proxy.
Release Automation
scripts/release.ts packages the CLI, generates changelogs, and publishes Docker images. The script coordinates version bumps across all workspace packages before creating distributable artifacts.
Practical Navigation Examples
Resolving Service Routing
To understand how Openship maps services to URLs, import the core routing resolver:
// src/example.ts
import { resolveServiceRouting } from '@repo/core/src/service-routing';
const project = {
name: 'my-app',
ports: [{ internal: 3000, external: 80 }],
};
const routing = resolveServiceRouting(project);
console.log(routing);
// → { host: 'my-app.openship.dev', path: '/', targetPort: 3000 }
Building Containers Programmatically
Interact with the toolchain adapter to build Docker images:
import { buildContainer } from '@repo/adapters/src/toolchain/installer';
await buildContainer({
context: './my-app',
dockerfile: 'Dockerfile',
tags: ['my-app:latest'],
});
Running CLI Commands
The CLI entry point at apps/cli/cli supports standard deployment workflows:
# Initialize a project in the current directory
openship init
# Deploy and trigger the CI/CD pipeline
openship deploy
Summary
- Openship uses pnpm workspaces with two main directories:
apps/for executables andpackages/for shared libraries. - Core business logic lives in
packages/core/src/, particularlyservice-routing.tsfor URL resolution. - Database schemas are defined in
packages/db/src/schema/using Drizzle ORM. - Infrastructure automation is handled by
packages/adapters/src/toolchain/installer.tsfor Docker operations. - Application entry points vary by platform:
apps/api/src/index.tsfor the server,apps/cli/clifor the command line, andapps/web/source.config.tsfor the dashboard. - Local development requires running
docker/docker-compose.ymlfor the full stack and using Turborepo for builds.
Frequently Asked Questions
Where is the main API server code located in Openship?
The main API server is located at apps/api/src/index.ts. This Express-style server exposes the REST and MCP API endpoints and coordinates build processes across the platform. It imports logic from packages/core and packages/adapters to handle routing and container operations.
How do I find the database schema definitions in the Openship codebase?
Database schemas are located in packages/db/src/schema/. The Drizzle ORM configuration in packages/db/drizzle.config.ts points to these files. For example, the projects table is defined in packages/db/src/schema/project.ts, which you can query using the @repo/db import alias.
What is the purpose of the packages/core directory?
packages/core/ contains the platform's business logic that is shared across all applications. It handles service routing (src/service-routing.ts), version updates (src/updates/), and deployment metadata rendering. This package has no UI or infrastructure dependencies, making it pure domain logic.
How do I run the Openship CLI from the source code?
Navigate to the repository root and run bun run --cwd apps/cli cli (or use npm/pnpm with the appropriate --cwd flag). The CLI entry point is the apps/cli/cli file, which parses commands and communicates with the API server defined in apps/api/src/index.ts.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →