aboutsummaryrefslogtreecommitdiffstats
path: root/skills/ship-service/SKILL.md
blob: e4d7510070db1cb2e04685d82356e3cbf0d96b99 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
---
name: ship-service
description: 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.
argument-hint: "<app-name> [start|stop|restart|status|logs] [host-nickname]"
---

# ship-service

Manage systemd services for apps deployed on a ship VPS.

## Read Config

```bash
python3 -c "
import json, os
cfg = json.load(open(os.path.expanduser('~/.config/ship/config.json')))
nick = '<nickname-or-default>'
h = cfg['hosts'].get(nick, cfg['hosts'][cfg['default']])
print(h['host'])
"
```

## Usage Patterns

### Status

```bash
ssh <host> "sudo systemctl status <app-name> --no-pager"
```

Shows whether the service is running, its PID, memory usage, and recent log lines.

### Restart

```bash
ssh <host> "sudo systemctl restart <app-name>"
```

Use after changing env vars or replacing the binary.

### Stop

```bash
ssh <host> "sudo systemctl stop <app-name>"
```

### Start

```bash
ssh <host> "sudo systemctl start <app-name>"
```

### View logs

Recent logs (last 50 lines):
```bash
ssh <host> "sudo journalctl -u <app-name> -n 50 --no-pager"
```

Follow live logs:
```bash
ssh <host> "sudo journalctl -u <app-name> -f"
```

Logs since last boot:
```bash
ssh <host> "sudo journalctl -u <app-name> -b --no-pager"
```

### Enable (start on boot)

```bash
ssh <host> "sudo systemctl enable <app-name>"
```

### Disable (don't start on boot)

```bash
ssh <host> "sudo systemctl disable <app-name>"
```

### View the systemd unit file

```bash
ssh <host> "sudo cat /etc/systemd/system/<app-name>.service"
```

### Remove a service entirely

Only do this if the user explicitly asks to remove/uninstall an app:

```bash
ssh <host> "sudo systemctl stop <app-name> && sudo systemctl disable <app-name> && sudo rm /etc/systemd/system/<app-name>.service && sudo systemctl daemon-reload"
```

Confirm with the user before removing. Note that this does not delete the binary,
data directory, env file, or Caddy config — those are managed separately.

## Diagnosing Problems

If a service is failing, check:

1. Service status for the error:
```bash
ssh <host> "sudo systemctl status <app-name> --no-pager"
```

2. Full logs for context:
```bash
ssh <host> "sudo journalctl -u <app-name> -n 100 --no-pager"
```

3. Whether the binary exists and is executable:
```bash
ssh <host> "ls -la /usr/local/bin/<app-name>"
```

4. Whether the env file exists and looks correct:
```bash
ssh <host> "sudo cat /etc/ship/env/<app-name>.env"
```

5. Whether the port is already in use by something else:
```bash
ssh <host> "sudo ss -tlnp | grep <port>"
```

## Notes

- If the user just says "restart foodtracker" or "check the logs for myapp", infer the action
- After a restart, give it a moment then check status to confirm it came up
- If a service repeatedly crashes, look at the logs before suggesting a fix
- Use default host unless another is specified