851 lines
29 KiB
Bash
Executable file
851 lines
29 KiB
Bash
Executable file
#!/bin/bash
|
||
|
||
set -e
|
||
|
||
# Expected resource requirements
|
||
EXPECTED_DOCKER_RAM_GB=10
|
||
EXPECTED_DISK_GB=32
|
||
|
||
# Parse command line arguments
|
||
SHUTDOWN_MODE=false
|
||
DELETE_DATA_MODE=false
|
||
|
||
while [[ $# -gt 0 ]]; do
|
||
case $1 in
|
||
--shutdown)
|
||
SHUTDOWN_MODE=true
|
||
shift
|
||
;;
|
||
--delete-data)
|
||
DELETE_DATA_MODE=true
|
||
shift
|
||
;;
|
||
--help|-h)
|
||
echo "Onyx Installation Script"
|
||
echo ""
|
||
echo "Usage: $0 [OPTIONS]"
|
||
echo ""
|
||
echo "Options:"
|
||
echo " --shutdown Stop (pause) Onyx containers"
|
||
echo " --delete-data Remove all Onyx data (containers, volumes, and files)"
|
||
echo " --help, -h Show this help message"
|
||
echo ""
|
||
echo "Examples:"
|
||
echo " $0 # Install Onyx"
|
||
echo " $0 --shutdown # Pause Onyx services"
|
||
echo " $0 --delete-data # Completely remove Onyx and all data"
|
||
exit 0
|
||
;;
|
||
*)
|
||
echo "Unknown option: $1"
|
||
echo "Use --help for usage information"
|
||
exit 1
|
||
;;
|
||
esac
|
||
done
|
||
|
||
# Colors for output
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
BLUE='\033[0;34m'
|
||
BOLD='\033[1m'
|
||
NC='\033[0m' # No Color
|
||
|
||
# Step counter variables
|
||
CURRENT_STEP=0
|
||
TOTAL_STEPS=8
|
||
|
||
# Print colored output
|
||
print_success() {
|
||
echo -e "${GREEN}✓${NC} $1"
|
||
}
|
||
|
||
print_error() {
|
||
echo -e "${RED}✗${NC} $1"
|
||
}
|
||
|
||
print_info() {
|
||
echo -e "${YELLOW}ℹ${NC} $1"
|
||
}
|
||
|
||
print_step() {
|
||
CURRENT_STEP=$((CURRENT_STEP + 1))
|
||
echo ""
|
||
echo -e "${BLUE}${BOLD}=== $1 - Step ${CURRENT_STEP}/${TOTAL_STEPS} ===${NC}"
|
||
echo ""
|
||
}
|
||
|
||
print_warning() {
|
||
echo -e "${YELLOW}⚠${NC} $1"
|
||
}
|
||
|
||
# Handle shutdown mode
|
||
if [ "$SHUTDOWN_MODE" = true ]; then
|
||
echo ""
|
||
echo -e "${BLUE}${BOLD}=== Shutting down Onyx ===${NC}"
|
||
echo ""
|
||
|
||
if [ -d "onyx_data/deployment" ]; then
|
||
print_info "Stopping Onyx containers..."
|
||
|
||
# Check if docker-compose.yml exists
|
||
if [ -f "onyx_data/deployment/docker-compose.yml" ]; then
|
||
# Determine compose command
|
||
if docker compose version &> /dev/null; then
|
||
COMPOSE_CMD="docker compose"
|
||
elif command -v docker-compose &> /dev/null; then
|
||
COMPOSE_CMD="docker-compose"
|
||
else
|
||
print_error "Docker Compose not found. Cannot stop containers."
|
||
exit 1
|
||
fi
|
||
|
||
# Stop containers (without removing them)
|
||
(cd onyx_data/deployment && $COMPOSE_CMD -f docker-compose.yml stop)
|
||
if [ $? -eq 0 ]; then
|
||
print_success "Onyx containers stopped (paused)"
|
||
else
|
||
print_error "Failed to stop containers"
|
||
exit 1
|
||
fi
|
||
else
|
||
print_warning "docker-compose.yml not found in onyx_data/deployment"
|
||
fi
|
||
else
|
||
print_warning "Onyx data directory not found. Nothing to shutdown."
|
||
fi
|
||
|
||
echo ""
|
||
print_success "Onyx shutdown complete!"
|
||
exit 0
|
||
fi
|
||
|
||
# Handle delete data mode
|
||
if [ "$DELETE_DATA_MODE" = true ]; then
|
||
echo ""
|
||
echo -e "${RED}${BOLD}=== WARNING: This will permanently delete all Onyx data ===${NC}"
|
||
echo ""
|
||
print_warning "This action will remove:"
|
||
echo " • All Onyx containers and volumes"
|
||
echo " • All downloaded files and configurations"
|
||
echo " • All user data and documents"
|
||
echo ""
|
||
read -p "Are you sure you want to continue? Type 'DELETE' to confirm: " -r
|
||
echo ""
|
||
|
||
if [ "$REPLY" != "DELETE" ]; then
|
||
print_info "Operation cancelled."
|
||
exit 0
|
||
fi
|
||
|
||
print_info "Removing Onyx containers and volumes..."
|
||
|
||
if [ -d "onyx_data/deployment" ]; then
|
||
# Check if docker-compose.yml exists
|
||
if [ -f "onyx_data/deployment/docker-compose.yml" ]; then
|
||
# Determine compose command
|
||
if docker compose version &> /dev/null; then
|
||
COMPOSE_CMD="docker compose"
|
||
elif command -v docker-compose &> /dev/null; then
|
||
COMPOSE_CMD="docker-compose"
|
||
else
|
||
print_error "Docker Compose not found. Cannot remove containers."
|
||
exit 1
|
||
fi
|
||
|
||
# Stop and remove containers with volumes
|
||
(cd onyx_data/deployment && $COMPOSE_CMD -f docker-compose.yml down -v)
|
||
if [ $? -eq 0 ]; then
|
||
print_success "Onyx containers and volumes removed"
|
||
else
|
||
print_error "Failed to remove containers and volumes"
|
||
fi
|
||
fi
|
||
fi
|
||
|
||
print_info "Removing data directories..."
|
||
if [ -d "onyx_data" ]; then
|
||
rm -rf onyx_data
|
||
print_success "Data directories removed"
|
||
else
|
||
print_warning "No onyx_data directory found"
|
||
fi
|
||
|
||
echo ""
|
||
print_success "All Onyx data has been permanently deleted!"
|
||
exit 0
|
||
fi
|
||
|
||
# ASCII Art Banner
|
||
echo ""
|
||
echo -e "${BLUE}${BOLD}"
|
||
echo " ____ "
|
||
echo " / __ \ "
|
||
echo "| | | |_ __ _ ___ __ "
|
||
echo "| | | | '_ \| | | \ \/ / "
|
||
echo "| |__| | | | | |_| |> < "
|
||
echo " \____/|_| |_|\__, /_/\_\ "
|
||
echo " __/ | "
|
||
echo " |___/ "
|
||
echo -e "${NC}"
|
||
echo "Welcome to Onyx Installation Script"
|
||
echo "===================================="
|
||
echo ""
|
||
|
||
# User acknowledgment section
|
||
echo -e "${YELLOW}${BOLD}This script will:${NC}"
|
||
echo "1. Download deployment files for Onyx into a new 'onyx_data' directory"
|
||
echo "2. Check your system resources (Docker, memory, disk space)"
|
||
echo "3. Guide you through deployment options (version, authentication)"
|
||
echo ""
|
||
|
||
# Only prompt for acknowledgment if running interactively
|
||
if [ -t 0 ]; then
|
||
echo -e "${YELLOW}${BOLD}Please acknowledge and press Enter to continue...${NC}"
|
||
read -r
|
||
echo ""
|
||
else
|
||
echo -e "${YELLOW}${BOLD}Running in non-interactive mode - proceeding automatically...${NC}"
|
||
echo ""
|
||
fi
|
||
|
||
# GitHub repo base URL - using docker-compose-easy branch
|
||
GITHUB_RAW_URL="https://raw.githubusercontent.com/onyx-dot-app/onyx/main/deployment/docker_compose"
|
||
|
||
# Check system requirements
|
||
print_step "Verifying Docker installation"
|
||
|
||
# Check Docker
|
||
if ! command -v docker &> /dev/null; then
|
||
print_error "Docker is not installed. Please install Docker first."
|
||
echo "Visit: https://docs.docker.com/get-docker/"
|
||
exit 1
|
||
fi
|
||
DOCKER_VERSION=$(docker --version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1)
|
||
print_success "Docker $DOCKER_VERSION is installed"
|
||
|
||
# Check Docker Compose
|
||
if docker compose version &> /dev/null; then
|
||
COMPOSE_VERSION=$(docker compose version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1)
|
||
COMPOSE_CMD="docker compose"
|
||
print_success "Docker Compose $COMPOSE_VERSION is installed (plugin)"
|
||
elif command -v docker-compose &> /dev/null; then
|
||
COMPOSE_VERSION=$(docker-compose --version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1)
|
||
COMPOSE_CMD="docker-compose"
|
||
print_success "Docker Compose $COMPOSE_VERSION is installed (standalone)"
|
||
else
|
||
print_error "Docker Compose is not installed. Please install Docker Compose first."
|
||
echo "Visit: https://docs.docker.com/compose/install/"
|
||
exit 1
|
||
fi
|
||
|
||
# Function to compare version numbers
|
||
version_compare() {
|
||
# Returns 0 if $1 <= $2, 1 if $1 > $2
|
||
local version1=$1
|
||
local version2=$2
|
||
|
||
# Split versions into components
|
||
local v1_major=$(echo $version1 | cut -d. -f1)
|
||
local v1_minor=$(echo $version1 | cut -d. -f2)
|
||
local v1_patch=$(echo $version1 | cut -d. -f3)
|
||
|
||
local v2_major=$(echo $version2 | cut -d. -f1)
|
||
local v2_minor=$(echo $version2 | cut -d. -f2)
|
||
local v2_patch=$(echo $version2 | cut -d. -f3)
|
||
|
||
# Compare major version
|
||
if [ "$v1_major" -lt "$v2_major" ]; then
|
||
return 0
|
||
elif [ "$v1_major" -gt "$v2_major" ]; then
|
||
return 1
|
||
fi
|
||
|
||
# Compare minor version
|
||
if [ "$v1_minor" -lt "$v2_minor" ]; then
|
||
return 0
|
||
elif [ "$v1_minor" -gt "$v2_minor" ]; then
|
||
return 1
|
||
fi
|
||
|
||
# Compare patch version
|
||
if [ "$v1_patch" -le "$v2_patch" ]; then
|
||
return 0
|
||
else
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
# Check Docker daemon
|
||
if ! docker info &> /dev/null; then
|
||
print_error "Docker daemon is not running. Please start Docker."
|
||
exit 1
|
||
fi
|
||
print_success "Docker daemon is running"
|
||
|
||
# Check Docker resources
|
||
print_step "Verifying Docker resources"
|
||
|
||
# Get Docker system info
|
||
DOCKER_INFO=$(docker system info 2>/dev/null)
|
||
|
||
# Try to get memory allocation (method varies by platform)
|
||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||
# macOS - Docker Desktop
|
||
if command -v jq &> /dev/null && [ -f ~/Library/Group\ Containers/group.com.docker/settings.json ]; then
|
||
MEMORY_MB=$(cat ~/Library/Group\ Containers/group.com.docker/settings.json 2>/dev/null | jq '.memoryMiB // 0' 2>/dev/null || echo "0")
|
||
else
|
||
# Try to get from docker system info
|
||
MEMORY_BYTES=$(docker system info 2>/dev/null | grep -i "total memory" | grep -oE '[0-9]+\.[0-9]+' | head -1)
|
||
if [ -n "$MEMORY_BYTES" ]; then
|
||
# Convert from GiB to MB (multiply by 1024)
|
||
MEMORY_MB=$(echo "$MEMORY_BYTES * 1024" | bc 2>/dev/null | cut -d. -f1)
|
||
if [ -z "$MEMORY_MB" ]; then
|
||
MEMORY_MB="0"
|
||
fi
|
||
else
|
||
MEMORY_MB="0"
|
||
fi
|
||
fi
|
||
else
|
||
# Linux - Native Docker
|
||
MEMORY_KB=$(grep MemTotal /proc/meminfo | grep -oE '[0-9]+' || echo "0")
|
||
MEMORY_MB=$((MEMORY_KB / 1024))
|
||
fi
|
||
|
||
# Convert to GB for display
|
||
if [ "$MEMORY_MB" -gt 0 ]; then
|
||
MEMORY_GB=$((MEMORY_MB / 1024))
|
||
print_info "Docker memory allocation: ~${MEMORY_GB}GB"
|
||
else
|
||
print_warning "Could not determine Docker memory allocation"
|
||
MEMORY_MB=0
|
||
fi
|
||
|
||
# Check disk space (different commands for macOS vs Linux)
|
||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||
# macOS uses -g for GB
|
||
DISK_AVAILABLE=$(df -g . | awk 'NR==2 {print $4}')
|
||
else
|
||
# Linux uses -BG for GB
|
||
DISK_AVAILABLE=$(df -BG . | awk 'NR==2 {print $4}' | sed 's/G//')
|
||
fi
|
||
print_info "Available disk space: ${DISK_AVAILABLE}GB"
|
||
|
||
# Resource requirements check
|
||
RESOURCE_WARNING=false
|
||
EXPECTED_RAM_MB=$((EXPECTED_DOCKER_RAM_GB * 1024))
|
||
|
||
if [ "$MEMORY_MB" -gt 0 ] && [ "$MEMORY_MB" -lt "$EXPECTED_RAM_MB" ]; then
|
||
print_warning "Docker has less than ${EXPECTED_DOCKER_RAM_GB}GB RAM allocated (found: ~${MEMORY_GB}GB)"
|
||
RESOURCE_WARNING=true
|
||
fi
|
||
|
||
if [ "$DISK_AVAILABLE" -lt "$EXPECTED_DISK_GB" ]; then
|
||
print_warning "Less than ${EXPECTED_DISK_GB}GB disk space available (found: ${DISK_AVAILABLE}GB)"
|
||
RESOURCE_WARNING=true
|
||
fi
|
||
|
||
if [ "$RESOURCE_WARNING" = true ]; then
|
||
echo ""
|
||
print_warning "Onyx recommends at least ${EXPECTED_DOCKER_RAM_GB}GB RAM and ${EXPECTED_DISK_GB}GB disk space for optimal performance."
|
||
echo ""
|
||
read -p "Do you want to continue anyway? (y/N): " -n 1 -r
|
||
echo ""
|
||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||
print_info "Installation cancelled. Please allocate more resources and try again."
|
||
exit 1
|
||
fi
|
||
print_info "Proceeding with installation despite resource limitations..."
|
||
fi
|
||
|
||
# Create directory structure
|
||
print_step "Creating directory structure"
|
||
if [ -d "onyx_data" ]; then
|
||
print_info "Directory structure already exists"
|
||
print_success "Using existing onyx_data directory"
|
||
else
|
||
mkdir -p onyx_data/deployment
|
||
mkdir -p onyx_data/data/nginx/local
|
||
print_success "Directory structure created"
|
||
fi
|
||
|
||
# Download all required files
|
||
print_step "Downloading Onyx configuration files"
|
||
print_info "This step downloads all necessary configuration files from GitHub..."
|
||
echo ""
|
||
print_info "Downloading the following files:"
|
||
echo " • docker-compose.yml - Main Docker Compose configuration"
|
||
echo " • env.template - Environment variables template"
|
||
echo " • nginx/app.conf.template - Nginx web server configuration"
|
||
echo " • nginx/run-nginx.sh - Nginx startup script"
|
||
echo " • README.md - Documentation and setup instructions"
|
||
echo ""
|
||
|
||
# Download Docker Compose file
|
||
COMPOSE_FILE="onyx_data/deployment/docker-compose.yml"
|
||
print_info "Downloading docker-compose.yml..."
|
||
if curl -fsSL -o "$COMPOSE_FILE" "${GITHUB_RAW_URL}/docker-compose.yml" 2>/dev/null; then
|
||
print_success "Docker Compose file downloaded successfully"
|
||
|
||
# Check if Docker Compose version is older than 2.24.0 and show warning
|
||
if version_compare "$COMPOSE_VERSION" "2.24.0"; then
|
||
print_warning "Docker Compose version $COMPOSE_VERSION is older than 2.24.0"
|
||
echo ""
|
||
print_warning "The docker-compose.yml file uses the newer env_file format that requires Docker Compose 2.24.0 or later."
|
||
echo ""
|
||
print_info "To use this configuration with your current Docker Compose version, you have two options:"
|
||
echo ""
|
||
echo "1. Upgrade Docker Compose to version 2.24.0 or later (recommended)"
|
||
echo " Visit: https://docs.docker.com/compose/install/"
|
||
echo ""
|
||
echo "2. Manually replace all env_file sections in docker-compose.yml"
|
||
echo " Change from:"
|
||
echo " env_file:"
|
||
echo " - path: .env"
|
||
echo " required: false"
|
||
echo " To:"
|
||
echo " env_file: .env"
|
||
echo ""
|
||
print_warning "The installation will continue, but may fail if Docker Compose cannot parse the file."
|
||
echo ""
|
||
read -p "Do you want to continue anyway? (y/N): " -n 1 -r
|
||
echo ""
|
||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||
print_info "Installation cancelled. Please upgrade Docker Compose or manually edit the docker-compose.yml file."
|
||
exit 1
|
||
fi
|
||
print_info "Proceeding with installation despite Docker Compose version compatibility issues..."
|
||
fi
|
||
else
|
||
print_error "Failed to download Docker Compose file"
|
||
print_info "Please ensure you have internet connection and try again"
|
||
exit 1
|
||
fi
|
||
|
||
# Download env.template file
|
||
ENV_TEMPLATE="onyx_data/deployment/env.template"
|
||
print_info "Downloading env.template..."
|
||
if curl -fsSL -o "$ENV_TEMPLATE" "${GITHUB_RAW_URL}/env.template" 2>/dev/null; then
|
||
print_success "Environment template downloaded successfully"
|
||
else
|
||
print_error "Failed to download env.template"
|
||
print_info "Please ensure you have internet connection and try again"
|
||
exit 1
|
||
fi
|
||
|
||
# Download nginx config files
|
||
NGINX_BASE_URL="https://raw.githubusercontent.com/onyx-dot-app/onyx/main/deployment/data/nginx"
|
||
|
||
# Download app.conf.template
|
||
NGINX_CONFIG="onyx_data/data/nginx/app.conf.template"
|
||
print_info "Downloading nginx configuration template..."
|
||
if curl -fsSL -o "$NGINX_CONFIG" "$NGINX_BASE_URL/app.conf.template" 2>/dev/null; then
|
||
print_success "Nginx configuration template downloaded"
|
||
else
|
||
print_error "Failed to download nginx configuration template"
|
||
print_info "Please ensure you have internet connection and try again"
|
||
exit 1
|
||
fi
|
||
|
||
# Download run-nginx.sh script
|
||
NGINX_RUN_SCRIPT="onyx_data/data/nginx/run-nginx.sh"
|
||
print_info "Downloading nginx startup script..."
|
||
if curl -fsSL -o "$NGINX_RUN_SCRIPT" "$NGINX_BASE_URL/run-nginx.sh" 2>/dev/null; then
|
||
chmod +x "$NGINX_RUN_SCRIPT"
|
||
print_success "Nginx startup script downloaded and made executable"
|
||
else
|
||
print_error "Failed to download nginx startup script"
|
||
print_info "Please ensure you have internet connection and try again"
|
||
exit 1
|
||
fi
|
||
|
||
# Download README file
|
||
README_FILE="onyx_data/README.md"
|
||
print_info "Downloading README.md..."
|
||
if curl -fsSL -o "$README_FILE" "${GITHUB_RAW_URL}/README.md" 2>/dev/null; then
|
||
print_success "README.md downloaded successfully"
|
||
else
|
||
print_error "Failed to download README.md"
|
||
print_info "Please ensure you have internet connection and try again"
|
||
exit 1
|
||
fi
|
||
|
||
# Create empty local directory marker (if needed)
|
||
touch "onyx_data/data/nginx/local/.gitkeep"
|
||
print_success "All configuration files downloaded successfully"
|
||
|
||
# Set up deployment configuration
|
||
print_step "Setting up deployment configs"
|
||
ENV_FILE="onyx_data/deployment/.env"
|
||
|
||
# Check if services are already running
|
||
if [ -d "onyx_data/deployment" ] && [ -f "onyx_data/deployment/docker-compose.yml" ]; then
|
||
# Determine compose command
|
||
if docker compose version &> /dev/null; then
|
||
COMPOSE_CMD="docker compose"
|
||
elif command -v docker-compose &> /dev/null; then
|
||
COMPOSE_CMD="docker-compose"
|
||
else
|
||
COMPOSE_CMD=""
|
||
fi
|
||
|
||
if [ -n "$COMPOSE_CMD" ]; then
|
||
# Check if any containers are running
|
||
RUNNING_CONTAINERS=$(cd onyx_data/deployment && $COMPOSE_CMD -f docker-compose.yml ps -q 2>/dev/null | wc -l)
|
||
if [ "$RUNNING_CONTAINERS" -gt 0 ]; then
|
||
print_error "Onyx services are currently running!"
|
||
echo ""
|
||
print_info "To make configuration changes, you must first shut down the services."
|
||
echo ""
|
||
print_info "Please run the following command to shut down Onyx:"
|
||
echo -e " ${BOLD}./install.sh --shutdown${NC}"
|
||
echo ""
|
||
print_info "Then run this script again to make your changes."
|
||
exit 1
|
||
fi
|
||
fi
|
||
fi
|
||
|
||
if [ -f "$ENV_FILE" ]; then
|
||
print_info "Existing .env file found. What would you like to do?"
|
||
echo ""
|
||
echo "• Press Enter to restart with current configuration"
|
||
echo "• Type 'update' to update to a newer version"
|
||
echo ""
|
||
read -p "Choose an option [default: restart]: " -r
|
||
echo ""
|
||
|
||
if [ "$REPLY" = "update" ]; then
|
||
print_info "Update selected. Which tag would you like to deploy?"
|
||
echo ""
|
||
echo "• Press Enter for latest (recommended)"
|
||
echo "• Type a specific tag (e.g., v0.1.0)"
|
||
echo ""
|
||
read -p "Enter tag [default: latest]: " -r VERSION
|
||
echo ""
|
||
|
||
if [ -z "$VERSION" ]; then
|
||
VERSION="latest"
|
||
print_info "Selected: Latest version"
|
||
else
|
||
print_info "Selected: $VERSION"
|
||
fi
|
||
|
||
# Update .env file with new version
|
||
print_info "Updating configuration for version $VERSION..."
|
||
if grep -q "^IMAGE_TAG=" "$ENV_FILE"; then
|
||
# Update existing IMAGE_TAG line
|
||
sed -i.bak "s/^IMAGE_TAG=.*/IMAGE_TAG=$VERSION/" "$ENV_FILE"
|
||
else
|
||
# Add IMAGE_TAG line if it doesn't exist
|
||
echo "IMAGE_TAG=$VERSION" >> "$ENV_FILE"
|
||
fi
|
||
print_success "Updated IMAGE_TAG to $VERSION in .env file"
|
||
print_success "Configuration updated for upgrade"
|
||
else
|
||
print_info "Keeping existing configuration..."
|
||
print_success "Will restart with current settings"
|
||
fi
|
||
else
|
||
print_info "No existing .env file found. Setting up new deployment..."
|
||
echo ""
|
||
|
||
# Ask for version
|
||
print_info "Which tag would you like to deploy?"
|
||
echo ""
|
||
echo "• Press Enter for latest (recommended)"
|
||
echo "• Type a specific tag (e.g., v0.1.0)"
|
||
echo ""
|
||
read -p "Enter tag [default: latest]: " -r VERSION
|
||
echo ""
|
||
|
||
if [ -z "$VERSION" ]; then
|
||
VERSION="latest"
|
||
print_info "Selected: Latest tag"
|
||
else
|
||
print_info "Selected: $VERSION"
|
||
fi
|
||
|
||
# Ask for authentication schema
|
||
echo ""
|
||
print_info "Which authentication schema would you like to set up?"
|
||
echo ""
|
||
echo "1) Basic - Username/password authentication"
|
||
echo "2) No Auth - Open access (development/testing)"
|
||
echo ""
|
||
read -p "Choose an option (1-2) [default 1]: " -r AUTH_CHOICE
|
||
echo ""
|
||
|
||
case "${AUTH_CHOICE:-1}" in
|
||
1)
|
||
AUTH_SCHEMA="basic"
|
||
print_info "Selected: Basic authentication"
|
||
;;
|
||
2)
|
||
AUTH_SCHEMA="disabled"
|
||
print_info "Selected: No authentication"
|
||
;;
|
||
*)
|
||
AUTH_SCHEMA="basic"
|
||
print_info "Invalid choice, using basic authentication"
|
||
;;
|
||
esac
|
||
|
||
# Create .env file from template
|
||
print_info "Creating .env file with your selections..."
|
||
cp "$ENV_TEMPLATE" "$ENV_FILE"
|
||
|
||
# Update IMAGE_TAG with selected version
|
||
print_info "Setting IMAGE_TAG to $VERSION..."
|
||
sed -i.bak "s/^IMAGE_TAG=.*/IMAGE_TAG=$VERSION/" "$ENV_FILE"
|
||
print_success "IMAGE_TAG set to $VERSION"
|
||
|
||
# Configure authentication settings based on selection
|
||
if [ "$AUTH_SCHEMA" = "disabled" ]; then
|
||
# Disable authentication in .env file
|
||
sed -i.bak 's/^AUTH_TYPE=.*/AUTH_TYPE=disabled/' "$ENV_FILE" 2>/dev/null || true
|
||
print_success "Authentication disabled in configuration"
|
||
else
|
||
# Enable basic authentication
|
||
sed -i.bak 's/^AUTH_TYPE=.*/AUTH_TYPE=basic/' "$ENV_FILE" 2>/dev/null || true
|
||
print_success "Basic authentication enabled in configuration"
|
||
fi
|
||
|
||
print_success ".env file created with your preferences"
|
||
echo ""
|
||
print_info "IMPORTANT: The .env file has been configured with your selections."
|
||
print_info "You can customize it later for:"
|
||
echo " • Advanced authentication (OAuth, SAML, etc.)"
|
||
echo " • AI model configuration"
|
||
echo " • Domain settings (for production)"
|
||
echo ""
|
||
fi
|
||
|
||
# Function to check if a port is available
|
||
is_port_available() {
|
||
local port=$1
|
||
|
||
# Try netcat first if available
|
||
if command -v nc &> /dev/null; then
|
||
# Try to connect to the port, if it fails, the port is available
|
||
! nc -z localhost "$port" 2>/dev/null
|
||
# Fallback using curl/telnet approach
|
||
elif command -v curl &> /dev/null; then
|
||
# Try to connect with curl, if it fails, the port might be available
|
||
! curl -s --max-time 1 --connect-timeout 1 "http://localhost:$port" >/dev/null 2>&1
|
||
# Final fallback using lsof if available
|
||
elif command -v lsof &> /dev/null; then
|
||
# Check if any process is listening on the port
|
||
! lsof -i ":$port" >/dev/null 2>&1
|
||
else
|
||
# No port checking tools available, assume port is available
|
||
print_warning "No port checking tools available (nc, curl, lsof). Assuming port $port is available."
|
||
return 0
|
||
fi
|
||
}
|
||
|
||
# Function to find the first available port starting from a given port
|
||
find_available_port() {
|
||
local start_port=${1:-3000}
|
||
local port=$start_port
|
||
|
||
while [ $port -le 65535 ]; do
|
||
if is_port_available "$port"; then
|
||
echo "$port"
|
||
return 0
|
||
fi
|
||
port=$((port + 1))
|
||
done
|
||
|
||
# If no port found, return the original port as fallback
|
||
echo "$start_port"
|
||
return 1
|
||
}
|
||
|
||
# Check for port checking tools availability
|
||
PORT_CHECK_AVAILABLE=false
|
||
if command -v nc &> /dev/null || command -v curl &> /dev/null || command -v lsof &> /dev/null; then
|
||
PORT_CHECK_AVAILABLE=true
|
||
fi
|
||
|
||
if [ "$PORT_CHECK_AVAILABLE" = false ]; then
|
||
print_warning "No port checking tools found (nc, curl, lsof). Port detection may not work properly."
|
||
print_info "Consider installing one of these tools for reliable automatic port detection."
|
||
fi
|
||
|
||
# Find available port for nginx
|
||
print_step "Checking for available ports"
|
||
AVAILABLE_PORT=$(find_available_port 3000)
|
||
|
||
if [ "$AVAILABLE_PORT" != "3000" ]; then
|
||
print_info "Port 3000 is in use, found available port: $AVAILABLE_PORT"
|
||
else
|
||
print_info "Port 3000 is available"
|
||
fi
|
||
|
||
# Export HOST_PORT for docker-compose
|
||
export HOST_PORT=$AVAILABLE_PORT
|
||
print_success "Using port $AVAILABLE_PORT for nginx"
|
||
|
||
# Determine if we're using the latest tag
|
||
# Read IMAGE_TAG from .env file and remove any quotes or whitespace
|
||
CURRENT_IMAGE_TAG=$(grep "^IMAGE_TAG=" "$ENV_FILE" | head -1 | cut -d'=' -f2 | tr -d ' "'"'"'')
|
||
if [ "$CURRENT_IMAGE_TAG" = "latest" ]; then
|
||
USE_LATEST=true
|
||
print_info "Using 'latest' tag - will force pull and recreate containers"
|
||
else
|
||
USE_LATEST=false
|
||
fi
|
||
|
||
# Pull Docker images with reduced output
|
||
print_step "Pulling Docker images"
|
||
print_info "This may take several minutes depending on your internet connection..."
|
||
echo ""
|
||
print_info "Downloading Docker images (this may take a while)..."
|
||
(cd onyx_data/deployment && $COMPOSE_CMD -f docker-compose.yml pull --quiet)
|
||
if [ $? -eq 0 ]; then
|
||
print_success "Docker images downloaded successfully"
|
||
else
|
||
print_error "Failed to download Docker images"
|
||
exit 1
|
||
fi
|
||
|
||
# Start services
|
||
print_step "Starting Onyx services"
|
||
print_info "Launching containers..."
|
||
echo ""
|
||
if [ "$USE_LATEST" = true ]; then
|
||
print_info "Force pulling latest images and recreating containers..."
|
||
(cd onyx_data/deployment && $COMPOSE_CMD -f docker-compose.yml up -d --pull always --force-recreate)
|
||
else
|
||
(cd onyx_data/deployment && $COMPOSE_CMD -f docker-compose.yml up -d)
|
||
fi
|
||
if [ $? -ne 0 ]; then
|
||
print_error "Failed to start Onyx services"
|
||
exit 1
|
||
fi
|
||
|
||
# Monitor container startup
|
||
print_step "Verifying container health"
|
||
print_info "Waiting for containers to initialize (10 seconds)..."
|
||
|
||
# Progress bar for waiting
|
||
for i in {1..10}; do
|
||
printf "\r[%-10s] %d%%" $(printf '#%.0s' $(seq 1 $((i*10/10)))) $((i*100/10))
|
||
sleep 1
|
||
done
|
||
echo ""
|
||
echo ""
|
||
|
||
# Check for restart loops
|
||
print_info "Checking container health status..."
|
||
RESTART_ISSUES=false
|
||
CONTAINERS=$(cd onyx_data/deployment && $COMPOSE_CMD -f docker-compose.yml ps -q 2>/dev/null)
|
||
|
||
for CONTAINER in $CONTAINERS; do
|
||
CONTAINER_NAME=$(docker inspect --format '{{.Name}}' "$CONTAINER" | sed 's/^\/\|^onyx_data_deployment_//g')
|
||
RESTART_COUNT=$(docker inspect --format '{{.RestartCount}}' "$CONTAINER")
|
||
STATUS=$(docker inspect --format '{{.State.Status}}' "$CONTAINER")
|
||
|
||
if [ "$STATUS" = "running" ]; then
|
||
if [ "$RESTART_COUNT" -gt 2 ]; then
|
||
print_error "$CONTAINER_NAME is in a restart loop (restarted $RESTART_COUNT times)"
|
||
RESTART_ISSUES=true
|
||
else
|
||
print_success "$CONTAINER_NAME is healthy"
|
||
fi
|
||
elif [ "$STATUS" = "restarting" ]; then
|
||
print_error "$CONTAINER_NAME is stuck restarting"
|
||
RESTART_ISSUES=true
|
||
else
|
||
print_warning "$CONTAINER_NAME status: $STATUS"
|
||
fi
|
||
done
|
||
|
||
echo ""
|
||
|
||
if [ "$RESTART_ISSUES" = true ]; then
|
||
print_error "Some containers are experiencing issues!"
|
||
echo ""
|
||
print_info "Please check the logs for more information:"
|
||
echo " (cd onyx_data/deployment && $COMPOSE_CMD -f docker-compose.yml logs)"
|
||
echo ""
|
||
print_info "If the issue persists, please contact: founders@onyx.app"
|
||
echo "Include the output of the logs command in your message."
|
||
exit 1
|
||
fi
|
||
|
||
# Health check function
|
||
check_onyx_health() {
|
||
local max_attempts=600 # 10 minutes * 60 attempts per minute (every 1 second)
|
||
local attempt=1
|
||
local port=${HOST_PORT:-3000}
|
||
|
||
print_info "Checking Onyx service health..."
|
||
echo "Containers are healthy, waiting for database migrations and service initialization to finish."
|
||
echo ""
|
||
|
||
while [ $attempt -le $max_attempts ]; do
|
||
# Check for successful HTTP responses (200, 301, 302, etc.)
|
||
local http_code=$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:$port")
|
||
if echo "$http_code" | grep -qE "^(200|301|302|303|307|308)$"; then
|
||
return 0
|
||
fi
|
||
|
||
# Show animated progress with time elapsed
|
||
local elapsed=$((attempt))
|
||
local minutes=$((elapsed / 60))
|
||
local seconds=$((elapsed % 60))
|
||
|
||
# Create animated dots with fixed spacing (cycle through 1-3 dots)
|
||
local dots=""
|
||
case $((attempt % 3)) in
|
||
0) dots=". " ;;
|
||
1) dots=".. " ;;
|
||
2) dots="..." ;;
|
||
esac
|
||
|
||
# Clear line and show progress with fixed spacing
|
||
printf "\r\033[KChecking Onyx service%s (%dm %ds elapsed)" "$dots" "$minutes" "$seconds"
|
||
|
||
sleep 1
|
||
attempt=$((attempt + 1))
|
||
done
|
||
|
||
echo "" # New line after the progress line
|
||
return 1
|
||
}
|
||
|
||
# Success message
|
||
print_step "Installation Complete!"
|
||
print_success "All containers are running successfully!"
|
||
echo ""
|
||
|
||
# Run health check
|
||
if check_onyx_health; then
|
||
echo ""
|
||
echo -e "${GREEN}${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||
echo -e "${GREEN}${BOLD} 🎉 Onyx service is ready! 🎉${NC}"
|
||
echo -e "${GREEN}${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||
else
|
||
print_warning "Health check timed out after 10 minutes"
|
||
print_info "Containers are running, but the web service may still be initializing (or something went wrong)"
|
||
echo ""
|
||
echo -e "${YELLOW}${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||
echo -e "${YELLOW}${BOLD} ⚠️ Onyx containers are running ⚠️${NC}"
|
||
echo -e "${YELLOW}${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||
fi
|
||
echo ""
|
||
print_info "Access Onyx at:"
|
||
echo -e " ${BOLD}http://localhost:${HOST_PORT}${NC}"
|
||
echo ""
|
||
print_info "If authentication is enabled, you can create your admin account here:"
|
||
echo " • Visit http://localhost:${HOST_PORT}/auth/signup to create your admin account"
|
||
echo " • The first user created will automatically have admin privileges"
|
||
echo ""
|
||
print_info "Refer to the README in the onyx_data directory for more information."
|
||
echo ""
|
||
print_info "For help or issues, contact: founders@onyx.app"
|
||
echo ""
|