aboutsummaryrefslogtreecommitdiffstats
path: root/skills/ship-caddy/SKILL.md
diff options
context:
space:
mode:
Diffstat (limited to 'skills/ship-caddy/SKILL.md')
-rw-r--r--skills/ship-caddy/SKILL.md135
1 files changed, 135 insertions, 0 deletions
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 @@
1---
2name: ship-caddy
3description: 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.
4argument-hint: "<app-name> [host-nickname]"
5---
6
7# ship-caddy
8
9Manage per-app Caddy configuration 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### View current Caddy config for an app
26
27```bash
28ssh <host> "sudo cat /etc/caddy/sites-enabled/<app-name>.caddy"
29```
30
31### Add or update a site config
32
33Read the current config first if it exists, then write the new one. Always reload
34Caddy after writing — validate first by checking syntax:
35
36```bash
37ssh <host> "sudo caddy validate --config /etc/caddy/Caddyfile 2>&1"
38```
39
40If validation passes:
41```bash
42ssh <host> "sudo systemctl reload caddy"
43```
44
45If validation fails, show the error and do NOT reload. Tell the user what the
46problem is.
47
48### Standard reverse proxy config (most apps)
49
50```bash
51ssh <host> "sudo tee /etc/caddy/sites-enabled/<app-name>.caddy > /dev/null << 'EOF'
52<domain> {
53 reverse_proxy 127.0.0.1:<port>
54}
55EOF"
56```
57
58### Custom domain (in addition to default)
59
60```bash
61ssh <host> "sudo tee /etc/caddy/sites-enabled/<app-name>.caddy > /dev/null << 'EOF'
62<custom-domain>, <default-domain> {
63 reverse_proxy 127.0.0.1:<port>
64}
65EOF"
66```
67
68### Basic auth
69
70```bash
71ssh <host> "sudo tee /etc/caddy/sites-enabled/<app-name>.caddy > /dev/null << 'EOF'
72<domain> {
73 basicauth {
74 <username> <bcrypt-hash>
75 }
76 reverse_proxy 127.0.0.1:<port>
77}
78EOF"
79```
80
81To generate a bcrypt hash for a password:
82```bash
83ssh <host> "caddy hash-password --plaintext '<password>'"
84```
85
86### Redirect www to non-www
87
88```bash
89ssh <host> "sudo tee /etc/caddy/sites-enabled/<app-name>.caddy > /dev/null << 'EOF'
90www.<domain> {
91 redir https://<domain>{uri} permanent
92}
93
94<domain> {
95 reverse_proxy 127.0.0.1:<port>
96}
97EOF"
98```
99
100### Static site
101
102```bash
103ssh <host> "sudo tee /etc/caddy/sites-enabled/<app-name>.caddy > /dev/null << 'EOF'
104<domain> {
105 root * /var/www/<app-name>
106 file_server
107 encode gzip
108}
109EOF"
110```
111
112### Remove a site config
113
114```bash
115ssh <host> "sudo rm /etc/caddy/sites-enabled/<app-name>.caddy && sudo systemctl reload caddy"
116```
117
118Confirm with the user before removing.
119
120### View Caddy status and logs
121
122```bash
123ssh <host> "sudo systemctl status caddy --no-pager"
124ssh <host> "sudo journalctl -u caddy -n 50 --no-pager"
125```
126
127## Notes
128
129- Always validate before reloading — never reload with a broken config
130- The port for an app can be found at `/etc/ship/ports/<app-name>`
131- Caddy handles HTTPS automatically — no need to configure certificates
132- If the user asks for something not covered here, write the appropriate Caddy
133 directives — Caddy's config language is flexible and well documented
134- Main Caddyfile is at `/etc/caddy/Caddyfile` and imports all files in
135 `/etc/caddy/sites-enabled/`