diff --git a/registry/coder-labs/modules/open-webui/README.md b/registry/coder-labs/modules/open-webui/README.md new file mode 100644 index 00000000..6281560f --- /dev/null +++ b/registry/coder-labs/modules/open-webui/README.md @@ -0,0 +1,109 @@ +--- +display_name: Open WebUI +description: A self-hosted AI chat interface supporting various LLM providers +icon: ../../../../.icons/openai.svg +verified: false +tags: [ai, llm, chat, web-ui, python] +--- + +# Open WebUI + +Open WebUI is a user-friendly web interface for interacting with Large Language Models. It provides a ChatGPT-like interface that can connect to various LLM providers including OpenAI, Ollama, and more. + +This module installs and runs Open WebUI using Python and pip within your Coder workspace. + +## Prerequisites + +- **Python 3.11 or higher** (automatically installed from deadsnakes PPA if not present) +- `pip` package manager +- `sudo` access (for automatic Python installation if needed) +- Port 8080 (default) or your custom port must be available + +**Note:** If Python 3.11+ is not found, the module will automatically: +1. Add the deadsnakes PPA repository +2. Install Python 3.11 with venv and dev packages +3. Install pip if not available + +## Basic Usage + +```tf +module "open-webui" { + count = data.coder_workspace.me.start_count + source = "registry.coder.com/coder-labs/open-webui/coder" + version = "1.0.0" + agent_id = coder_agent.main.id +} +``` + +## Examples + +### Custom Port + +Run Open WebUI on a custom port: + +```tf +module "open-webui" { + count = data.coder_workspace.me.start_count + source = "registry.coder.com/coder-labs/open-webui/coder" + version = "1.0.0" + agent_id = coder_agent.main.id + port = 3000 +} +``` + +### Public Sharing + +Make Open WebUI accessible to authenticated Coder users: + +```tf +module "open-webui" { + count = data.coder_workspace.me.start_count + source = "registry.coder.com/coder-labs/open-webui/coder" + version = "1.0.0" + agent_id = coder_agent.main.id + share = "authenticated" +} +``` + +### Custom Log Path and Grouping + +```tf +module "open-webui" { + count = data.coder_workspace.me.start_count + source = "registry.coder.com/coder-labs/open-webui/coder" + version = "1.0.0" + agent_id = coder_agent.main.id + log_path = "/var/log/open-webui.log" + group = "AI Tools" + order = 1 +} +``` + +## Features + +- 🐍 Pure Python installation (no Docker required) +- 🔄 Automatic Python 3.11+ installation from deadsnakes PPA +- 💾 Data stored in `~/.open-webui` directory +- 🚀 Runs in background as a Python process +- 📝 Configurable logging +- 🌐 Subdomain support for clean URLs +- 🔧 Compatible with various LLM providers (OpenAI, Ollama, etc.) + +## Data Persistence + +Open WebUI data is stored in `~/.open-webui` directory in your workspace, which includes: +- User accounts +- Chat history +- Settings and configurations +- Model configurations + +## Installation Process + +The module automatically handles the installation: + +1. **Check Python Version**: Looks for Python 3.11+ (checks python3.13, python3.12, python3.11, python3, python) +2. **Install Python if Needed**: If not found, installs Python 3.11 from deadsnakes PPA +3. **Install pip**: Ensures pip is available +4. **Install Open WebUI**: Installs open-webui package via pip +5. **Start Server**: Launches Open WebUI on the specified port + diff --git a/registry/coder-labs/modules/open-webui/main.tf b/registry/coder-labs/modules/open-webui/main.tf new file mode 100644 index 00000000..3276dc64 --- /dev/null +++ b/registry/coder-labs/modules/open-webui/main.tf @@ -0,0 +1,72 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + coder = { + source = "coder/coder" + version = ">= 2.5" + } + } +} + +# Add required variables for your modules and remove any unneeded variables +variable "agent_id" { + type = string + description = "The ID of a Coder agent." +} + +variable "log_path" { + type = string + description = "The path to log Open WebUI to." + default = "/tmp/open-webui.log" +} + +variable "port" { + type = number + description = "The port to run Open WebUI on." + default = 8080 +} + +variable "share" { + type = string + default = "owner" + validation { + condition = var.share == "owner" || var.share == "authenticated" || var.share == "public" + error_message = "Incorrect value. Please set either 'owner', 'authenticated', or 'public'." + } +} + +variable "order" { + type = number + description = "The order determines the position of app in the UI presentation. The lowest order is shown first and apps with equal order are sorted by name (ascending order)." + default = null +} + +variable "group" { + type = string + description = "The name of a group that this app belongs to." + default = null +} + +resource "coder_script" "open-webui" { + agent_id = var.agent_id + display_name = "open-webui" + icon = "/icon/openai.svg" + script = templatefile("${path.module}/run.sh", { + LOG_PATH : var.log_path, + PORT : var.port, + }) + run_on_start = true +} + +resource "coder_app" "open-webui" { + agent_id = var.agent_id + slug = "open-webui" + display_name = "Open WebUI" + url = "http://localhost:${var.port}" + icon = "/icon/openai.svg" + subdomain = true + share = var.share + order = var.order + group = var.group +} diff --git a/registry/coder-labs/modules/open-webui/run.sh b/registry/coder-labs/modules/open-webui/run.sh new file mode 100755 index 00000000..3a472ec2 --- /dev/null +++ b/registry/coder-labs/modules/open-webui/run.sh @@ -0,0 +1,93 @@ +#!/usr/bin/env sh + +# Convert templated variables to shell variables +# shellcheck disable=SC2269 +LOG_PATH=${LOG_PATH} +# shellcheck disable=SC2269 +PORT=${PORT} + +# shellcheck disable=SC2059 +printf '\033[0;1mInstalling Open WebUI...\n\n' + +# Function to check Python version +check_python_version() { + python_cmd="$1" + if command -v "$python_cmd" > /dev/null 2>&1; then + version=$("$python_cmd" --version 2>&1 | awk '{print $2}') + major=$(echo "$version" | cut -d. -f1) + minor=$(echo "$version" | cut -d. -f2) + if [ "$major" -eq 3 ] && [ "$minor" -ge 11 ]; then + echo "$python_cmd" + return 0 + fi + fi + return 1 +} + +# Find suitable Python version +PYTHON_CMD="" +for cmd in python3.13 python3.12 python3.11 python3 python; do + if result=$(check_python_version "$cmd"); then + PYTHON_CMD="$result" + echo "✅ Found suitable Python: $PYTHON_CMD ($($PYTHON_CMD --version 2>&1))" + break + fi +done + +if [ -z "$PYTHON_CMD" ]; then + echo "❌ Python 3.11 or higher is not installed" + echo "" + echo "Installing Python 3.11 from deadsnakes PPA..." + + # Check if we have sudo access + if ! command -v sudo > /dev/null 2>&1; then + echo "❌ sudo is not available. Please install Python 3.11+ manually" + exit 1 + fi + + # Install Python 3.11 + echo "📦 Adding deadsnakes PPA..." + sudo apt-get update -qq + sudo apt-get install -y software-properties-common + sudo add-apt-repository -y ppa:deadsnakes/ppa + sudo apt-get update -qq + + echo "📦 Installing Python 3.11..." + sudo apt-get install -y python3.11 python3.11-venv python3.11-dev + + PYTHON_CMD="python3.11" + echo "✅ Python 3.11 installed successfully" +fi + +# Check if pip is available +if ! "$PYTHON_CMD" -m pip --version > /dev/null 2>&1; then + echo "📦 Installing pip..." + curl -sS https://bootstrap.pypa.io/get-pip.py | "$PYTHON_CMD" +fi + +# Check if open-webui is already installed +if ! "$PYTHON_CMD" -m pip show open-webui > /dev/null 2>&1; then + echo "📦 Installing Open WebUI..." + "$PYTHON_CMD" -m pip install --user open-webui + echo "🥳 Open WebUI has been installed" +else + echo "✅ Open WebUI is already installed" +fi + +# Check if Open WebUI is already running +if pgrep -f "open-webui serve" > /dev/null; then + echo "✅ Open WebUI is already running" + exit 0 +fi + +echo "👷 Starting Open WebUI in background..." +echo "Check logs at $LOG_PATH" + +# Start Open WebUI +"$PYTHON_CMD" -m open_webui serve --host 0.0.0.0 --port "$PORT" > "$LOG_PATH" 2>&1 & + +# Wait a bit for the server to start +sleep 2 + +echo "🥳 Open WebUI is starting!" +echo "Access it at http://localhost:$PORT"