[Package] Typesense Search Engine - Fast, Typo-Tolerant Search
-
Hi Cloudron community!
I've created a Typesense Cloudron package that provides lightning-fast, typo-tolerant search functionality. Typesense is an open-source alternative to Algolia and an easier-to-use alternative to ElasticSearch.
Installation
You'll need the Cloudron CLI to install this. Here's the command:
cloudron install --image clientamp/typesense-cloudron:29.0.0 --location your-domain.com
What You Get
- Fast search with sub-second response times
- Typo tolerance - finds results even with spelling mistakes
- Auto-generated API keys with secure defaults
- CORS support for web application integration
- Health checks and monitoring for production use
- Automatic backups through Cloudron
Perfect For
E-commerce sites, documentation, content management, user directories - basically any application that needs fast, intelligent search.
I'm using it on my Ghost website now, see it in action: daveswift.com (it's a big upgrade over Ghost's native search!)
Requirements
- Cloudron 7.0.0 or higher
- Minimum 512MB RAM (1GB+ recommended for production)
How It Works
The package automatically generates secure API keys, sets up data directories, and configures everything needed for production use. You can then create search collections via REST API and integrate with any programming language.
Why Typesense?
It's simpler than ElasticSearch to set up and use, provides an open-source alternative to Algolia with no vendor lock-in, and includes real-time updates and typo tolerance out of the box.
Getting Started
Once installed, check out the Typesense API documentation for examples of creating collections, adding documents, and performing searches.
Docker Hub
Repository: https://hub.docker.com/r/clientamp/typesense-cloudron
Image:clientamp/typesense-cloudron:29.0.0
GitHub
Repository: https://github.com/clientamp/typesense-cloudron
This package has been tested and as I mentioned, is currently running in production on my Cloudron instance.
-
D Dave Swift referenced this topic
-
Sure, i’m using webhooks from Ghost (Settings >Integrations > Custom) to n8n when a post is created, updated, unpublished, or deleted and then n8n updates Typesense.
-
Will share more later, if you’d like more detail.
-
More details:
My integration focuses on two main parts: (1) setting up webhooks in Ghost to trigger real-time sync via n8n to Typesense, and (2) embedding the search UI directly in the Ghost theme for the frontend.
Ghost Webhook Setup (for Real-Time Sync)
In Ghost Admin (yourblog.com/ghost/#/integrations), I created a Custom Integration called "Typesense n8n Integration." This gives you a Content API key (used in n8n to fetch full post/page data).
Then, add webhooks for key events (publish, update, unpublish, delete). Each points to an n8n webhook URL:
-
Post published or Post updated:
https://n8n.yourdomain.com/webhook/ghost-typesense
(n8n workflow: Receives minimal payload with post ID, fetches full data via Ghost Content API/posts/{id}?key=CONTENT_API_KEY&include=tags,authors
, transforms to Typesense schema, upserts.) -
Post unpublished or Post deleted:
https://n8n.yourdomain.com/webhook/ghost-typesense-delete
(n8n: Extracts ID, sends DELETE to Typesense/collections/ghost/documents/{id}
.)
Ghost webhooks send limited data (e.g., just ID/slug), so n8n always fetches the full object. This keeps Typesense updated in near real-time (n8n adds ~30-60s delay, but it's seamless for users).
For initial bulk sync: Separate n8n workflows paginate Ghost API (
/posts/?key=CONTENT_API_KEY&limit=100&page=N&filter=status:published
), transform to NDJSON, and bulk import to Typesense withaction=upsert
.Frontend UI Integration in Ghost Theme
I used the official Typesense InstantSearch Adapter. In your custom theme's
default.hbs
(head section):<script src="https://cdn.jsdelivr.net/npm/typesense-instantsearch-adapter@2/dist/typesense-instantsearch-adapter.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/instantsearch.js@4"></script> <script src="{{asset 'js/search.js'}}"></script> <!-- Custom init script --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/instantsearch.css@8/themes/reset-min.css"> <link rel="stylesheet" href="{{asset 'css/search.css'}}"> <!-- Custom styles -->
In
assets/js/search.js
, initialize InstantSearch with your search-only Typesense key, query params (e.g.,query_by: 'title,excerpt,plaintext,tags.name,authors.name'
), and a custom hit template to display tags/authors:// Simplified excerpt const search = instantsearch({ indexName: 'ghost', searchClient: typesenseInstantsearchAdapter.searchClient }); search.addWidgets([ instantsearch.widgets.searchBox({ container: '.js-search-input' }), instantsearch.widgets.hits({ container: '.js-search-results', templates: { item: hit => ` <article> <h2><a href="${hit.url}">${hit.title}</a></h2> <p>${hit.excerpt}</p> <div>By ${hit.authors?.map(a => a.name).join(', ') || 'Unknown'}</div> <div>${hit.tags?.map(t => `<span class="tag">#${t.name}</span>`).join(' ') || ''}</div> </article> ` } }), // Add refinementList for facets (tags, authors, type) ]); search.start(); // Bind to theme's search button/modal
Styles in
search.css
for cards, facets sidebar, etc. Trigger the modal via a button in your header partial (e.g.,<button class="js-search-button">Search</button>
).This gives full control—e.g., facets for filtering by tags.
After making changes, Zip your theme and upload it in Ghost Admin and restart Ghost.
Hope this helps as an example!
-