4.8 KB164 lines
Blame
1#!/bin/bash
2# Sets up the Grove hub on a fresh DigitalOcean droplet.
3# The hub is a full Grove instance: Mononoke + Bridge + API + Hub API + Web + Registry.
4#
5# Usage: bash setup.sh <domain>
6# e.g. bash setup.sh grove.host
7
8set -euo pipefail
9
10DOMAIN="${1:?Usage: setup.sh <domain>}"
11SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
12GROVE_DIR="/opt/grove"
13
14mkdir -p "$GROVE_DIR"
15mkdir -p "$GROVE_DIR/data/mononoke"
16mkdir -p "$GROVE_DIR/data/api"
17
18# ── Copy configs ──────────────────────────────────────────────────
19
20cp "$SCRIPT_DIR/Caddyfile" "$GROVE_DIR/"
21cp "$SCRIPT_DIR/docker-compose.yml" "$GROVE_DIR/"
22
23# ── Generate JWT secret and write .env ────────────────────────────
24
25JWT_SECRET=$(openssl rand -base64 32)
26cat > "$GROVE_DIR/.env" <<EOF
27DOMAIN=$DOMAIN
28JWT_SECRET=$JWT_SECRET
29EOF
30
31# ── Generate TLS certificates for Mononoke ─────────────────────
32
33GROVE_TLS_DIR=/data/grove/tls "$SCRIPT_DIR/../scripts/generate-certs.sh" "$DOMAIN"
34
35# ── Write Mononoke config ────────────────────────────────────────
36
37mkdir -p "$GROVE_DIR/config/mononoke/common"
38mkdir -p "$GROVE_DIR/config/mononoke/repo_definitions/grove"
39mkdir -p "$GROVE_DIR/config/mononoke/repos/grove"
40
41cat > "$GROVE_DIR/config/mononoke/common/common.toml" <<'TOML'
42enable_http_control_api = true
43
44[internal_identity]
45identity_type = "SERVICE"
46identity_data = "grove"
47TOML
48
49cat > "$GROVE_DIR/config/mononoke/common/storage.toml" <<'TOML'
50[default]
51
52[default.metadata]
53[default.metadata.local]
54local_db_path = "/data/mononoke/metadata"
55
56[default.blobstore]
57[default.blobstore.blob_files]
58path = "/data/mononoke/blobs"
59
60[default.mutable_blobstore]
61[default.mutable_blobstore.blob_files]
62path = "/data/mononoke/mutable_blobs"
63TOML
64
65cat > "$GROVE_DIR/config/mononoke/repo_definitions/grove/server.toml" <<'TOML'
66repo_id = 0
67repo_name = "grove"
68repo_config = "grove"
69enabled = true
70hipster_acl = "default"
71TOML
72
73cat > "$GROVE_DIR/config/mononoke/repos/grove/server.toml" <<'TOML'
74storage_config = "default"
75
76[hook_manager_params]
77disable_acl_checker = true
78
79[push]
80pure_push_allowed = true
81
82[pushrebase]
83rewritedates = false
84
85[source_control_service]
86permit_writes = true
87permit_service_writes = true
88
89[git_configs.git_bundle_uri_config.uri_generator_type.local_fs]
90
91[infinitepush]
92allow_writes = true
93
94[commit_cloud_config]
95
96[derived_data_config]
97enabled_config_name = "default"
98
99[derived_data_config.available_configs.default]
100types = [
101 "blame",
102 "changeset_info",
103 "fastlog",
104 "filenodes",
105 "fsnodes",
106 "git_commits",
107 "git_delta_manifests_v2",
108 "unodes",
109 "hgchangesets",
110 "skeleton_manifests",
111 "skeleton_manifests_v2",
112 "ccsm",
113]
114
115[derived_data_config.available_configs.default.git_delta_manifest_v2_config]
116max_inlined_object_size = 2000
117max_inlined_delta_size = 2000
118delta_chunk_size = 1000000
119TOML
120
121# ── Pull bootstrap images from ghcr.io ───────────────────────────
122
123docker pull ghcr.io/letterpress-labs/grove-mononoke:latest
124docker pull ghcr.io/letterpress-labs/grove-api:latest
125docker pull ghcr.io/letterpress-labs/grove-hub-api:latest
126docker pull ghcr.io/letterpress-labs/grove-web:latest
127
128# Tag for local registry (images now in Docker cache)
129docker tag ghcr.io/letterpress-labs/grove-api:latest localhost:5000/grove-api:latest
130docker tag ghcr.io/letterpress-labs/grove-hub-api:latest localhost:5000/grove-hub-api:latest
131docker tag ghcr.io/letterpress-labs/grove-web:latest localhost:5000/grove-web:latest
132
133# ── Start ─────────────────────────────────────────────────────────
134
135cd "$GROVE_DIR"
136docker compose up -d
137
138# ── Seed local registry ──────────────────────────────────────────
139
140echo "Seeding local registry..."
141for i in $(seq 1 30); do
142 if curl -sf http://localhost:5000/v2/ > /dev/null 2>&1; then
143 docker push localhost:5000/grove-api:latest
144 docker push localhost:5000/grove-hub-api:latest
145 docker push localhost:5000/grove-web:latest
146 echo "Local registry seeded."
147 break
148 fi
149 sleep 2
150done
151
152# ── Wait for health ──────────────────────────────────────────────
153
154echo "Waiting for Grove Bridge to be healthy..."
155for i in $(seq 1 60); do
156 if curl -sf http://localhost:3100/health > /dev/null 2>&1; then
157 echo "Grove Bridge is healthy."
158 break
159 fi
160 sleep 5
161done
162
163echo "Hub is running at https://$DOMAIN"
164