Add one-click install script with automatic secret generation
- Create scripts/install.sh that auto-generates Ed25519 signing key, JWT secret, Postgres and MinIO passwords from .env.example placeholders - Add startup validation in server to reject placeholder secrets - Add 401 interceptor in console API client to clear stale JWT tokens - Update README Quick Start to use ./scripts/install.sh - Update .env.example with GENERATE_ME placeholders for all secrets Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
b29314fd80
commit
5153587baf
5 files changed
+170
-17
No files matched your search
Executable
+122
@@ -0,0 +1,122 @@
|
||||
#!/usr/bin/env sh
|
||||
set -e
|
||||
|
||||
# ───────────────────────────────────────────────────────────
|
||||
# Elydora Open Source — One-click deployment
|
||||
# ───────────────────────────────────────────────────────────
|
||||
|
||||
printf '\n'
|
||||
printf ' ╔══════════════════════════════════════════╗\n'
|
||||
printf ' ║ Elydora Open Source Installer ║\n'
|
||||
printf ' ║ Self-hosted AI audit platform ║\n'
|
||||
printf ' ╚══════════════════════════════════════════╝\n'
|
||||
printf '\n'
|
||||
|
||||
# ── helpers ────────────────────────────────────────────────
|
||||
|
||||
fail() { printf '\n[ERROR] %s\n' "$1" >&2; exit 1; }
|
||||
info() { printf '[INFO] %s\n' "$1"; }
|
||||
ok() { printf '[OK] %s\n' "$1"; }
|
||||
|
||||
# Platform-aware sed in-place (macOS needs '')
|
||||
sedi() {
|
||||
if [ "$(uname)" = "Darwin" ]; then
|
||||
sed -i '' "$@"
|
||||
else
|
||||
sed -i "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
# ── 1. check prerequisites ────────────────────────────────
|
||||
|
||||
info "Checking prerequisites..."
|
||||
|
||||
command -v docker >/dev/null 2>&1 \
|
||||
|| fail "docker is not installed. See https://docs.docker.com/get-docker/"
|
||||
|
||||
docker compose version >/dev/null 2>&1 \
|
||||
|| fail "docker compose (v2) is not available. See https://docs.docker.com/compose/install/"
|
||||
|
||||
command -v openssl >/dev/null 2>&1 \
|
||||
|| fail "openssl is not installed."
|
||||
|
||||
command -v curl >/dev/null 2>&1 \
|
||||
|| fail "curl is not installed."
|
||||
|
||||
ok "All prerequisites satisfied."
|
||||
|
||||
# ── 2. generate .env ───────────────────────────────────────
|
||||
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
if [ -f .env ]; then
|
||||
info "Existing .env found — skipping secret generation."
|
||||
else
|
||||
info "Generating .env from .env.example..."
|
||||
|
||||
[ -f .env.example ] || fail ".env.example not found in project root."
|
||||
|
||||
cp .env.example .env
|
||||
|
||||
# Generate secrets
|
||||
PG_PASS=$(openssl rand -hex 24)
|
||||
MINIO_PASS=$(openssl rand -hex 24)
|
||||
JWT=$(openssl rand -hex 32)
|
||||
SIGNING_KEY=$(openssl genpkey -algorithm ed25519 2>/dev/null \
|
||||
| openssl pkcs8 -topk8 -nocrypt -outform DER 2>/dev/null \
|
||||
| tail -c 32 \
|
||||
| base64 \
|
||||
| tr '+/' '-_' \
|
||||
| tr -d '=\n')
|
||||
|
||||
[ -n "$PG_PASS" ] || fail "Failed to generate Postgres password."
|
||||
[ -n "$MINIO_PASS" ] || fail "Failed to generate MinIO password."
|
||||
[ -n "$JWT" ] || fail "Failed to generate JWT secret."
|
||||
[ -n "$SIGNING_KEY" ] || fail "Failed to generate Ed25519 signing key."
|
||||
|
||||
# Replace placeholders
|
||||
sedi "s|POSTGRES_PASSWORD=GENERATE_ME|POSTGRES_PASSWORD=${PG_PASS}|" .env
|
||||
sedi "s|elydora:GENERATE_ME@postgres|elydora:${PG_PASS}@postgres|" .env
|
||||
sedi "s|MINIO_ROOT_PASSWORD=GENERATE_ME|MINIO_ROOT_PASSWORD=${MINIO_PASS}|" .env
|
||||
sedi "s|MINIO_SECRET_KEY=GENERATE_ME|MINIO_SECRET_KEY=${MINIO_PASS}|" .env
|
||||
sedi "s|JWT_SECRET=GENERATE_ME|JWT_SECRET=${JWT}|" .env
|
||||
sedi "s|ELYDORA_SIGNING_KEY=GENERATE_ME|ELYDORA_SIGNING_KEY=${SIGNING_KEY}|" .env
|
||||
|
||||
chmod 600 .env
|
||||
|
||||
ok "Generated .env with fresh secrets (permissions 0600)."
|
||||
fi
|
||||
|
||||
# ── 3. docker compose up ──────────────────────────────────
|
||||
|
||||
info "Starting services with docker compose..."
|
||||
docker compose up -d
|
||||
|
||||
# ── 4. wait for API health ────────────────────────────────
|
||||
|
||||
info "Waiting for API to become healthy (up to 60 s)..."
|
||||
|
||||
elapsed=0
|
||||
while [ "$elapsed" -lt 60 ]; do
|
||||
if curl -sf http://localhost:8787/v1/health >/dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
sleep 2
|
||||
elapsed=$((elapsed + 2))
|
||||
done
|
||||
|
||||
if [ "$elapsed" -ge 60 ]; then
|
||||
fail "API did not become healthy within 60 seconds. Run 'docker compose logs api' to diagnose."
|
||||
fi
|
||||
|
||||
# ── 5. done ───────────────────────────────────────────────
|
||||
|
||||
printf '\n'
|
||||
printf ' ╔══════════════════════════════════════════╗\n'
|
||||
printf ' ║ Elydora is running! ║\n'
|
||||
printf ' ╠══════════════════════════════════════════╣\n'
|
||||
printf ' ║ Console: http://localhost:3000 ║\n'
|
||||
printf ' ║ API: http://localhost:8787 ║\n'
|
||||
printf ' ║ MinIO Console: http://localhost:9001 ║\n'
|
||||
printf ' ╚══════════════════════════════════════════╝\n'
|
||||
printf '\n'
|
||||
Reference in new issue
Block a user