-
Notifications
You must be signed in to change notification settings - Fork 82
Expand file tree
/
Copy pathsetup.sh
More file actions
executable file
·188 lines (154 loc) · 5.59 KB
/
setup.sh
File metadata and controls
executable file
·188 lines (154 loc) · 5.59 KB
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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#!/bin/sh
set -e
# Eclaire Self-Hosted Setup Script
# Usage: mkdir eclaire && cd eclaire && curl -fsSL https://raw.githubusercontent.com/eclaire-labs/eclaire/main/setup.sh | sh
REPO_URL="https://raw.githubusercontent.com/eclaire-labs/eclaire/main"
# Colors (if terminal supports them)
if [ -t 1 ]; then
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
CYAN='\033[0;36m'
BOLD='\033[1m'
NC='\033[0m'
else
RED=''
GREEN=''
YELLOW=''
CYAN=''
BOLD=''
NC=''
fi
info() { printf "${CYAN}→${NC} %s\n" "$1"; }
success() { printf "${GREEN}✓${NC} %s\n" "$1"; }
warn() { printf "${YELLOW}!${NC} %s\n" "$1"; }
error() { printf "${RED}✗${NC} %s\n" "$1"; exit 1; }
# Collect diagnostics on failure
cleanup_on_error() {
printf "\n${RED}Setup failed. Collecting diagnostics...${NC}\n\n"
printf "${BOLD}Container status:${NC}\n"
docker compose --env-file .env ps 2>/dev/null || true
printf "\n${BOLD}Postgres logs (last 30 lines):${NC}\n"
docker compose --env-file .env logs --tail=30 postgres 2>/dev/null || true
printf "\n"
}
trap 'cleanup_on_error' ERR
# Generate a random 32-byte hex string
generate_secret() {
if command -v openssl >/dev/null 2>&1; then
openssl rand -hex 32
elif [ -r /dev/urandom ]; then
head -c 32 /dev/urandom | od -An -tx1 | tr -d ' \n'
else
error "Cannot generate secrets: neither openssl nor /dev/urandom available"
fi
}
# Check for existing installation
check_existing_installation() {
if [ -f ".env" ] || [ -d "data" ] || [ -d "config" ]; then
printf "\n${YELLOW}Existing installation detected.${NC}\n\n"
printf "Found: "
[ -f ".env" ] && printf ".env "
[ -d "data" ] && printf "data/ "
[ -d "config" ] && printf "config/ "
printf "\n\n"
printf "To upgrade an existing installation:\n"
printf " ${CYAN}docker compose pull${NC}\n"
printf " ${CYAN}docker compose run --rm eclaire upgrade${NC}\n"
printf " ${CYAN}docker compose up -d${NC}\n\n"
printf "To start fresh, remove existing files first.\n"
exit 1
fi
}
# Check prerequisites
check_prerequisites() {
info "Checking prerequisites..."
if ! command -v docker >/dev/null 2>&1; then
error "Docker is required but not installed. Install it from https://docs.docker.com/get-docker/"
fi
if ! docker compose version >/dev/null 2>&1; then
error "Docker Compose is required but not available. Make sure you have Docker Compose v2+."
fi
success "Docker and Docker Compose found"
}
# Download files from repository
download_files() {
info "Downloading files..."
mkdir -p config/ai data/postgres
curl -fsSL "$REPO_URL/compose.yaml" -o compose.yaml
curl -fsSL "$REPO_URL/.env.example" -o .env
curl -fsSL "$REPO_URL/config/ai/providers.json.example" -o config/ai/providers.json
curl -fsSL "$REPO_URL/config/ai/models.json.example" -o config/ai/models.json
curl -fsSL "$REPO_URL/config/ai/selection.json.example" -o config/ai/selection.json
success "Downloaded configuration files"
}
# Generate and inject secrets into .env
configure_secrets() {
info "Generating secrets..."
SECRET1=$(generate_secret)
SECRET2=$(generate_secret)
SECRET3=$(generate_secret)
# Replace empty secret values in .env
if [ "$(uname)" = "Darwin" ]; then
# macOS sed requires empty string for -i
sed -i '' "s/^BETTER_AUTH_SECRET=$/BETTER_AUTH_SECRET=$SECRET1/" .env
sed -i '' "s/^MASTER_ENCRYPTION_KEY=$/MASTER_ENCRYPTION_KEY=$SECRET2/" .env
sed -i '' "s/^API_KEY_HMAC_KEY_V1=$/API_KEY_HMAC_KEY_V1=$SECRET3/" .env
else
sed -i "s/^BETTER_AUTH_SECRET=$/BETTER_AUTH_SECRET=$SECRET1/" .env
sed -i "s/^MASTER_ENCRYPTION_KEY=$/MASTER_ENCRYPTION_KEY=$SECRET2/" .env
sed -i "s/^API_KEY_HMAC_KEY_V1=$/API_KEY_HMAC_KEY_V1=$SECRET3/" .env
fi
success "Generated and configured secrets"
}
# Pull Docker images
pull_images() {
info "Pulling Docker images (this may take a few minutes)..."
docker compose --env-file .env pull
success "Docker images pulled"
}
# Initialize database
initialize_database() {
info "Starting database..."
docker compose --env-file .env up -d postgres
info "Waiting for database to be ready..."
timeout=60
while ! docker compose --env-file .env exec -T postgres psql -U eclaire -d eclaire -c "SELECT 1" >/dev/null 2>&1; do
timeout=$((timeout - 1))
if [ $timeout -le 0 ]; then
error "Database failed to become ready"
fi
sleep 1
done
info "Running migrations..."
if ! docker compose --env-file .env run --rm -T --no-deps eclaire upgrade; then
error "Database migration failed. Check logs above for details."
fi
docker compose --env-file .env stop postgres >/dev/null 2>&1
success "Database initialized"
}
# Print next steps
print_next_steps() {
printf "\n${GREEN}${BOLD}Setup complete!${NC}\n\n"
printf "${BOLD}Next steps:${NC}\n\n"
printf "1. Start your LLM servers (in separate terminals):\n"
printf " ${CYAN}llama-server -hf unsloth/Qwen3-14B-GGUF:Q4_K_XL --ctx-size 16384 --port 11500${NC}\n"
printf " ${CYAN}llama-server -hf unsloth/gemma-3-4b-it-qat-GGUF:Q4_K_XL --ctx-size 16384 --port 11501${NC}\n"
printf " ${YELLOW}(Models download automatically on first run, if not already cached)${NC}\n\n"
printf "2. Start Eclaire:\n"
printf " ${CYAN}docker compose up -d${NC}\n\n"
printf "3. Open ${CYAN}http://localhost:3000${NC} and register an account.\n\n"
printf "For alternative AI model configuration, see: ${CYAN}docs/ai-models.md${NC}\n\n"
}
# Main
main() {
printf "\n${BOLD}Eclaire Self-Hosted Setup${NC}\n\n"
check_existing_installation
check_prerequisites
download_files
configure_secrets
pull_images
initialize_database
print_next_steps
}
main