Skip to main content
Chroma is an open-source vector database designed for AI applications that need to store, query, and manage embeddings efficiently. This tutorial demonstrates how to deploy Chroma with persistent storage on Upsun, along with both Python and Node.js client applications that can ingest documents and store their embeddings.
The complete source code for this tutorial is available on GitHub: upsun/tutorial-chromadb. You can clone this repository and deploy it directly to Upsun.

Why Chroma?

Chroma excels in several use cases:
  • Semantic Search: Find documents based on meaning rather than exact keyword matches
  • Retrieval Augmented Generation (RAG): Enhance LLMs with relevant context from your knowledge base
  • Recommendation Systems: Build similarity-based recommendation engines
  • Content Classification: Automatically categorize documents based on their semantic content
  • Duplicate Detection: Identify similar or duplicate content across large document collections

Architecture Overview

Our setup includes three applications:
  1. Chroma Server: The vector database with persistent storage
  2. Python Application: Uses uv for dependency management and Flask for the web interface
  3. Node.js Application: TypeScript-based Express server
Both client applications can ingest markdown documents, generate embeddings using OpenAI’s API, and store them in Chroma.

Chroma configuration on Upsun

The .upsun/config.yaml file defines our multi-applications setup. Let’s start with the Chroma server configuration:
Key configuration points for Chroma:
  • Persistent Storage: Chroma uses mounted volumes to persist data between deployments
  • uv Integration: Uses uv for fast, reliable dependency management
  • Internal Access: Other applications connect via internal networking
Note that Chroma doesn’t have a public HTTP endpoint, it’s only accessible internally within the Upsun platform. The Python and Node.js applications will establish relationships to Chroma through their respective configurations, allowing them to connect to the vector database using the internal chroma.internal hostname.

Python implementation

The Python application uses uv for dependency management and includes both ingestion and web interface capabilities.

Upsun configuration

The Python app route configuration:

Document ingestion

The ingestion script processes markdown files and stores their embeddings:

Flask web interface

The main application provides a web interface to view stored documents:

Node.js implementation

The Node.js application uses TypeScript and Express, with similar document ingestion capabilities.

Upsun configuration

The Node.js app route configuration:

TypeScript ingestion script

Express web server

Deployment

To deploy this setup:
  1. Clone the repository:
  2. Create a new Upsun project:
  3. Set up the OpenAI environment variable:
  4. Deploy to Upsun:
The deployment process will:
  • Set up the Chroma server with persistent storage
  • Build and deploy both Python and Node.js applications
  • Automatically run document ingestion during deployment
  • Configure internal networking between applications
The deploy hook injests the data for both apps:
You can now access your deployed applications with the endpoint displayed in the CLI or the console.

Python app:

Python app

Node.js app:

Node.js app Both applications will display the ingested documents and their chunk counts, demonstrating successful embedding storage in Chroma with persistent storage across deployments.
Last modified on April 27, 2026