From d0ae31c24c3c98ae89eebd67227c0c0d01606ed5 Mon Sep 17 00:00:00 2001 From: Clawd Date: Sat, 11 Apr 2026 20:43:41 -0700 Subject: Add ship-* Claude skills and plan Introduces a skills/ directory with 8 Claude skills that reimagine ship as a set of composable, human-driven deployment tools backed by Claude's reasoning rather than a rigid CLI. Skills: - ship-setup: one-time VPS config, saves host to ~/.config/ship/config.json - ship-status: derives live state from server, no local state file - ship-env: read/write env vars with merge semantics, never overwrites - ship-binary: deploy Go binaries with SQLite backup, correct restart behavior - ship-caddy: manage per-app Caddyfile with validate-before-reload - ship-service: systemd management and log inspection - ship-static: rsync static sites with SPA routing support - ship-deploy: orchestration runbook tying the others together Also adds SKILLS_PLAN.md documenting the architecture and rationale. Co-Authored-By: Claude Sonnet 4.6 --- skills/ship-caddy/SKILL.md | 135 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 skills/ship-caddy/SKILL.md (limited to 'skills/ship-caddy/SKILL.md') diff --git a/skills/ship-caddy/SKILL.md b/skills/ship-caddy/SKILL.md new file mode 100644 index 0000000..df79e39 --- /dev/null +++ b/skills/ship-caddy/SKILL.md @@ -0,0 +1,135 @@ +--- +name: ship-caddy +description: Manage Caddy configuration for a deployed app. Add, update, or remove site configs. Use when you need to change how Caddy serves an app — custom domains, redirects, auth, headers, etc. +argument-hint: " [host-nickname]" +--- + +# ship-caddy + +Manage per-app Caddy configuration on a ship VPS. + +## Read Config + +```bash +python3 -c " +import json, os +cfg = json.load(open(os.path.expanduser('~/.config/ship/config.json'))) +nick = '' +h = cfg['hosts'].get(nick, cfg['hosts'][cfg['default']]) +print(h['host']) +" +``` + +## Usage Patterns + +### View current Caddy config for an app + +```bash +ssh "sudo cat /etc/caddy/sites-enabled/.caddy" +``` + +### Add or update a site config + +Read the current config first if it exists, then write the new one. Always reload +Caddy after writing — validate first by checking syntax: + +```bash +ssh "sudo caddy validate --config /etc/caddy/Caddyfile 2>&1" +``` + +If validation passes: +```bash +ssh "sudo systemctl reload caddy" +``` + +If validation fails, show the error and do NOT reload. Tell the user what the +problem is. + +### Standard reverse proxy config (most apps) + +```bash +ssh "sudo tee /etc/caddy/sites-enabled/.caddy > /dev/null << 'EOF' + { + reverse_proxy 127.0.0.1: +} +EOF" +``` + +### Custom domain (in addition to default) + +```bash +ssh "sudo tee /etc/caddy/sites-enabled/.caddy > /dev/null << 'EOF' +, { + reverse_proxy 127.0.0.1: +} +EOF" +``` + +### Basic auth + +```bash +ssh "sudo tee /etc/caddy/sites-enabled/.caddy > /dev/null << 'EOF' + { + basicauth { + + } + reverse_proxy 127.0.0.1: +} +EOF" +``` + +To generate a bcrypt hash for a password: +```bash +ssh "caddy hash-password --plaintext ''" +``` + +### Redirect www to non-www + +```bash +ssh "sudo tee /etc/caddy/sites-enabled/.caddy > /dev/null << 'EOF' +www. { + redir https://{uri} permanent +} + + { + reverse_proxy 127.0.0.1: +} +EOF" +``` + +### Static site + +```bash +ssh "sudo tee /etc/caddy/sites-enabled/.caddy > /dev/null << 'EOF' + { + root * /var/www/ + file_server + encode gzip +} +EOF" +``` + +### Remove a site config + +```bash +ssh "sudo rm /etc/caddy/sites-enabled/.caddy && sudo systemctl reload caddy" +``` + +Confirm with the user before removing. + +### View Caddy status and logs + +```bash +ssh "sudo systemctl status caddy --no-pager" +ssh "sudo journalctl -u caddy -n 50 --no-pager" +``` + +## Notes + +- Always validate before reloading — never reload with a broken config +- The port for an app can be found at `/etc/ship/ports/` +- Caddy handles HTTPS automatically — no need to configure certificates +- If the user asks for something not covered here, write the appropriate Caddy + directives — Caddy's config language is flexible and well documented +- Main Caddyfile is at `/etc/caddy/Caddyfile` and imports all files in + `/etc/caddy/sites-enabled/` -- cgit v1.2.3