Documentation

Everything you need to deploy with Ship.

Prerequisites

  • macOS or Linux
  • SSH key (ed25519 recommended): ssh-keygen -t ed25519
  • Docker (for default deploy flow)
  • A Dockerfile or ship.json in your project root
  • Cloud provider API token

ship server create

Provision a new Ubuntu 22.04 server with Docker pre-installed. Your SSH key is automatically registered with the provider. State is saved to .ship/server.json and the machine-wide inventory at ~/.ship/servers.json.

bash
# Use defaults
ship server create --provider digitalocean

# Custom options
ship server create --provider hetzner --region fsn1 --size cx22 --image ubuntu-24-04-x64

Flags

  • --provider — digitalocean, hetzner, or vultr (required)
  • --region — override default region
  • --size — override default instance size
  • --image — override default OS image

ship server list

Show all servers tracked in your machine-wide inventory at ~/.ship/servers.json. Displays provider, IP, region, and project path for each server.

bash
ship server list

ship server destroy

Tears down the server at the cloud provider and removes all local state files (.ship/server.json, releases, runtime config). Also removes the entry from the machine-wide inventory.

bash
ship server destroy

ship deploy

Build and deploy your application to the provisioned server. If a ship.json deploy config exists, Ship runs your custom local commands, uploads files, and executes remote commands. Otherwise it uses the default Docker flow: build image locally, upload via SSH, and run the container.

bash
ship deploy

Custom Deploy Flow

Define a ship.json with local build commands, file uploads, and remote commands.

json
{
  "deploy": {
    "local_commands": ["npm ci", "npm run build"],
    "uploads": [{
      "source": "dist.tar.gz",
      "destination": "/opt/app/release.tar.gz",
      "mode": "0644"
    }],
    "remote_commands": [
      "cd /opt/app && tar -xzf release.tar.gz",
      "pm2 restart app"
    ],
    "cleanup_local": ["dist.tar.gz"]
  }
}

ship status

Report the health of your server and application. Checks SSH reachability, app container status, healthcheck endpoint result, and last release timestamp. Configure the healthcheck path in ship.json.

bash
$ ship status
SSH_REACHABLE=true
APP_STATUS=running
HEALTHCHECK=ok
LAST_RELEASE=2026-03-14T10:30:00Z

Configuration

json
{
  "status": {
    "healthcheck_path": "/"
  }
}

ship logs

Fetch the last 100 lines of logs from the application container on your server. Useful for quick debugging without SSHing in manually.

bash
ship logs

ship exec

Run an arbitrary command on your remote server over SSH. The command runs as the configured SSH user and returns stdout/stderr.

bash
ship exec "docker ps"
ship exec "df -h"
ship exec "cat /var/log/syslog | tail -50"

ship rollback

Restore a previous release. Ship tracks every deploy in .ship/releases.json. Rollback re-uploads the previous release artifact and re-runs the remote commands from that release.

bash
# List available releases
ship release list

# Roll back to the previous release
ship rollback

ship secrets

Manage environment secrets locally in .ship/secrets.env (mode 0600) and sync them to your server.

bash
# Add a secret
ship secrets set DATABASE_URL=postgres://...

# List secrets
ship secrets list

# Sync to server
ship secrets sync

ship domain setup

Configure a Caddy reverse proxy with automatic TLS certificates. Point your DNS to the server IP first, then run the command.

bash
ship domain setup --domain example.com --port 3000

Or configure via ship.json:

json
{
  "proxy": {
    "domains": ["example.com", "www.example.com"],
    "app_port": 3000
  }
}

ship init

Generate a starter ship.json configuration file. Choose from built-in templates for common project types.

bash
ship init --template docker
ship init --template node
ship init --template go
ship init --template static

ship bootstrap

Apply packages, proxy configuration, and setup commands defined in your ship.json to the server. Runs automatically on ship server create if a bootstrap config exists, or can be run manually.

bash
ship bootstrap

Configuration

json
{
  "bootstrap": {
    "packages": ["nodejs", "pm2"],
    "commands": ["npm install -g pm2"]
  }
}

Output Format

Ship outputs machine-friendly KEY=VALUE pairs by default, ideal for AI agents. Use --json for structured JSON output.

$ ship server create --provider digitalocean
STATUS=SERVER_CREATED
SERVER_ID=12345
SERVER_IP=1.2.3.4

$ ship server create --provider digitalocean --json
{"status":"SERVER_CREATED","server_id":"12345","server_ip":"1.2.3.4"}