Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .icons/perplexica.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added registry/coder-labs/.images/perplexica.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
55 changes: 55 additions & 0 deletions registry/coder-labs/modules/perplexica/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
display_name: Perplexica
description: Run Perplexica AI search engine in your workspace via Docker
icon: ../../../../.icons/perplexica.svg
verified: false
tags: [ai, search, docker]
---

# Perplexica

Run [Perplexica](https://github.com/ItzCrazyKns/Perplexica), a privacy-focused AI search engine, in your Coder workspace. Supports cloud providers (OpenAI, Anthropic Claude) and local LLMs via Ollama.

```tf
module "perplexica" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder-labs/perplexica/coder"
version = "1.0.0"
agent_id = coder_agent.main.id
}
```

This module uses the full Perplexica image with embedded SearXNG for simpler setup with no external dependencies.

![Perplexica](../../.images/perplexica.png)

## Prerequisites

This module requires Docker to be available on the host.

## Examples

### With API Keys

```tf
module "perplexica" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder-labs/perplexica/coder"
version = "1.0.0"
agent_id = coder_agent.main.id
openai_api_key = var.openai_api_key
anthropic_api_key = var.anthropic_api_key
}
```

### With Local Ollama

```tf
module "perplexica" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder-labs/perplexica/coder"
version = "1.0.0"
agent_id = coder_agent.main.id
ollama_api_url = "http://ollama-external-endpoint:11434"
}
```
108 changes: 108 additions & 0 deletions registry/coder-labs/modules/perplexica/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
terraform {
required_version = ">= 1.0"

required_providers {
coder = {
source = "coder/coder"
version = ">= 2.5"
}
}
}

variable "agent_id" {
type = string
description = "The ID of a Coder agent."
}

variable "docker_socket" {
type = string
description = "(Optional) Docker socket URI"
default = ""
}

variable "port" {
type = number
description = "The port to run Perplexica on."
default = 3000
}

variable "data_path" {
type = string
description = "Host path to mount for Perplexica data persistence."
default = "./perplexica-data"
}

variable "uploads_path" {
type = string
description = "Host path to mount for Perplexica file uploads."
default = "./perplexica-uploads"
}

variable "openai_api_key" {
type = string
description = "OpenAI API key."
default = ""
sensitive = true
}

variable "anthropic_api_key" {
type = string
description = "Anthropic API key for Claude models."
default = ""
sensitive = true
}

variable "ollama_api_url" {
type = string
description = "Ollama API URL for local LLM support."
default = ""
}

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" "perplexica" {
agent_id = var.agent_id
display_name = "Perplexica"
icon = "/icon/perplexica.svg"
script = templatefile("${path.module}/run.sh", {
DOCKER_HOST : var.docker_socket,
PORT : var.port,
DATA_PATH : var.data_path,
UPLOADS_PATH : var.uploads_path,
OPENAI_API_KEY : var.openai_api_key,
ANTHROPIC_API_KEY : var.anthropic_api_key,
OLLAMA_API_URL : var.ollama_api_url,
})
run_on_start = true
}

resource "coder_app" "perplexica" {
agent_id = var.agent_id
slug = "perplexica"
display_name = "Perplexica"
url = "http://localhost:${var.port}"
icon = "/icon/perplexica.svg"
subdomain = true
share = var.share
order = var.order
group = var.group
}
26 changes: 26 additions & 0 deletions registry/coder-labs/modules/perplexica/perplexica.tftest.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
run "plan_basic" {
command = plan

variables {
agent_id = "test-agent"
}

assert {
condition = resource.coder_app.perplexica.url == "http://localhost:3000"
error_message = "Default port should be 3000"
}
}

run "plan_custom_port" {
command = plan

variables {
agent_id = "test-agent"
port = 8080
}

assert {
condition = resource.coder_app.perplexica.url == "http://localhost:8080"
error_message = "Should use custom port"
}
}
67 changes: 67 additions & 0 deletions registry/coder-labs/modules/perplexica/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#!/usr/bin/env sh

set -eu

BOLD='\033[0;1m'
RESET='\033[0m'

printf "$${BOLD}Starting Perplexica...$${RESET}\n"

# Set Docker host if provided
if [ -n "${DOCKER_HOST}" ]; then
export DOCKER_HOST="${DOCKER_HOST}"
fi

# Wait for docker to become ready
max_attempts=10
delay=2
attempt=1

while ! docker ps; do
if [ $attempt -ge $max_attempts ]; then
echo "Failed to list containers after $${max_attempts} attempts."
exit 1
fi
echo "Attempt $${attempt} failed, retrying in $${delay}s..."
sleep $delay
attempt=$(expr "$attempt" + 1)
delay=$(expr "$delay" \* 2)
done

# Pull the image
IMAGE="itzcrazykns1337/perplexica:latest"
docker pull "$${IMAGE}"

# Build docker run command
DOCKER_ARGS="-d --rm --name perplexica -p ${PORT}:3000"

# Add mounts - convert relative paths to absolute
DATA_PATH="${DATA_PATH}"
UPLOADS_PATH="${UPLOADS_PATH}"

mkdir -p "$${DATA_PATH}"
mkdir -p "$${UPLOADS_PATH}"

DATA_PATH_ABS=$(cd "$${DATA_PATH}" && pwd)
UPLOADS_PATH_ABS=$(cd "$${UPLOADS_PATH}" && pwd)

DOCKER_ARGS="$${DOCKER_ARGS} -v $${DATA_PATH_ABS}:/home/perplexica/data"
DOCKER_ARGS="$${DOCKER_ARGS} -v $${UPLOADS_PATH_ABS}:/home/perplexica/uploads"

# Add environment variables if provided
if [ -n "${OPENAI_API_KEY}" ]; then
DOCKER_ARGS="$${DOCKER_ARGS} -e OPENAI_API_KEY=${OPENAI_API_KEY}"
fi

if [ -n "${ANTHROPIC_API_KEY}" ]; then
DOCKER_ARGS="$${DOCKER_ARGS} -e ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}"
fi

if [ -n "${OLLAMA_API_URL}" ]; then
DOCKER_ARGS="$${DOCKER_ARGS} -e OLLAMA_API_URL=${OLLAMA_API_URL}"
fi

# Run container
docker run $${DOCKER_ARGS} "$${IMAGE}"

printf "\n$${BOLD}Perplexica is running on port ${PORT}$${RESET}\n"