What Is the Role of the Root Directory in Openship?

The root directory in Openship serves as the Configuration Hub, Build Context Provider, and Control-Plane Host, anchoring all platform operations from deployment configuration to source code resolution.

The root directory (top-level folder) of the oblien/openship repository is the single source of truth for runtime configuration and build scope. According to the source code, this directory determines how the platform discovers services, resolves build contexts, and hosts its own control plane components.

Configuration Hub: Runtime Discovery and Manifest Resolution

Openship treats the repository root as the primary Configuration Hub for determining what to build, how to build it, and where deployed services should run.

At startup, the platform searches the root directory for top-level configuration files, specifically openship.json and the root-level docker-compose.yml. These manifest files define the orchestration rules and service definitions that drive the deployment pipeline. If these files are absent, Openship initiates an auto-discovery process, falling back on conventional markers such as package.json, lockfiles, and other project metadata to infer the application structure.

This behavior is documented in the repository’s README.md, which explains that the root folder supplies the essential configuration context required before any build or deployment can proceed.

Build Context Provider: Source Resolution for Sub-Applications

Every service built through Openship resolves its build context relative to the repository root. This relationship is formally captured in the database schema defined in packages/db/src/schema/project.ts, which includes a root_directory field.

This field stores the path relative to the repository root, telling the orchestrator exactly where the source code lives for each sub-application. When the build process initiates, the system references this stored path to establish the correct working directory for Docker builds or bare-metal deployments.

// Reading the root directory from the project schema
import { db } from '@/db/client';
import { projects } from '@/db/schema/project';

async function getProjectRoot(projectId: number) {
  const row = await db
    .select()
    .from(projects)
    .where(eq(projects.id, projectId))
    .single();

  // `rootDirectory` is the path relative to the repository root
  return row?.rootDirectory ?? '.';
}

Control-Plane Host: Platform Services vs. User Applications

The root directory hosts the SaaS-style control plane that runs the Openship API, dashboard, and edge server. However, it is critical to distinguish between the platform’s own services and user-deployed applications.

The root docker-compose.yml (located at the repository top level) defines only the control plane infrastructure. This file does not host user applications. For self-hosting scenarios, user applications are deployed via alternative methods:

  • Compose Mode: Uses docker/docker-compose.yml (inside the docker/ subdirectory), which assumes the repository root contains the application source.
  • Bare Mode: Uses the openship up command, which builds directly from the repository root context.

# Start the control plane (SaaS platform services only)

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

# Deploy user applications in compose mode

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

# Run the platform in bare mode, using the repository root as build context

openship up --public-url https://my.openship.example.com

Summary

Frequently Asked Questions

What is the difference between the root docker-compose.yml and the docker/docker-compose.yml file?

The root docker-compose.yml defines the SaaS control plane that runs only the Openship platform services (API, dashboard, and edge server). In contrast, docker/docker-compose.yml is used in "compose mode" to deploy user applications, and it assumes the repository root contains the application source code. According to the source code, you should never use the root compose file to host user apps.

How does Openship determine the root directory for a project?

Openship determines the root directory by reading the root_directory column from the projects table defined in packages/db/src/schema/project.ts. This field stores the path relative to the repository root, which the orchestrator uses to resolve build contexts. If the project configuration is missing, the system defaults to the current working directory (.).

Can I run Openship if the root directory lacks an openship.json file?

Yes. While Openship looks for openship.json at the repository root to determine configuration, it implements an auto-discovery mechanism that falls back to reading package.json, lockfiles, and other manifest files if the primary configuration is absent. This allows the platform to infer project settings without explicit configuration files.

What services run from the root directory versus subdirectories?

The root directory hosts the control plane services—including the Openship API, web dashboard, and edge server—via the root docker-compose.yml. User applications and their supporting services run from subdirectories or alternative deployment contexts, either through the docker/docker-compose.yml file (compose mode) or the openship up command (bare mode), both of which reference the root directory as the build context source.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →