aboutsummaryrefslogtreecommitdiffstats
path: root/skills/ship-setup/setup.sh
diff options
context:
space:
mode:
Diffstat (limited to 'skills/ship-setup/setup.sh')
-rw-r--r--skills/ship-setup/setup.sh147
1 files changed, 147 insertions, 0 deletions
diff --git a/skills/ship-setup/setup.sh b/skills/ship-setup/setup.sh
new file mode 100644
index 0000000..4bb5a82
--- /dev/null
+++ b/skills/ship-setup/setup.sh
@@ -0,0 +1,147 @@
1#!/usr/bin/env bash
2# ship-setup: Configure a VPS for ship deployments.
3# Usage: ./setup.sh <ssh-host> <base-domain> <nickname> [--default]
4#
5# - Idempotent: safe to run multiple times
6# - Mirrors the behavior of `ship host init` from the Go CLI
7# - Updates ~/.config/ship/config.json with the new host
8
9set -euo pipefail
10
11# ── Args ────────────────────────────────────────────────────────────────────
12
13if [ $# -lt 3 ]; then
14 echo "Usage: $0 <ssh-host> <base-domain> <nickname> [--default]"
15 echo " ssh-host: SSH connection string or alias (e.g. ubuntu@1.2.3.4 or alaskav6)"
16 echo " base-domain: Base domain for this server (e.g. example.com)"
17 echo " nickname: Short name for this host (e.g. prod, staging)"
18 echo " --default: Make this the default host"
19 exit 1
20fi
21
22SSH_HOST="$1"
23DOMAIN="$2"
24NICKNAME="$3"
25MAKE_DEFAULT=false
26if [ "${4:-}" = "--default" ]; then
27 MAKE_DEFAULT=true
28fi
29
30CONFIG_FILE="$HOME/.config/ship/config.json"
31
32# ── Step 1: Test SSH connection ──────────────────────────────────────────────
33
34echo "→ Testing SSH connection to $SSH_HOST..."
35if ! ssh -o ConnectTimeout=5 -o BatchMode=yes "$SSH_HOST" "echo ok" &>/dev/null; then
36 echo "✗ SSH connection failed. Make sure your key is authorized:"
37 echo " ssh-copy-id $SSH_HOST"
38 exit 1
39fi
40echo " ✓ Connected"
41
42# ── Step 2: Detect OS ────────────────────────────────────────────────────────
43
44echo "→ Detecting OS..."
45OS_RELEASE=$(ssh "$SSH_HOST" "cat /etc/os-release")
46if ! echo "$OS_RELEASE" | grep -qE "Ubuntu|Debian"; then
47 echo "✗ Unsupported OS. Only Ubuntu and Debian are supported."
48 exit 1
49fi
50echo " ✓ OS supported"
51
52# ── Step 3: Install Caddy (if not present) ───────────────────────────────────
53
54echo "→ Checking Caddy..."
55if ssh "$SSH_HOST" "which caddy" &>/dev/null; then
56 echo " ✓ Caddy already installed"
57else
58 echo " Installing Caddy..."
59 ssh "$SSH_HOST" "sudo apt-get update -qq && \
60 sudo apt-get install -y -qq debian-keyring debian-archive-keyring apt-transport-https curl gnupg && \
61 curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' -o /tmp/caddy.gpg && \
62 sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg < /tmp/caddy.gpg && \
63 curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list && \
64 sudo apt-get update -qq && \
65 sudo apt-get install -y -qq caddy"
66 echo " ✓ Caddy installed"
67fi
68
69# ── Step 4: Configure Caddyfile (only if not already set up) ─────────────────
70
71echo "→ Checking Caddyfile..."
72if ssh "$SSH_HOST" "sudo test -f /etc/caddy/Caddyfile && sudo grep -q 'sites-enabled' /etc/caddy/Caddyfile" 2>/dev/null; then
73 echo " ✓ Caddyfile already configured"
74else
75 echo " Writing Caddyfile..."
76 ssh "$SSH_HOST" "echo '{
77}
78
79import /etc/caddy/sites-enabled/*' | sudo tee /etc/caddy/Caddyfile > /dev/null"
80 echo " ✓ Caddyfile configured"
81fi
82
83# ── Step 5: Create directory structure ───────────────────────────────────────
84
85echo "→ Creating directories..."
86ssh "$SSH_HOST" "sudo mkdir -p \
87 /etc/ship/env \
88 /etc/ship/ports \
89 /etc/ship/ttl \
90 /etc/ship/overrides \
91 /etc/caddy/sites-enabled \
92 /var/www && \
93 sudo chmod 755 /etc/ship"
94echo " ✓ Directories ready"
95
96# ── Step 6: Enable and start Caddy ───────────────────────────────────────────
97
98echo "→ Enabling Caddy..."
99ssh "$SSH_HOST" "sudo systemctl enable caddy && sudo systemctl start caddy || sudo systemctl reload caddy"
100echo " ✓ Caddy running"
101
102# ── Step 7: Save config locally ──────────────────────────────────────────────
103
104echo "→ Saving host config to $CONFIG_FILE..."
105mkdir -p "$(dirname "$CONFIG_FILE")"
106
107python3 - <<EOF
108import json, os
109
110path = os.path.expanduser("$CONFIG_FILE")
111cfg = {"default": None, "hosts": {}}
112
113if os.path.exists(path):
114 with open(path) as f:
115 cfg = json.load(f)
116
117cfg["hosts"]["$NICKNAME"] = {
118 "host": "$SSH_HOST",
119 "domain": "$DOMAIN"
120}
121
122if cfg["default"] is None or "$MAKE_DEFAULT" == "true":
123 cfg["default"] = "$NICKNAME"
124
125with open(path, "w") as f:
126 json.dump(cfg, f, indent=2)
127 f.write("\n")
128
129print(f" Hosts: {list(cfg['hosts'].keys())}")
130print(f" Default: {cfg['default']}")
131EOF
132
133echo " ✓ Config saved"
134
135# ── Done ─────────────────────────────────────────────────────────────────────
136
137echo ""
138echo "✓ $NICKNAME ($SSH_HOST) is ready for deployments"
139echo " Domain: $DOMAIN"
140if [ "$MAKE_DEFAULT" = true ]; then
141 echo " Set as default host"
142fi
143echo ""
144echo "Next steps:"
145echo " Deploy a binary: /ship-deploy"
146echo " Check what's running: /ship-status"
147echo " Add another host: ./setup.sh <host> <domain> <nickname>"