Core Services Managed by Project N.O.M.A.D.: Complete Technical Overview
Project N.O.M.A.D. manages six containerized core services—Kiwix, Qdrant, Ollama, CyberChef, FlatNotes, and Kolibri—defined in the service seeder and orchestrated via Docker with centralized constants in SERVICE_NAMES.
Project N.O.M.A.D. (Network-Optimized Modular-Application-Deployment) by Crosstalk-Solutions is an open-source, offline-ready application deployment platform. It ships with a curated set of core services that can be installed, started, stopped, and updated through both the web UI and CLI, with all definitions centralized in the service seeder and referenced throughout the codebase via the SERVICE_NAMES constant.
Core Services Managed by Project N.O.M.A.D.
The platform defines six essential services in admin/database/seeders/service_seeder.ts, each configured with specific Docker images and deployment parameters. These services cover information retrieval, AI/ML, data manipulation, and education.
Kiwix: Information Library
Kiwix provides offline access to Wikipedia, medical references, and other encyclopedic content without requiring internet connectivity. The service runs the ghcr.io/kiwix/kiwix-serve:3.8.1 container image and is referenced in code as SERVICE_NAMES.KIWIX with the value nomad_kiwix_server.
Qdrant: Vector Database
Qdrant stores and searches high-dimensional embeddings for RAG (Retrieval-Augmented Generation) and semantic search capabilities. It uses the qdrant/qdrant:v1.16 image and is identified by SERVICE_NAMES.QDRANT (nomad_qdrant). This service serves as a dependency for the AI assistant functionality.
Ollama: AI Assistant
Ollama delivers a local Large Language Model (LLM) chat interface that requires no external API calls, operating entirely offline. Running on ollama/ollama:0.15.2, this service depends on Qdrant for vector storage and is referenced as SERVICE_NAMES.OLLAMA (nomad_ollama).
CyberChef: Data Tools
CyberChef functions as a "Swiss-army-knife" for data encoding, encryption, and analysis. The service uses the ghcr.io/gchq/cyberchef:10.19.4 image and is identified by SERVICE_NAMES.CYBERCHEF (nomad_cyberchef).
FlatNotes: Notes
FlatNotes offers simple markdown-based note-taking with local storage capabilities. It deploys using the dullage/flatnotes:v5.5.4 image and is referenced as SERVICE_NAMES.FLATNOTES (nomad_flatnotes).
Kolibri: Education Platform
Kolibri serves as an offline learning platform designed for schools, supporting videos, quizzes, and structured curriculum delivery. The service runs treehouses/kolibri:0.12.8 and is identified by SERVICE_NAMES.KOLIBRI (nomad_kolibri).
How Project N.O.M.A.D. Manages Services
The platform employs a layered architecture for service management, combining database persistence with Docker orchestration to handle the core services managed by Project N.O.M.A.D.
Persistence Layer
Service definitions are stored in the services table, modeled by admin/app/models/service.ts. Key fields include service_name, container_image, installed, installation_status, and optional depends_on (e.g., Ollama depends on Qdrant). The service seeder populates these records on first run via admin/database/seeders/service_seeder.ts, ensuring all six core services are present in the database with their default configurations.
Docker Orchestration
The DockerService class (admin/app/services/docker_service.ts) manages container lifecycle operations using the SERVICE_NAMES constants. It handles starting, stopping, and retrieving URLs for containers. For example, fetching a service URL uses the constant identifier:
const url = await this.getServiceURL(SERVICE_NAMES.OLLAMA);
The implementation at line 443 of docker_service.ts resolves the container's bound host port to construct accessible URLs.
Installation Flow
The ServiceSeeder runs during initial setup, executing the run() method (lines 64-73) to populate the database with default service entries. This ensures that core services are immediately available for installation through the administrative interface.
Working with Core Services Programmatically
Developers interact with these services through TypeScript models and service classes. The following examples demonstrate common operations against the services table and Docker runtime.
Listing All Core Services
Query the database for all six services using the canonical identifiers:
import Service from '#models/service'
async function listCoreServices() {
const services = await Service.query()
.whereIn('service_name', [
SERVICE_NAMES.KIWIX,
SERVICE_NAMES.QDRANT,
SERVICE_NAMES.OLLAMA,
SERVICE_NAMES.CYBERCHEF,
SERVICE_NAMES.FLATNOTES,
SERVICE_NAMES.KOLIBRI,
])
.select('service_name', 'friendly_name', 'installed', 'ui_location')
return services
}
This query leverages the Service Lucid ORM model and the central SERVICE_NAMES enumeration to retrieve current installation status and UI endpoints.
Checking Service Installation Status
Verify whether a specific service like Ollama is installed using SystemService:
import SystemService from '#app/services/system_service'
async function isOllamaReady() {
const systemService = new SystemService()
return await systemService.checkServiceInstalled(SERVICE_NAMES.OLLAMA)
}
The checkServiceInstalled method (line 74 of system_service.ts) queries the installed boolean flag from the corresponding database record.
Retrieving Service UI URLs
Construct accessible web interfaces for installed services through DockerService:
import DockerService from '#app/services/docker_service'
async function getServiceUI(name: string) {
const docker = new DockerService()
const url = await docker.getServiceURL(name)
return `${url}/${await docker.getServiceUIPath(name)}`
}
// Example: UI URL for Kiwix
const kiwixUI = await getServiceUI(SERVICE_NAMES.KIWIX)
This pattern combines getServiceURL (line 443 of docker_service.ts) with path resolution to generate complete navigation links.
Summary
- Project N.O.M.A.D. manages six containerized core services: Kiwix, Qdrant, Ollama, CyberChef, FlatNotes, and Kolibri.
- Service identities are centralized in
admin/constants/service_names.tsvia theSERVICE_NAMESconstant object. - Default configurations are seeded via
admin/database/seeders/service_seeder.tson first run. - Runtime management occurs through
admin/app/services/docker_service.ts, which handles container lifecycle and URL discovery. - Database persistence uses the
Servicemodel (admin/app/models/service.ts) to track installation states and dependencies. - High-level health checks are available through
admin/app/services/system_service.ts.
Frequently Asked Questions
What is Project N.O.M.A.D.?
Project N.O.M.A.D. (Network-Optimized Modular-Application-Deployment) is an open-source platform by Crosstalk-Solutions designed for offline-first deployment of containerized applications. It enables users to install, manage, and run services like AI assistants and educational tools without requiring persistent internet connectivity.
How does Project N.O.M.A.D. handle Docker container orchestration?
The platform uses the DockerService class (admin/app/services/docker_service.ts) to abstract container operations. This service reads the SERVICE_NAMES constants to start, stop, and restart containers, retrieve bound port URLs, and apply configuration updates through a standardized TypeScript API.
Can additional services be added beyond the six core services?
While the service seeder (admin/database/seeders/service_seeder.ts) defines six default services, the architecture supports extension through the Service model and SERVICE_NAMES pattern. New services can be added to the database with corresponding container images, though they require manual configuration and potential updates to the orchestration logic.
Why does Ollama depend on Qdrant in Project N.O.M.A.D.?
Ollama utilizes Qdrant as its vector database backend to store and search high-dimensional embeddings for RAG (Retrieval-Augmented Generation) capabilities. This dependency is encoded in the depends_on field of the service definition, ensuring Qdrant initializes before Ollama during the startup sequence.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →