Projects, services & domains
Link a directory and manage projects, compose services, and custom domains from the terminal with openship init, project, service, and domain.
These commands are the terminal side of the dashboard's project screens: they create and inspect
projects, manage the services inside a compose stack, and attach custom domains. Everything here talks to
your instance's /api under the hood, so the same rules apply as anywhere else in the CLI.
Before you start
Log in once with openship login, and (optionally) run openship init in a project directory so deploy
commands know which project to act on. Add --json to any command for machine-readable output (stdout
becomes a clean data stream). Where a command wants a project, most accept a proj_… id; openship service
also accepts a slug or name.
openship init
Links the current directory to a project by writing .openship/project.json. Later commands (like
openship deploy) read that file so you don't have to pass a project every time. With no --project, it
lists your projects and prompts you to pick one.
# Interactive picker
openship init
# Link a specific project non-interactively
openship init --project proj_123 --environment production| Flag | Purpose |
|---|---|
--project <id> | Project id to link (skips the picker). |
--environment <name> | Default deploy environment. Default production. |
--dir <path> | Directory to initialize. Default: current directory. |
--force | Overwrite an existing project link. |
-y, --yes | Non-interactive: fail instead of prompting. |
openship project
Project lifecycle: list, inspect, create, delete, plus environment variables, git linkage, power state,
sleep mode, cloud transfer, and logs. Alias: openship projects.
Subcommands
| Command | Purpose |
|---|---|
project list (alias ls) | List projects in the active organization. |
project get <id> | Show a single project. |
project create | Create a project. |
project delete <id> (alias rm) | Delete a project and tear down all its resources. |
project env get <id> | List environment variables (secret values are masked). |
project env set <id> | Merge env vars — upsert KEY=VALUE pairs and/or delete keys. |
project git link <id> | Link a GitHub repository to a project. |
project git branch <id> <branch> | Set the deploy branch. |
project git auto-deploy <id> | Enable or disable push-to-deploy. |
project git webhook-domain <id> [domain] | Set or clear the domain that receives GitHub webhooks. |
project connect <id> <domain> | Connect a custom domain to a project. |
project enable <id> | Start a stopped project. |
project disable <id> | Stop a running project. |
project sleep-mode <id> <mode> | Set the project sleep mode. |
project transfer <id> <direction> | Promote to Openship Cloud or bring it back (self-hosted only). |
project logs <id> | Show or stream runtime (container) logs. |
project server-logs <id> | Show or stream HTTP request logs (edge / OpenResty). |
create
openship project create --name "My App" --slug my-app \
--git-owner acme --git-repo my-app --git-branch main --framework nextjs| Flag | Purpose |
|---|---|
--name <name> | Project name. Required. |
--slug <slug> | Free-subdomain slug (slug.opsh.io). |
--git-owner <owner> | GitHub owner / org. |
--git-repo <repo> | GitHub repository name. |
--git-branch <branch> | Git branch to deploy. |
--framework <framework> | Stack / framework id. |
--local-path <path> | Local source path. |
--port <port> | Container port. |
--type <type> | Project type: app, docker, services, or monorepo. |
delete
Tears down containers, routes, and (optionally) volumes, then removes the project row. Prompts for
confirmation unless you pass -y.
openship project delete proj_123 --wipe-volumes -y| Flag | Purpose |
|---|---|
--force | Cancel active work and delete anyway. |
--force-orphan | Orphan resources that won't destroy, then drop the row. |
--wipe-volumes | Also destroy persistent volumes. |
-y, --yes | Skip the confirmation prompt. |
env
Read or update a project's environment variables. set is a merge: it upserts the pairs you pass and
deletes the keys you --unset, leaving everything else untouched. See the
environment variables guide for how these flow into builds and runtime.
# List production vars
openship project env get proj_123 --environment production
# Upsert two secret vars and remove another (other keys are left untouched)
openship project env set proj_123 \
--set DATABASE_URL=postgres://… --set API_TOKEN=sk-… --secret \
--unset OLD_KEYFlag (on env get) | Purpose |
|---|---|
--environment <env> | Filter by environment: production, preview, or development. |
Flag (on env set) | Purpose |
|---|---|
--environment <env> | Target environment. Default production. |
--set <KEY=VALUE> | Pair to upsert. Repeatable. |
--unset <key> | Key to delete. Repeatable. |
--secret | Mark every --set value as a secret. |
git
Manage the GitHub link and push-to-deploy. After linking a repo, auto-deploy turns on redeploy-on-push;
webhook-domain selects which verified project domain receives webhook deliveries. See the
auto-deploy guide for the full flow.
openship project git link proj_123 --owner acme --repo my-app --branch main
openship project git auto-deploy proj_123 --enable
openship project git branch proj_123 develop
openship project git webhook-domain proj_123 app.example.com # or: --clearFlag (on git link) | Purpose |
|---|---|
--owner <owner> | GitHub owner / org. Required. |
--repo <repo> | Repository name. Required. |
--branch <branch> | Branch. Defaults to the repo's default branch. |
--installation-id <id> | GitHub App installation id. |
Flag (on git auto-deploy) | Purpose |
|---|---|
--enable | Enable auto-deploy. |
--disable | Disable auto-deploy. |
Pass exactly one of --enable / --disable. git webhook-domain takes an optional [domain] argument or
a --clear flag to unset it.
connect
Attaches a custom domain and prints the DNS records to add. Verification then runs automatically once the records resolve.
openship project connect proj_123 app.example.com --include-www| Flag | Purpose |
|---|---|
--include-www | Also connect the www. variant. |
Two ways to add a domain
project connect and domain add both attach a custom domain to a project and return
the records to create. connect is the quickest one-liner; the domain command group adds verify, renew,
and primary-selection on top. See the custom domains guide.
enable / disable
Power a project on or off without deleting it.
openship project disable proj_123
openship project enable proj_123sleep-mode
Controls whether the project sleeps when idle. See the sleep mode & resources guide.
openship project sleep-mode proj_123 auto_sleep # or: always_on| Mode | Meaning |
|---|---|
auto_sleep | Sleep the container when idle, wake on the next request. |
always_on | Keep the container running. |
transfer
Moves a project between your self-hosted instance and Openship Cloud. Only available on a self-hosted instance; see the cloud connect & migration guide.
openship project transfer proj_123 to-cloud # or: to-self-hostedlogs / server-logs
logs shows the container's runtime output; server-logs shows edge HTTP request logs (OpenResty). Both
print recent lines by default, or stream with -f. More context in the
logs & monitoring guide.
openship project logs proj_123 --tail 100 -f
openship project server-logs proj_123 --limit 200 --domain app.example.comFlag (on logs) | Purpose |
|---|---|
--tail <n> | Number of recent lines to show. |
-f, --follow | Stream logs until interrupted. |
Flag (on server-logs) | Purpose |
|---|---|
--limit <n> | Number of recent entries (max 200). |
--domain <domain> | Restrict to a specific domain. |
-f, --follow | Stream request logs until interrupted (self-hosted). |
openship service
Manage the services inside a compose stack (a multi-service project). Alias: openship services. Every
subcommand targets a stack with -p, --project <id|slug|name> and then a service by its name or svc_… id.
For the bigger picture, see the multi-service compose guide.
Every service command needs -p
Because services live under a project, each subcommand below requires -p, --project <id|slug|name>. A
proj_… id is used verbatim; a slug or name is resolved against your projects (and must be unambiguous).
Subcommands
| Command | Purpose |
|---|---|
service list -p <stack> | List the services in a stack. |
service get -p <stack> <service> | Show one service's configuration. |
service create -p <stack> <name> | Add a service to a stack. |
service delete -p <stack> <service> (alias rm) | Remove a service (tears down its container). |
service sync -p <stack> <compose-file> | Sync services from a docker-compose file. |
service start -p <stack> <service> | Start a service's container. |
service stop -p <stack> <service> | Stop a service's container. |
service restart -p <stack> <service> | Restart a service's container. |
service containers -p <stack> | List the stack's active-deployment containers. |
service drift accept -p <stack> <service> | Apply upstream compose values, discarding your edits. |
service drift keep -p <stack> <service> | Keep your edits and stop flagging the upstream change. |
service env get -p <stack> <service> | List a service's env vars (secrets masked). |
service env set -p <stack> <service> <pairs...> | Set a service's env vars for one environment. |
service logs -p <stack> <service> | Show or stream a service's runtime logs. |
service exec -p <stack> [service] | Open an interactive shell in a container (coming soon). |
create
openship service create -p my-stack db \
--image postgres:16 --port 5432:5432 --env POSTGRES_PASSWORD=secret
openship service create -p my-stack web \
--build ./web --dockerfile Dockerfile --port 3000:3000 \
--depends-on db --expose --exposed-port 3000 --domain my-web| Flag | Purpose |
|---|---|
--image <image> | Container image (e.g. postgres:16). |
--build <context> | Build context path (relative to repo root). |
--dockerfile <path> | Dockerfile path (relative to the build context). |
--port <mapping> | Port mapping, e.g. 8080:80. Repeatable. |
--depends-on <service> | Service this one depends on. Repeatable. |
--env <KEY=VALUE> | Compose environment default. Repeatable. |
--command <command> | Override the container command. |
--restart <policy> | Restart policy: no, always, on-failure, or unless-stopped. |
--expose | Expose the service publicly through managed routing. |
--exposed-port <port> | Container port to expose publicly. |
--domain <label> | Free subdomain label (used with --expose). |
sync
Reconciles the stack against a compose file: services present in the file are created or updated, and
services not in the file are removed. Parsing is delegated to Docker Compose, so docker (Compose v2)
must be installed locally.
openship service sync -p my-stack ./docker-compose.yml -y| Flag | Purpose |
|---|---|
-y, --yes | Skip the confirmation prompt. |
delete
openship service delete -p my-stack db -y| Flag | Purpose |
|---|---|
-y, --yes | Skip the confirmation prompt. |
drift
When an upstream compose change touches a value you edited in the dashboard, the service is flagged with
pending drift. Resolve it by taking the upstream values (accept) or keeping your edits (keep).
openship service drift accept -p my-stack web
openship service drift keep -p my-stack webenv
Read or set a service's environment variables, scoped to one environment. Unlike project env, the service
set command targets a single environment and merges into it by default; --replace swaps the whole set.
openship service env get -p my-stack web --env production
openship service env set -p my-stack web LOG_LEVEL=debug FEATURE_X=on --env productionFlag (on env get) | Purpose |
|---|---|
-e, --env <environment> | Environment: production, preview, or development. |
Flag (on env set) | Purpose |
|---|---|
-e, --env <environment> | Environment. Default production. |
--secret | Mark the provided variables as secret. |
--replace | Replace all variables for this environment with only the given pairs. |
logs
openship service logs -p my-stack web --tail 200 -f| Flag | Purpose |
|---|---|
-f, --follow | Stream new log lines as they arrive (SSE). |
--tail <n> | Number of lines to show from the end. Default 200. |
service exec is not available yet
openship service exec is stubbed — an interactive terminal needs a WebSocket client the CLI doesn't yet
ship. Use the dashboard's service terminal for now.
openship domain
Manage custom domains, DNS verification, and SSL certificates. This is the terminal side of a project's Domains tab; the same operations are documented as HTTP endpoints in the Domains API reference, and the full walkthrough lives in the custom domains guide.
Subcommands
| Command | Purpose |
|---|---|
domain list -p <id> | List a project's custom domains. |
domain add <hostname> -p <id> | Add a custom domain to a project. |
domain preview <hostname> | Preview the DNS records a hostname would need (nothing saved). |
domain verify <id> | Run DNS verification for a domain. |
domain primary <id> | Make a domain the project's primary hostname. |
domain records <id> | Show the DNS records for an existing domain. |
domain renew <id> | Renew the SSL certificate for a domain. |
domain verify-ssl <id> | Recheck that a certificate is issued and valid (no reissue). |
domain renew-all | Renew SSL for every near-expiry domain in your organization. |
Typical flow
# 1. See the records a hostname will need
openship domain preview app.example.com
# 2. Attach it to a project (prints the exact records to add)
openship domain add app.example.com -p proj_123 --primary
# 3. After the DNS records propagate, verify
openship domain verify <domainId>Flag (on list) | Purpose |
|---|---|
-p, --project <id> | Project id to list domains for. Required. |
Flag (on add) | Purpose |
|---|---|
-p, --project <id> | Project to attach the domain to. Required. |
--primary | Mark this domain as the project's primary. Default false. |
Adding a domain doesn't make it live
add (and preview) return the records to create at your DNS provider. The domain only goes live after the
records resolve and verify succeeds — for a domain that isn't propagating, re-check the records against
preview and retry. Certificates are then provisioned automatically.