#!/usr/bin/env bash # ============================================================= # Komodo Installer - Proxmox LXC (Alpine 3.22, Privileged) # Fixed & Production-Ready | ASCII-SAFE VERSION # License: MIT # Source: https://komo.do # ============================================================= set -euo pipefail # ------------------ Load Core Functions ----------------------- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../core/build.func" # ------------------ App Configuration ------------------------ APP="Komodo" var_tags="${var_tags:-docker}" var_cpu="${var_cpu:-2}" var_ram="${var_ram:-2048}" var_disk="${var_disk:-10}" var_os="${var_os:-alpine}" var_version="${var_version:-3.22}" var_unprivileged="${var_unprivileged:-0}" # MUST BE 0 # ------------------ Header & Validation ---------------------- header_info "$APP" variables color catch_errors # ------------------ Enforce Privileged LXC ------------------- if [[ "$var_unprivileged" -eq 1 ]]; then msg_error "Komodo requires a PRIVILEGED LXC with nesting=1" echo "Please recreate the container with:" echo " --unprivileged 0 --features nesting=1,keyctl=1" exit 1 fi # ------------------ Install Docker + Compose v2 ------------- msg_info "Installing Docker + Compose v2 plugin" $STD apk add --no-cache \ ca-certificates openssl \ docker docker-cli docker-cli-compose openrc msg_ok "Docker & Compose plugin installed" msg_info "Enabling Docker service" $STD rc-update add docker boot $STD rc-service docker start || { msg_error "Failed to start Docker"; exit 1; } # Wait for Docker daemon msg_info "Waiting for Docker daemon..." while ! docker info >/dev/null 2>&1; do sleep 1; done msg_ok "Docker daemon ready" # ------------------ Choose Database -------------------------- echo "Choose the database for Komodo installation:" echo " 1) MongoDB (recommended)" echo " 2) FerretDB" read -rp "Enter your choice (default: 1): " DB_CHOICE DB_CHOICE=${DB_CHOICE:-1} case $DB_CHOICE in 1) COMPOSE_FILE="mongo.compose.yaml" ;; 2) COMPOSE_FILE="ferretdb.compose.yaml" ;; *) echo "Invalid choice. Defaulting to MongoDB."; COMPOSE_FILE="mongo.compose.yaml" ;; esac export COMPOSE_FILE # ------------------ Download Compose Files ------------------- msg_info "Downloading $COMPOSE_FILE" mkdir -p /opt/komodo && cd /opt/komodo curl -fsSL "https://raw.githubusercontent.com/moghtech/komodo/main/compose/$COMPOSE_FILE" -o "$COMPOSE_FILE" curl -fsSL "https://raw.githubusercontent.com/moghtech/komodo/main/compose/compose.env" -o "compose.env" msg_ok "Compose files downloaded" # ------------------ Generate Secrets ------------------------- msg_info "Generating secure secrets" DB_PASSWORD=$(openssl rand -base64 16 | tr -d '/+=') PASSKEY=$(openssl rand -base64 24 | tr -d '/+=') WEBHOOK_SECRET=$(openssl rand -base64 24 | tr -d '/+=') JWT_SECRET=$(openssl rand -base64 24 | tr -d '/+=') sed -i \ -e "s/^KOMODO_DB_USERNAME=.*/KOMODO_DB_USERNAME=komodo_admin/" \ -e "s|^KOMODO_DB_PASSWORD=.*|KOMODO_DB_PASSWORD=${DB_PASSWORD}|" \ -e "s|^KOMODO_PASSKEY=.*|KOMODO_PASSKEY=${PASSKEY}|" \ -e "s|^KOMODO_WEBHOOK_SECRET=.*|KOMODO_WEBHOOK_SECRET=${WEBHOOK_SECRET}|" \ -e "s|^KOMODO_JWT_SECRET=.*|KOMODO_JWT_SECRET=${JWT_SECRET}|" \ compose.env msg_ok "Secrets generated and injected" # ------------------ Start Komodo ----------------------------- msg_info "Starting Komodo stack" if docker compose -p komodo -f "$COMPOSE_FILE" --env-file compose.env up -d; then msg_ok "Komodo stack started" else msg_error "Failed to start Komodo - showing logs" docker compose -p komodo -f "$COMPOSE_FILE" logs exit 1 fi # ------------------ Health Check ----------------------------- msg_info "Waiting for Komodo to be healthy (max 60s)..." for i in {1..30}; do if curl -s http://localhost:3000/health | grep -q '"status":"healthy"'; then msg_ok "Komodo is healthy and ready!" break fi sleep 2 done [[ $i -eq 30 ]] && { msg_error "Health check timed out"; exit 1; } # ------------------ Final Setup ------------------------------ motd_ssh customize msg_info "Cleaning up" $STD apk cache clean msg_ok "Cleanup complete" # ------------------ Success Message -------------------------- IP=$(hostname -I | awk '{print $1}') echo echo "=== KOMODO INSTALLATION COMPLETE ===" echo "Access the web interface at:" echo " http://$IP:3000" echo "Admin password is stored in:" echo " /opt/komodo/compose.env" echo echo "To update later, run: update_komodo.sh" echo