Skip to content

Tutorial E: Cesivi + Accept All + In-Memory + TfIdf on Docker

Overview

This tutorial guides you through setting up Cesivi Server with: - Authentication: Accept All (no authentication required) - Storage: In-Memory (fast, ephemeral) - Search: TfIdf (Term Frequency-Inverse Document Frequency) - Platform: Docker

Use Case: Quick-start development environment in containers. Perfect for CI/CD pipelines, containerized development, and simple search testing.

Time Required: ~5 minutes


Prerequisites

  • Docker Desktop installed (Windows, Mac, or Linux)
  • Basic familiarity with Docker commands

Architecture

┌─────────────────────────────────────────────────────────────┐
│                      Docker Host                             │
│                                                              │
│  ┌──────────────────────────────────────────────────────┐   │
│  │              Cesivi Container                │   │
│  │                    :8080                              │   │
│  │  ┌──────────────┐  ┌──────────────┐  ┌────────────┐  │   │
│  │  │ Accept All   │  │  In-Memory   │  │   TfIdf    │  │   │
│  │  │ Auth         │  │   Storage    │  │  Search    │  │   │
│  │  │ (No Auth)    │  │  (RAM)       │  │  Engine    │  │   │
│  │  └──────────────┘  └──────────────┘  └────────────┘  │   │
│  └──────────────────────────────────────────────────────┘   │
│                              │                               │
└──────────────────────────────┼───────────────────────────────┘
                               │
                        Host: localhost:8080

TfIdf Search: Lightweight statistical search algorithm. Good for: - Simple keyword matching - Basic relevance ranking - Low memory footprint - No external dependencies


Quick Start (Single Command!)

# Run Cesivi with all defaults
docker run -d \
  --name cesivi \
  -p 8080:8080 \
  -e Cesivi__StorageProvider=InMemory \
  -e Cesivi__SearchEngine=TfIdf \
  -e Cesivi__Authentication__AcceptAllCredentials=true \
  ghcr.io/your-org/cesivi:latest

# Or build from source
cd /path/to/Cesivi2
docker build -t cesivi .
docker run -d --name cesivi -p 8080:8080 cesivi

Step 1: Create Project Directory

mkdir -p ~/cesivi-tutorial-e
cd ~/cesivi-tutorial-e

Step 2: Create Configuration File

Create appsettings.json:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Cesivi": "Debug"
    },
    "Console": {
      "FormatterName": "json",
      "FormatterOptions": {
        "SingleLine": true
      }
    }
  },
  "Cesivi": {
    "HostName": "localhost",
    "UseHttps": false,
    "HttpPort": 8080,

    "StorageProvider": "InMemory",
    "SearchEngine": "TfIdf",

    "Identity": {
      "Providers": {
        "AcceptAll": {
          "Enabled": true,
          "Priority": 1,
          "DefaultUsername": "DOCKER\\developer",
          "DefaultEmail": "developer@docker.local",
          "DefaultDisplayName": "Docker Developer"
        }
      }
    },

    "Authentication": {
      "AcceptAllCredentials": true,
      "AllowAnonymous": true,
      "EnableNTLM": false,
      "EnableJWT": false,
      "EnableBasic": false
    },

    "Search": {
      "TfIdf": {
        "MaxResults": 500,
        "MinScore": 0.01,
        "EnableStemming": true,
        "StopWords": ["the", "a", "an", "is", "are", "was", "were", "be", "been", "being"]
      }
    }
  }
}

Step 3: Create Docker Compose File

Create docker-compose.yml:

version: '3.8'

services:
  cesivi:
    build:
      context: ../../  # Path to Cesivi2 root
      dockerfile: Dockerfile
    image: cesivi:tutorial-e
    container_name: cesivi-e
    environment:
      - ASPNETCORE_ENVIRONMENT=Docker
      - ASPNETCORE_URLS=http://+:8080
      - Cesivi__StorageProvider=InMemory
      - Cesivi__SearchEngine=TfIdf
      - Cesivi__Authentication__AcceptAllCredentials=true
      - Cesivi__Authentication__AllowAnonymous=true
    volumes:
      - ./appsettings.json:/app/appsettings.Docker.json:ro
    ports:
      - "8080:8080"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/_vti_bin/health"]
      interval: 10s
      timeout: 5s
      retries: 3
      start_period: 10s
    restart: unless-stopped
    deploy:
      resources:
        limits:
          memory: 512M
        reservations:
          memory: 256M

Step 4: Start the Container

Using Docker Compose

docker-compose up -d

# View logs
docker-compose logs -f

Using Docker Run (Alternative)

# Build image
cd /path/to/Cesivi2
docker build -t cesivi .

# Run container
docker run -d \
  --name cesivi-e \
  -p 8080:8080 \
  -e Cesivi__StorageProvider=InMemory \
  -e Cesivi__SearchEngine=TfIdf \
  -e Cesivi__Authentication__AcceptAllCredentials=true \
  cesivi

Step 5: Verify the Server is Running

# Check container status
docker ps | grep cesivi

# Check health
curl http://localhost:8080/_vti_bin/health

# Get web info (no auth needed!)
curl http://localhost:8080/_api/web \
  -H "Accept: application/json;odata=verbose"

Step 6: Test REST API

Get Site Information

# Get site
curl -s http://localhost:8080/_api/site \
  -H "Accept: application/json;odata=verbose" | jq '.d.Url'

# Get web
curl -s http://localhost:8080/_api/web \
  -H "Accept: application/json;odata=verbose" | jq '.d.Title'

Create a List

