feat(installer): add output file generation (credentials, INSTALL.md, config)
This commit is contained in:
@@ -955,3 +955,263 @@ verify_health() {
|
||||
fi
|
||||
log_success "All services healthy."
|
||||
}
|
||||
|
||||
# --- Output file generation ---
|
||||
|
||||
write_config_file() {
|
||||
local f="$INSTALL_DIR/cameleer.conf"
|
||||
cat > "$f" << EOF
|
||||
# Cameleer installation config
|
||||
# Generated by installer v${CAMELEER_INSTALLER_VERSION} on $(date -u '+%Y-%m-%d %H:%M:%S UTC')
|
||||
|
||||
install_dir=${INSTALL_DIR}
|
||||
public_host=${PUBLIC_HOST}
|
||||
public_protocol=${PUBLIC_PROTOCOL}
|
||||
admin_user=${ADMIN_USER}
|
||||
tls_mode=${TLS_MODE}
|
||||
http_port=${HTTP_PORT}
|
||||
https_port=${HTTPS_PORT}
|
||||
logto_console_port=${LOGTO_CONSOLE_PORT}
|
||||
logto_console_exposed=${LOGTO_CONSOLE_EXPOSED}
|
||||
vendor_enabled=${VENDOR_ENABLED}
|
||||
vendor_user=${VENDOR_USER}
|
||||
monitoring_network=${MONITORING_NETWORK}
|
||||
version=${VERSION}
|
||||
compose_project=${COMPOSE_PROJECT}
|
||||
docker_socket=${DOCKER_SOCKET}
|
||||
node_tls_reject=${NODE_TLS_REJECT}
|
||||
EOF
|
||||
log_info "Saved installer config to cameleer.conf"
|
||||
}
|
||||
|
||||
generate_credentials_file() {
|
||||
local f="$INSTALL_DIR/credentials.txt"
|
||||
cat > "$f" << EOF
|
||||
===========================================
|
||||
CAMELEER PLATFORM CREDENTIALS
|
||||
Generated: $(date -u '+%Y-%m-%d %H:%M:%S UTC')
|
||||
|
||||
SECURE THIS FILE AND DELETE AFTER NOTING
|
||||
THESE CREDENTIALS CANNOT BE RECOVERED
|
||||
===========================================
|
||||
|
||||
Admin Console: ${PUBLIC_PROTOCOL}://${PUBLIC_HOST}/platform/
|
||||
Admin User: ${ADMIN_USER}
|
||||
Admin Password: ${ADMIN_PASS}
|
||||
|
||||
PostgreSQL: cameleer / ${POSTGRES_PASSWORD}
|
||||
ClickHouse: default / ${CLICKHOUSE_PASSWORD}
|
||||
|
||||
EOF
|
||||
|
||||
if [ "$VENDOR_ENABLED" = "true" ]; then
|
||||
cat >> "$f" << EOF
|
||||
Vendor User: ${VENDOR_USER}
|
||||
Vendor Password: ${VENDOR_PASS}
|
||||
|
||||
EOF
|
||||
else
|
||||
echo "Vendor User: (not enabled)" >> "$f"
|
||||
echo "" >> "$f"
|
||||
fi
|
||||
|
||||
if [ "$LOGTO_CONSOLE_EXPOSED" = "true" ]; then
|
||||
echo "Logto Console: ${PUBLIC_PROTOCOL}://${PUBLIC_HOST}:${LOGTO_CONSOLE_PORT}" >> "$f"
|
||||
else
|
||||
echo "Logto Console: (not exposed)" >> "$f"
|
||||
fi
|
||||
|
||||
chmod 600 "$f"
|
||||
log_info "Saved credentials to credentials.txt"
|
||||
}
|
||||
|
||||
generate_install_doc() {
|
||||
local f="$INSTALL_DIR/INSTALL.md"
|
||||
local tls_desc="Self-signed (auto-generated)"
|
||||
[ "$TLS_MODE" = "custom" ] && tls_desc="Custom certificate"
|
||||
|
||||
cat > "$f" << EOF
|
||||
# Cameleer SaaS <20> Installation Documentation
|
||||
|
||||
## Installation Summary
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| **Version** | ${VERSION} |
|
||||
| **Date** | $(date -u '+%Y-%m-%d %H:%M:%S UTC') |
|
||||
| **Installer** | v${CAMELEER_INSTALLER_VERSION} |
|
||||
| **Install Directory** | ${INSTALL_DIR} |
|
||||
| **Hostname** | ${PUBLIC_HOST} |
|
||||
| **TLS** | ${tls_desc} |
|
||||
|
||||
## Service URLs
|
||||
|
||||
- **Platform UI:** ${PUBLIC_PROTOCOL}://${PUBLIC_HOST}/platform/
|
||||
- **API Endpoint:** ${PUBLIC_PROTOCOL}://${PUBLIC_HOST}/platform/api/
|
||||
EOF
|
||||
|
||||
if [ "$LOGTO_CONSOLE_EXPOSED" = "true" ]; then
|
||||
echo "- **Logto Admin Console:** ${PUBLIC_PROTOCOL}://${PUBLIC_HOST}:${LOGTO_CONSOLE_PORT}" >> "$f"
|
||||
fi
|
||||
|
||||
cat >> "$f" << 'EOF'
|
||||
|
||||
## First Steps
|
||||
|
||||
1. Open the Platform UI in your browser
|
||||
2. Log in with the admin credentials from `credentials.txt`
|
||||
3. Create your first tenant via the Vendor console
|
||||
4. The platform will provision a dedicated server instance for the tenant
|
||||
|
||||
## Architecture
|
||||
|
||||
| Container | Purpose |
|
||||
|---|---|
|
||||
| `traefik` | Reverse proxy, TLS termination, routing |
|
||||
| `postgres` | PostgreSQL database (SaaS + Logto + tenant schemas) |
|
||||
| `clickhouse` | Time-series storage (traces, metrics, logs) |
|
||||
| `logto` | OIDC identity provider + bootstrap |
|
||||
| `cameleer-saas` | SaaS platform (Spring Boot + React) |
|
||||
|
||||
Per-tenant `cameleer3-server` and `cameleer3-server-ui` containers are provisioned dynamically when tenants are created.
|
||||
|
||||
## Networking
|
||||
|
||||
EOF
|
||||
|
||||
cat >> "$f" << EOF
|
||||
| Port | Service |
|
||||
|---|---|
|
||||
| ${HTTP_PORT} | HTTP (redirects to HTTPS) |
|
||||
| ${HTTPS_PORT} | HTTPS (main entry point) |
|
||||
EOF
|
||||
|
||||
if [ "$LOGTO_CONSOLE_EXPOSED" = "true" ]; then
|
||||
echo "| ${LOGTO_CONSOLE_PORT} | Logto Admin Console |" >> "$f"
|
||||
fi
|
||||
|
||||
if [ -n "$MONITORING_NETWORK" ]; then
|
||||
cat >> "$f" << EOF
|
||||
|
||||
### Monitoring
|
||||
|
||||
Services are connected to the \`${MONITORING_NETWORK}\` Docker network with Prometheus labels for auto-discovery.
|
||||
EOF
|
||||
fi
|
||||
|
||||
cat >> "$f" << EOF
|
||||
|
||||
## TLS
|
||||
|
||||
**Mode:** ${tls_desc}
|
||||
EOF
|
||||
|
||||
if [ "$TLS_MODE" = "self-signed" ]; then
|
||||
cat >> "$f" << 'EOF'
|
||||
|
||||
The platform generated a self-signed certificate on first boot. To replace it:
|
||||
1. Log in as admin and navigate to **Certificates** in the vendor console
|
||||
2. Upload your certificate and key via the UI
|
||||
3. Activate the new certificate (zero-downtime swap)
|
||||
EOF
|
||||
fi
|
||||
|
||||
cat >> "$f" << EOF
|
||||
|
||||
## Data & Backups
|
||||
|
||||
| Docker Volume | Contains |
|
||||
|---|---|
|
||||
| \`pgdata\` | PostgreSQL data (tenants, licenses, audit) |
|
||||
| \`chdata\` | ClickHouse data (traces, metrics, logs) |
|
||||
| \`certs\` | TLS certificates |
|
||||
| \`bootstrapdata\` | Logto bootstrap results |
|
||||
|
||||
### Backup Commands
|
||||
|
||||
\`\`\`bash
|
||||
# PostgreSQL
|
||||
docker compose -p ${COMPOSE_PROJECT} exec postgres pg_dump -U cameleer cameleer_saas > backup.sql
|
||||
|
||||
# ClickHouse
|
||||
docker compose -p ${COMPOSE_PROJECT} exec clickhouse clickhouse-client --query "SELECT * FROM cameleer.traces FORMAT Native" > traces.native
|
||||
\`\`\`
|
||||
|
||||
## Upgrading
|
||||
|
||||
Re-run the installer with a new version:
|
||||
|
||||
\`\`\`bash
|
||||
curl -sfL https://install.cameleer.io | bash -s -- --install-dir ${INSTALL_DIR} --version NEW_VERSION
|
||||
\`\`\`
|
||||
|
||||
The installer preserves your \`.env\`, credentials, and data volumes. Only the compose file and images are updated.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Issue | Command |
|
||||
|---|---|
|
||||
| Service not starting | \`docker compose -p ${COMPOSE_PROJECT} logs SERVICE_NAME\` |
|
||||
| Bootstrap failed | \`docker compose -p ${COMPOSE_PROJECT} logs logto\` |
|
||||
| Routing issues | \`docker compose -p ${COMPOSE_PROJECT} logs traefik\` |
|
||||
| Database issues | \`docker compose -p ${COMPOSE_PROJECT} exec postgres psql -U cameleer -d cameleer_saas\` |
|
||||
|
||||
## Uninstalling
|
||||
|
||||
\`\`\`bash
|
||||
# Stop and remove containers
|
||||
cd ${INSTALL_DIR} && docker compose -p ${COMPOSE_PROJECT} down
|
||||
|
||||
# Remove data volumes (DESTRUCTIVE)
|
||||
cd ${INSTALL_DIR} && docker compose -p ${COMPOSE_PROJECT} down -v
|
||||
|
||||
# Remove install directory
|
||||
rm -rf ${INSTALL_DIR}
|
||||
\`\`\`
|
||||
EOF
|
||||
|
||||
log_info "Generated INSTALL.md"
|
||||
}
|
||||
|
||||
print_credentials() {
|
||||
echo ""
|
||||
echo -e "${BOLD}==========================================${NC}"
|
||||
echo -e "${BOLD} CAMELEER PLATFORM CREDENTIALS${NC}"
|
||||
echo -e "${BOLD}==========================================${NC}"
|
||||
echo ""
|
||||
echo -e " Admin Console: ${BLUE}${PUBLIC_PROTOCOL}://${PUBLIC_HOST}/platform/${NC}"
|
||||
echo -e " Admin User: ${BOLD}${ADMIN_USER}${NC}"
|
||||
echo -e " Admin Password: ${BOLD}${ADMIN_PASS}${NC}"
|
||||
echo ""
|
||||
echo -e " PostgreSQL: cameleer / ${POSTGRES_PASSWORD}"
|
||||
echo -e " ClickHouse: default / ${CLICKHOUSE_PASSWORD}"
|
||||
echo ""
|
||||
if [ "$VENDOR_ENABLED" = "true" ]; then
|
||||
echo -e " Vendor User: ${BOLD}${VENDOR_USER}${NC}"
|
||||
echo -e " Vendor Password: ${BOLD}${VENDOR_PASS}${NC}"
|
||||
echo ""
|
||||
fi
|
||||
if [ "$LOGTO_CONSOLE_EXPOSED" = "true" ]; then
|
||||
echo -e " Logto Console: ${BLUE}${PUBLIC_PROTOCOL}://${PUBLIC_HOST}:${LOGTO_CONSOLE_PORT}${NC}"
|
||||
echo ""
|
||||
fi
|
||||
echo -e " Credentials saved to: ${INSTALL_DIR}/credentials.txt"
|
||||
echo -e " ${YELLOW}Secure this file and delete after noting credentials.${NC}"
|
||||
echo ""
|
||||
}
|
||||
|
||||
print_summary() {
|
||||
echo -e "${GREEN}==========================================${NC}"
|
||||
echo -e "${GREEN} Installation complete!${NC}"
|
||||
echo -e "${GREEN}==========================================${NC}"
|
||||
echo ""
|
||||
echo " Install directory: $INSTALL_DIR"
|
||||
echo " Documentation: $INSTALL_DIR/INSTALL.md"
|
||||
echo ""
|
||||
echo " To manage the stack:"
|
||||
echo " cd $INSTALL_DIR"
|
||||
echo " docker compose -p $COMPOSE_PROJECT ps # status"
|
||||
echo " docker compose -p $COMPOSE_PROJECT logs -f # logs"
|
||||
echo " docker compose -p $COMPOSE_PROJECT down # stop"
|
||||
echo ""
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user