Installation¶
Interactive installer (recommended)¶
The interactive installer guides you through product selection, LLM provider configuration, and security setup.
You'll be prompted for:
- Which products to install — select by number or install all
- LLM provider — Claude (recommended), OpenAI, or Ollama (local/air-gapped)
- API key — for your chosen provider
- Rate limiting — requests per minute (default: 60)
- Max upload size — for document/invoice uploads (default: 50MB)
- Data retention — days before auto-deletion for GDPR (default: 365)
- Log level — DEBUG, INFO, WARNING, or ERROR
- Custom domain — for CORS if deploying behind a domain
Install a single product¶
Headless / scripted installation¶
For CI/CD or automated deployments:
bash deploy/scripts/install.sh \
--headless \
--products document-search,faq-chatbot,email-triage \
--provider claude \
--api-key sk-ant-your-key-here
Manual installation¶
If you prefer full control:
# 1. Clone
git clone https://github.com/haagsman-ai/products.git
cd products
# 2. Create configuration
cp .env.example .env
# Edit .env with your API keys and settings
nano .env
# 3. Build and start
docker compose build document-search
docker compose up -d document-search
# 4. Verify
curl http://localhost:8100/health
Air-gapped deployment (Ollama)¶
For environments without internet access:
# 1. On a machine with internet, pull the model
ollama pull llama3
# 2. Transfer to air-gapped machine (USB, internal network)
# 3. Install with Ollama provider
bash deploy/scripts/install.sh --provider ollama --model llama3
No data ever leaves your infrastructure with this configuration.
Verify installation¶
After installation, check that all products are healthy:
# Check individual product
curl http://localhost:8100/health
# Expected response:
# {"status":"healthy","product":"haagsman-document-search","version":"1.0.0","uptime_seconds":42,"checks":{}}
# Check all products
for port in 8100 8101 8102 8103 8104 8105 8106 8107; do
echo -n "Port $port: "
curl -s http://localhost:$port/health/live | jq -r '.status' 2>/dev/null || echo "not running"
done