# Create a custom list
curl -X POST http://localhost:8080/_api/web/lists \
  -H "Accept: application/json;odata=verbose" \
  -H "Content-Type: application/json;odata=verbose" \
  -d '{
    "__metadata": { "type": "SP.List" },
    "Title": "Docker Test List",
    "BaseTemplate": 100
  }'
# Add items with searchable content
for i in {1..5}; do
  curl -X POST "http://localhost:8080/_api/web/lists/getbytitle('Docker Test List')/items" \
    -H "Accept: application/json;odata=verbose" \
    -H "Content-Type: application/json;odata=verbose" \
    -d "{
      \"__metadata\": { \"type\": \"SP.Data.Docker_x0020_Test_x0020_ListListItem\" },
      \"Title\": \"Test Item $i with searchable content docker container\"
    }"
done

# Search for "docker"
curl -s "http://localhost:8080/_api/search/query?querytext='docker'" \
  -H "Accept: application/json;odata=verbose" | jq '.d.query.PrimaryQueryResult.RelevantResults.TotalRows'

Search with Options

# Search with row limit
curl -s "http://localhost:8080/_api/search/query?querytext='container'&rowlimit=3" \
  -H "Accept: application/json;odata=verbose"

Step 8: Use in CI/CD Pipeline

GitHub Actions Example

name: SharePoint Integration Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest

    services:
      cesivi:
        image: ghcr.io/your-org/cesivi:latest
        ports:
          - 8080:8080
        env:
          Cesivi__StorageProvider: InMemory
          Cesivi__SearchEngine: TfIdf
          Cesivi__Authentication__AcceptAllCredentials: true
        options: >-
          --health-cmd "curl -f http://localhost:8080/_vti_bin/health"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 3

    steps:
      - uses: actions/checkout@v4

      - name: Wait for Cesivi
        run: |
          timeout 60 bash -c 'until curl -sf http://localhost:8080/_vti_bin/health; do sleep 2; done'

      - name: Run integration tests
        run: |
          npm test
        env:
          SHAREPOINT_URL: http://localhost:8080

GitLab CI Example

integration-tests:
  image: node:18
  services:
    - name: cesivi:latest
      alias: sharepoint
  variables:
    SHAREPOINT_URL: http://sharepoint:8080
    Cesivi__StorageProvider: InMemory
    Cesivi__SearchEngine: TfIdf
  script:
    - npm install
    - npm test

Step 9: Test with JavaScript/Node.js

Create test.js:

const fetch = require('node-fetch');

async function testCesivi() {
    const baseUrl = 'http://localhost:8080';
    const headers = { 'Accept': 'application/json;odata=verbose' };

    // Get web
    const web = await fetch(`${baseUrl}/_api/web`, { headers });
    const webData = await web.json();
    console.log('Web Title:', webData.d.Title);

    // Create list
    const createRes = await fetch(`${baseUrl}/_api/web/lists`, {
        method: 'POST',
        headers: {
            ...headers,
            'Content-Type': 'application/json;odata=verbose'
        },
        body: JSON.stringify({
            __metadata: { type: 'SP.List' },
            Title: 'Node Test List',
            BaseTemplate: 100
        })
    });
    const list = await createRes.json();
    console.log('Created list:', list.d.Title);

    // Search
    const searchRes = await fetch(`${baseUrl}/_api/search/query?querytext='test'`, { headers });
    const searchData = await searchRes.json();
    console.log('Search results:', searchData.d.query.PrimaryQueryResult.RelevantResults.TotalRows);
}

testCesivi().catch(console.error);

Run:

node test.js


Step 10: Monitor Container

# View logs
docker logs -f cesivi-e

# Check resource usage
docker stats cesivi-e

# Execute commands inside container
docker exec -it cesivi-e /bin/bash

TfIdf vs Lucene Comparison

Feature TfIdf Lucene
Memory Usage Low Medium-High
Dependencies None External files
Setup Complexity Simple Moderate
Phrase Search No Yes
Fuzzy Search No Yes
Wildcard Search Limited Full
Performance Good for small data Excellent for all sizes
Best For Simple keyword search Full-text search

Choose TfIdf when: - Simple keyword matching is sufficient - Memory is constrained - No external dependencies wanted - Quick setup needed

Choose Lucene when: - Advanced search features needed - Large document corpus - Complex queries required


Troubleshooting

"Container won't start"

# Check logs
docker logs cesivi-e

# Check port conflicts
lsof -i :8080
netstat -tlnp | grep 8080

"Connection refused"

# Verify container is running
docker ps

# Check health
docker inspect cesivi-e | jq '.[0].State.Health'

# Wait for health
timeout 60 bash -c 'until curl -sf http://localhost:8080/_vti_bin/health; do sleep 2; done'

"Search returns 0 results"

Cause: TfIdf index not yet populated or search term not matching

Solution: 1. Add items first, then search 2. Check exact spelling (TfIdf is case-insensitive but exact match) 3. Try broader search terms


Clean Up

# Stop and remove container
docker-compose down

# Or with docker run
docker stop cesivi-e
docker rm cesivi-e

# Remove image
docker rmi cesivi:tutorial-e

# Clean up directory
rm -rf ~/cesivi-tutorial-e

Summary

You have successfully set up: - Accept All authentication for zero-config access - In-Memory storage for ephemeral data - TfIdf search engine for lightweight search - Docker deployment for portability

Key Characteristics

Feature Value
Container Port 8080
Authentication None (Accept All)
Storage In-Memory
Search Engine TfIdf
Data Persistence None
Memory Limit 512MB

Quick Commands

# Start
docker-compose up -d

# Stop
docker-compose down

# Logs
docker-compose logs -f

# Health check
curl http://localhost:8080/_vti_bin/health

Next Steps


See Also