From 0ec6d9cb739a4357c5e168855296ce2389d23a27 Mon Sep 17 00:00:00 2001 From: Clawd Date: Sat, 11 Apr 2026 22:46:28 -0700 Subject: Rewrite README for skills-based approach Replaces outdated v1 git-push/CLI docs with accurate description of the Claude skills system. Covers install, quick start, config format, server layout, and skill reference table. Co-Authored-By: Claude Sonnet 4.6 --- README.md | 174 ++++++++++++++++++++------------------------------------------ 1 file changed, 56 insertions(+), 118 deletions(-) diff --git a/README.md b/README.md index c440c49..27ed219 100644 --- a/README.md +++ b/README.md @@ -1,167 +1,105 @@ # Ship -Ship turns a VPS into a self-hosted git server with a web frontend — similar to running cgit on your own domain. Visiting your base domain in a browser shows a cgit repo index; clicking through shows trees, commit logs, diffs, and blame. Public repos are cloneable over HTTPS. If you host Go code, `go get` works with your domain out of the box. This is the read-only, public-facing side, and it works exactly the way cgit users expect. +Deploy Go binaries and static sites to a VPS with automatic HTTPS. No agent on the server — just SSH, systemd, and Caddy. -The difference is what happens on the write side. When you `git push` over SSH, Ship doesn't just update the bare repo — it builds and deploys your code. A post-receive hook checks out the repo, runs `docker build`, installs a systemd service and Caddy reverse-proxy config, and restarts the app. Your deployment config (the systemd unit, the Caddyfile) lives in `.ship/` in your repo and is versioned alongside your code. Push to main and it's live; push to any other branch and nothing happens. +## How it works -Not every repo needs to be a running service. If there's no Dockerfile, the push is accepted but the deploy step is skipped — the repo just sits there as a browsable, cloneable library. This makes Ship useful for Go modules that only need vanity imports and a public source view, alongside apps that need the full build-and-deploy pipeline. The same base domain serves both. +Ship is a set of Claude skills. Instead of a rigid CLI that bakes in assumptions, Claude reasons about what to do using a family of narrow, composable skills. The server is the source of truth — no local state file that can go stale. -Ship also supports direct deploys (SCP a binary or rsync a static directory) for cases where git push isn't the right fit. +## Skills -Ship is a client-side CLI. All state lives on your laptop at `~/.config/ship/state.json`. The VPS is configured entirely over SSH — no agent or daemon runs on the server. +| Skill | What it does | +|-------|-------------| +| `/ship-setup` | One-time VPS config. Installs Caddy, creates directories, saves host to `~/.config/ship/config.json` | +| `/ship-status` | Show all running apps, ports, domains, and disk usage — derived live from server | +| `/ship-deploy` | Deploy a binary or static site — orchestrates the skills below | +| `/ship-binary` | Upload a pre-built binary, configure systemd + Caddy, back up SQLite | +| `/ship-static` | Rsync a dist folder, configure Caddy to serve it | +| `/ship-env` | Read/write env vars with merge semantics — never wipes existing vars | +| `/ship-caddy` | Manage per-app Caddyfile — validates before reloading | +| `/ship-service` | systemd control: start, stop, restart, logs | ## Install -``` -go install github.com/bdw/ship/cmd/ship@latest -``` - -Or build from source: +Copy the `skills/` directory into `~/.claude/skills/`: -``` -go build -o ship ./cmd/ship +```bash +cp -r skills/ship-* ~/.claude/skills/ ``` ## Quick start -### 1. Set up the VPS - -``` -ship host init --host user@your-vps --base-domain example.com -``` - -This installs Caddy, Docker, git, fcgiwrap, and cgit. It creates a `git` user for push access, configures sudoers for deploy hooks, and enables automatic HTTPS. The host becomes the default for subsequent commands. - -### 2. Deploy - -**Git push (Docker-based app):** - -``` -ship init myapp -git add .ship/ Dockerfile -git commit -m "initial deploy" -git push origin main -``` - -**Git push (static site):** +### 1. Set up your VPS ``` -ship init mysite --static -git add .ship/ index.html -git commit -m "initial deploy" -git push origin main +/ship-setup ``` -**Git push (library / Go module):** +Claude asks for SSH host, domain, and nickname. Saves to `~/.config/ship/config.json`. Installs Caddy on the server. -``` -ship init mylib --public -git add . -git commit -m "initial" -git push origin main -``` - -No Dockerfile, so nothing is deployed — the repo is just browsable and cloneable at `https://example.com/mylib`. +Or run the script directly: -**Direct (pre-built binary):** - -``` -GOOS=linux GOARCH=amd64 go build -o myapp -ship --binary ./myapp --domain api.example.com +```bash +bash ~/.claude/skills/ship-setup/setup.sh ubuntu@1.2.3.4 example.com prod --default ``` -On first deployment, Ship creates a `.ship/` directory in your current working directory containing: -- `.ship/service` - systemd unit file -- `.ship/Caddyfile` - Caddy reverse proxy config - -These files are uploaded on each deployment. You can edit them locally to customize your deployment (add extra Caddy routes, adjust systemd settings). The systemd service is regenerated when you update resource limits with `--memory`, `--cpu`, or `--args` flags. The Caddyfile is never regenerated, so your custom routes won't be overwritten. - -You can version control `.ship/` or add it to `.gitignore` — it's your choice. - -## Commands - -### `ship init ` - -Create a bare git repo on the VPS and generate local `.ship/` config files. +### 2. Deploy ``` -ship init myapp # Docker-based app -ship init mysite --static # static site -ship init myapp --domain custom.example.com # custom domain -ship init mylib --public # publicly cloneable (for go get) +/ship-deploy ``` -### `ship deploy ` - -Manually rebuild and deploy a git-deployed app. - -### `ship [deploy flags]` +Claude asks what you're deploying (binary or static site), where it is, what to call it, and any env vars. Handles the rest. -Deploy a pre-built binary or static directory directly. +### 3. Check status ``` -ship --binary ./myapp --domain api.example.com -ship --binary ./myapp --domain api.example.com --env DB_HOST=localhost -ship --static --dir ./dist --domain example.com -ship --name myapi --memory 512M --cpu 50% +/ship-status ``` -Flags: `--binary`, `--static`, `--dir`, `--domain`, `--name`, `--env`, `--env-file`, `--args`, `--file`, `--memory`, `--cpu` - -### `ship list` - -List all deployments on the default host. +Shows all running apps, ports, URLs, and disk usage — no local state file, reads directly from server. -### `ship status/logs/restart/remove ` +## Config -Manage a deployment's systemd service. +`~/.config/ship/config.json` — created by `/ship-setup`. Supports multiple hosts: -### `ship env` - -``` -ship env list myapp -ship env set myapp KEY=VALUE -ship env unset myapp KEY +```json +{ + "default": "prod", + "hosts": { + "prod": { + "host": "ubuntu@1.2.3.4", + "domain": "example.com" + }, + "staging": { + "host": "ubuntu@5.6.7.8", + "domain": "staging.example.com" + } + } +} ``` -### `ship host` - -``` -ship host init --host user@vps --base-domain example.com -ship host status -ship host update -ship host ssh -``` +Deploy to a specific host: "deploy foodtracker to staging" -### `ship ui` - -Launch a local web UI for viewing deployments. - -## VPS file layout +## Server layout ``` -/srv/git/.git/ # bare git repos -/srv/git/.git/hooks/post-receive # auto-deploy hook -/var/lib//src/ # checked-out source (for docker build) -/var/lib//data/ # persistent data volume +/usr/local/bin/ # binary +/var/lib// # work directory +/var/lib//data/ # persistent data (SQLite lives here) +/var/lib//backups/ # SQLite backups (made before each binary swap) /var/www// # static site files /etc/systemd/system/.service # systemd unit /etc/caddy/sites-enabled/.caddy # per-app Caddy config -/etc/caddy/sites-enabled/ship-code.caddy # base domain Caddy config -/etc/cgitrc # cgit configuration /etc/ship/env/.env # environment variables -/etc/sudoers.d/ship-git # sudo rules for git user -/opt/ship/vanity/index.html # vanity import template -/home/git/.ssh/authorized_keys # SSH keys for git push +/etc/ship/ports/ # allocated port number ``` -## Supported platforms - -VPS: Ubuntu 20.04+ or Debian 11+ - -## Security +## Requirements -See [SECURITY.md](SECURITY.md) for the threat model, mitigations, and known gaps. +- VPS running Ubuntu 20.04+ or Debian 11+ +- SSH access +- Claude Code with skills support ## License -- cgit v1.2.3