aboutsummaryrefslogtreecommitdiffstats
path: root/skills/ship-service
diff options
context:
space:
mode:
authorClawd <ai@clawd.bot>2026-04-11 20:43:41 -0700
committerClawd <ai@clawd.bot>2026-04-11 20:43:41 -0700
commitd0ae31c24c3c98ae89eebd67227c0c0d01606ed5 (patch)
treec684469e0f7d3b65477cfc631ecdaafa3c6a218a /skills/ship-service
parent5548b36e0953c17dbe30f6b63c892b7c83196b20 (diff)
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 <noreply@anthropic.com>
Diffstat (limited to 'skills/ship-service')
-rw-r--r--skills/ship-service/SKILL.md133
1 files changed, 133 insertions, 0 deletions
diff --git a/skills/ship-service/SKILL.md b/skills/ship-service/SKILL.md
new file mode 100644
index 0000000..e4d7510
--- /dev/null
+++ b/skills/ship-service/SKILL.md
@@ -0,0 +1,133 @@
1---
2name: ship-service
3description: Manage systemd services for deployed apps. Start, stop, restart, view status and logs. Use when you need to control a running service or diagnose problems.
4argument-hint: "<app-name> [start|stop|restart|status|logs] [host-nickname]"
5---
6
7# ship-service
8
9Manage systemd services for apps deployed on a ship VPS.
10
11## Read Config
12
13```bash
14python3 -c "
15import json, os
16cfg = json.load(open(os.path.expanduser('~/.config/ship/config.json')))
17nick = '<nickname-or-default>'
18h = cfg['hosts'].get(nick, cfg['hosts'][cfg['default']])
19print(h['host'])
20"
21```
22
23## Usage Patterns
24
25### Status
26
27```bash
28ssh <host> "sudo systemctl status <app-name> --no-pager"
29```
30
31Shows whether the service is running, its PID, memory usage, and recent log lines.
32
33### Restart
34
35```bash
36ssh <host> "sudo systemctl restart <app-name>"
37```
38
39Use after changing env vars or replacing the binary.
40
41### Stop
42
43```bash
44ssh <host> "sudo systemctl stop <app-name>"
45```
46
47### Start
48
49```bash
50ssh <host> "sudo systemctl start <app-name>"
51```
52
53### View logs
54
55Recent logs (last 50 lines):
56```bash
57ssh <host> "sudo journalctl -u <app-name> -n 50 --no-pager"
58```
59
60Follow live logs:
61```bash
62ssh <host> "sudo journalctl -u <app-name> -f"
63```
64
65Logs since last boot:
66```bash
67ssh <host> "sudo journalctl -u <app-name> -b --no-pager"
68```
69
70### Enable (start on boot)
71
72```bash
73ssh <host> "sudo systemctl enable <app-name>"
74```
75
76### Disable (don't start on boot)
77
78```bash
79ssh <host> "sudo systemctl disable <app-name>"
80```
81
82### View the systemd unit file
83
84```bash
85ssh <host> "sudo cat /etc/systemd/system/<app-name>.service"
86```
87
88### Remove a service entirely
89
90Only do this if the user explicitly asks to remove/uninstall an app:
91
92```bash
93ssh <host> "sudo systemctl stop <app-name> && sudo systemctl disable <app-name> && sudo rm /etc/systemd/system/<app-name>.service && sudo systemctl daemon-reload"
94```
95
96Confirm with the user before removing. Note that this does not delete the binary,
97data directory, env file, or Caddy config — those are managed separately.
98
99## Diagnosing Problems
100
101If a service is failing, check:
102
1031. Service status for the error:
104```bash
105ssh <host> "sudo systemctl status <app-name> --no-pager"
106```
107
1082. Full logs for context:
109```bash
110ssh <host> "sudo journalctl -u <app-name> -n 100 --no-pager"
111```
112
1133. Whether the binary exists and is executable:
114```bash
115ssh <host> "ls -la /usr/local/bin/<app-name>"
116```
117
1184. Whether the env file exists and looks correct:
119```bash
120ssh <host> "sudo cat /etc/ship/env/<app-name>.env"
121```
122
1235. Whether the port is already in use by something else:
124```bash
125ssh <host> "sudo ss -tlnp | grep <port>"
126```
127
128## Notes
129
130- If the user just says "restart foodtracker" or "check the logs for myapp", infer the action
131- After a restart, give it a moment then check status to confirm it came up
132- If a service repeatedly crashes, look at the logs before suggesting a fix
133- Use default host unless another is specified