aboutsummaryrefslogtreecommitdiffstats
path: root/skills/ship-setup/setup.sh
blob: 4bb5a82d8d8022eb865c7eaca6af789c36462b2c (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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#!/usr/bin/env bash
# ship-setup: Configure a VPS for ship deployments.
# Usage: ./setup.sh <ssh-host> <base-domain> <nickname> [--default]
#
# - Idempotent: safe to run multiple times
# - Mirrors the behavior of `ship host init` from the Go CLI
# - Updates ~/.config/ship/config.json with the new host

set -euo pipefail

# ── Args ────────────────────────────────────────────────────────────────────

if [ $# -lt 3 ]; then
  echo "Usage: $0 <ssh-host> <base-domain> <nickname> [--default]"
  echo "  ssh-host:    SSH connection string or alias (e.g. ubuntu@1.2.3.4 or alaskav6)"
  echo "  base-domain: Base domain for this server (e.g. example.com)"
  echo "  nickname:    Short name for this host (e.g. prod, staging)"
  echo "  --default:   Make this the default host"
  exit 1
fi

SSH_HOST="$1"
DOMAIN="$2"
NICKNAME="$3"
MAKE_DEFAULT=false
if [ "${4:-}" = "--default" ]; then
  MAKE_DEFAULT=true
fi

CONFIG_FILE="$HOME/.config/ship/config.json"

# ── Step 1: Test SSH connection ──────────────────────────────────────────────

echo "→ Testing SSH connection to $SSH_HOST..."
if ! ssh -o ConnectTimeout=5 -o BatchMode=yes "$SSH_HOST" "echo ok" &>/dev/null; then
  echo "✗ SSH connection failed. Make sure your key is authorized:"
  echo "  ssh-copy-id $SSH_HOST"
  exit 1
fi
echo "  ✓ Connected"

# ── Step 2: Detect OS ────────────────────────────────────────────────────────

echo "→ Detecting OS..."
OS_RELEASE=$(ssh "$SSH_HOST" "cat /etc/os-release")
if ! echo "$OS_RELEASE" | grep -qE "Ubuntu|Debian"; then
  echo "✗ Unsupported OS. Only Ubuntu and Debian are supported."
  exit 1
fi
echo "  ✓ OS supported"

# ── Step 3: Install Caddy (if not present) ───────────────────────────────────

echo "→ Checking Caddy..."
if ssh "$SSH_HOST" "which caddy" &>/dev/null; then
  echo "  ✓ Caddy already installed"
else
  echo "  Installing Caddy..."
  ssh "$SSH_HOST" "sudo apt-get update -qq && \
    sudo apt-get install -y -qq debian-keyring debian-archive-keyring apt-transport-https curl gnupg && \
    curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' -o /tmp/caddy.gpg && \
    sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg < /tmp/caddy.gpg && \
    curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list && \
    sudo apt-get update -qq && \
    sudo apt-get install -y -qq caddy"
  echo "  ✓ Caddy installed"
fi

# ── Step 4: Configure Caddyfile (only if not already set up) ─────────────────

echo "→ Checking Caddyfile..."
if ssh "$SSH_HOST" "sudo test -f /etc/caddy/Caddyfile && sudo grep -q 'sites-enabled' /etc/caddy/Caddyfile" 2>/dev/null; then
  echo "  ✓ Caddyfile already configured"
else
  echo "  Writing Caddyfile..."
  ssh "$SSH_HOST" "echo '{
}

import /etc/caddy/sites-enabled/*' | sudo tee /etc/caddy/Caddyfile > /dev/null"
  echo "  ✓ Caddyfile configured"
fi

# ── Step 5: Create directory structure ───────────────────────────────────────

echo "→ Creating directories..."
ssh "$SSH_HOST" "sudo mkdir -p \
  /etc/ship/env \
  /etc/ship/ports \
  /etc/ship/ttl \
  /etc/ship/overrides \
  /etc/caddy/sites-enabled \
  /var/www && \
  sudo chmod 755 /etc/ship"
echo "  ✓ Directories ready"

# ── Step 6: Enable and start Caddy ───────────────────────────────────────────

echo "→ Enabling Caddy..."
ssh "$SSH_HOST" "sudo systemctl enable caddy && sudo systemctl start caddy || sudo systemctl reload caddy"
echo "  ✓ Caddy running"

# ── Step 7: Save config locally ──────────────────────────────────────────────

echo "→ Saving host config to $CONFIG_FILE..."
mkdir -p "$(dirname "$CONFIG_FILE")"

python3 - <<EOF
import json, os

path = os.path.expanduser("$CONFIG_FILE")
cfg = {"default": None, "hosts": {}}

if os.path.exists(path):
    with open(path) as f:
        cfg = json.load(f)

cfg["hosts"]["$NICKNAME"] = {
    "host": "$SSH_HOST",
    "domain": "$DOMAIN"
}

if cfg["default"] is None or "$MAKE_DEFAULT" == "true":
    cfg["default"] = "$NICKNAME"

with open(path, "w") as f:
    json.dump(cfg, f, indent=2)
    f.write("\n")

print(f"  Hosts: {list(cfg['hosts'].keys())}")
print(f"  Default: {cfg['default']}")
EOF

echo "  ✓ Config saved"

# ── Done ─────────────────────────────────────────────────────────────────────

echo ""
echo "✓ $NICKNAME ($SSH_HOST) is ready for deployments"
echo "  Domain: $DOMAIN"
if [ "$MAKE_DEFAULT" = true ]; then
  echo "  Set as default host"
fi
echo ""
echo "Next steps:"
echo "  Deploy a binary:      /ship-deploy"
echo "  Check what's running: /ship-status"
echo "  Add another host:     ./setup.sh <host> <domain> <nickname>"