# Docker Deployment Guide Brainy provides **zero-configuration Docker deployment** with automatic model embedding. Deploy to any cloud provider with fast startup times and no runtime model downloads. ## Quick Start **1. Install models package:** ```bash npm install @soulcraft/brainy-models ``` **2. Add to Dockerfile:** ```dockerfile RUN npm run extract-models # ← Automatic model extraction COPY --from=builder /app/models ./models # ← Include models in image ``` **3. Deploy anywhere:** ```bash gcloud run deploy --source . # Google Cloud aws ecs create-service ... # AWS az container create ... # Azure ``` **That's it!** No configuration, environment variables, or custom setup needed. ## How It Works ### Build Time 1. `npm run extract-models` automatically finds `@soulcraft/brainy-models` 2. Extracts models to `./models` directory 3. Creates marker file for runtime detection 4. Models are embedded in Docker image ### Runtime 1. Brainy auto-detects extracted models in `./models` 2. Loads models locally without network calls 3. **7x faster startup** compared to downloading models 4. Works offline and in restricted networks ### Priority Order Brainy uses this fallback hierarchy: 1. **Auto-extracted models** (`./models` directory) ← **Fastest** 2. `BRAINY_MODELS_PATH` environment variable 3. `@soulcraft/brainy-models` package 4. Remote URL download ← **Slowest** ## Universal Dockerfile Template ```dockerfile # Universal Brainy Dockerfile - Works on all cloud providers FROM node:24-alpine AS builder WORKDIR /app # Install dependencies including models COPY package*.json ./ RUN npm ci # Copy source and extract models COPY . . RUN npm run extract-models # ← Zero-config model extraction RUN npm run build # Production stage FROM node:24-alpine AS production WORKDIR /app # Install production dependencies only COPY package*.json ./ RUN npm ci --only=production --omit=optional && npm cache clean --force # Copy application and auto-extracted models COPY --from=builder /app/dist ./dist COPY --from=builder /app/models ./models # ← Models included automatically # Security: non-root user RUN addgroup -g 1001 -S nodejs && adduser -S brainy -u 1001 RUN chown -R brainy:nodejs /app USER brainy # Environment ENV NODE_ENV=production # Health check for all cloud providers HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ CMD node -e "console.log('Health check passed')" || exit 1 # Start application CMD ["node", "dist/server.js"] ``` ## Cloud Provider Examples ### Google Cloud Run ```dockerfile FROM node:24-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run extract-models RUN npm run build FROM node:24-alpine AS production WORKDIR /app COPY package*.json ./ RUN npm ci --only=production --omit=optional COPY --from=builder /app/dist ./dist COPY --from=builder /app/models ./models ENV PORT=8080 EXPOSE 8080 CMD ["node", "dist/server.js"] ``` Deploy: ```bash gcloud run deploy brainy-app \ --source . \ --platform managed \ --region us-central1 \ --memory 2Gi \ --cpu 1 ``` ### AWS Lambda ```dockerfile FROM public.ecr.aws/lambda/nodejs:24 COPY package*.json ./ RUN npm ci COPY . . RUN npm run extract-models CMD ["index.handler"] ``` Deploy: ```bash # Build and push to ECR docker build -t brainy-lambda . docker tag brainy-lambda:latest $ECR_URI:latest docker push $ECR_URI:latest # Create/update function aws lambda create-function \ --function-name brainy-function \ --package-type Image \ --code ImageUri=$ECR_URI:latest \ --timeout 60 \ --memory-size 2048 ``` ### AWS ECS/Fargate ```dockerfile FROM node:24-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run extract-models RUN npm run build FROM node:24-alpine AS production WORKDIR /app COPY package*.json ./ RUN npm ci --only=production --omit=optional COPY --from=builder /app/dist ./dist COPY --from=builder /app/models ./models ENV PORT=3000 EXPOSE 3000 CMD ["node", "dist/server.js"] ``` ECS Task Definition: ```json { "family": "brainy-task", "cpu": "1024", "memory": "2048", "requiresCompatibilities": ["FARGATE"], "networkMode": "awsvpc", "containerDefinitions": [{ "name": "brainy-container", "image": "your-ecr-repo/brainy:latest", "memory": 2048, "portMappings": [{"containerPort": 3000}], "logConfiguration": { "logDriver": "awslogs", "options": { "awslogs-group": "/ecs/brainy-task", "awslogs-region": "us-east-1", "awslogs-stream-prefix": "ecs" } } }] } ``` ### Azure Container Instances ```dockerfile FROM node:24-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run extract-models RUN npm run build FROM node:24-alpine AS production WORKDIR /app COPY package*.json ./ RUN npm ci --only=production --omit=optional COPY --from=builder /app/dist ./dist COPY --from=builder /app/models ./models ENV PORT=80 EXPOSE 80 CMD ["node", "dist/server.js"] ``` Deploy: ```bash # Build and push to Azure Container Registry az acr build --registry myregistry --image brainy:latest . # Deploy to Container Instances az container create \ --resource-group myResourceGroup \ --name brainy-container \ --image myregistry.azurecr.io/brainy:latest \ --cpu 1 \ --memory 2 \ --ports 80 \ --environment-variables NODE_ENV=production ``` ### Cloudflare Workers Due to size constraints, Cloudflare Workers use R2 storage: ```javascript // wrangler.toml [[r2_buckets]] binding = "BRAINY_MODELS_BUCKET" bucket_name = "brainy-models" // worker.js export default { async fetch(request, env) { const brainy = new BrainyData({ storageAdapter: new CloudflareR2Storage(env.BRAINY_MODELS_BUCKET), customModelsPath: 'r2://brainy-models/models' }) await brainy.init() // Your logic here } } ``` ## Performance Comparison | Deployment Method | Cold Start Time | Memory Usage | Network Calls | Reliability | |-------------------|----------------|--------------|---------------|-------------| | **Auto-extracted models** | ~2 seconds | +500MB | 0 | 99.9% | | **Environment variable** | ~2 seconds | +500MB | 0 | 99.9% | | **@soulcraft/brainy-models** | ~3 seconds | +500MB | 0 | 99.8% | | **Remote download** | ~15 seconds | +200MB | Multiple | 95% | ## Verification ### Success Messages (What You Want to See) ``` [Brainy Model Extractor] 🔍 Checking for @soulcraft/brainy-models... [Brainy Model Extractor] ✅ Found @soulcraft/brainy-models package [Brainy Model Extractor] 📦 Creating models directory... [Brainy Model Extractor] 📋 Copying models from: /app/node_modules/@soulcraft/brainy-models/models [Brainy Model Extractor] ✅ Models extracted successfully! [Brainy Model Extractor] 🎉 Model extraction completed successfully! ``` At runtime: ``` 🎯 Auto-detected extracted models at: /app/models ✅ Successfully loaded model from custom directory Using custom model path for Docker/production deployment ``` ### Fallback Messages (When Models Not Found) ``` ⚠️ Local model not found. Falling back to remote model loading. For best performance and reliability: 1. Install @soulcraft/brainy-models: npm install @soulcraft/brainy-models 2. Or set BRAINY_MODELS_PATH environment variable for Docker deployments 3. Or use customModelsPath option in RobustModelLoader ``` ## Troubleshooting ### Models Not Found **Symptoms:** - Warning: "Local model not found. Falling back to remote model loading" - Slow startup times (15+ seconds) - Network timeouts in restricted environments **Solutions:** 1. **Check package.json**: Ensure `@soulcraft/brainy-models` is in `dependencies` (not `devDependencies`) 2. **Check Dockerfile**: Verify `RUN npm run extract-models` is present 3. **Check Docker build**: Look for extraction success messages 4. **Inspect image**: `docker run -it your-image ls -la /app/models` ### Memory Issues **Symptoms:** - Container OOM (Out of Memory) kills - Slow performance - Failed deployments **Solutions:** - **Cloud Run**: `--memory 2Gi` - **Lambda**: `--memory-size 2048` - **ECS**: Set memory in task definition to 2048 - **Azure**: `--memory 2` ### Build Failures **Symptoms:** - `npm run extract-models` fails - "Cannot find module" errors - Build timeouts **Solutions:** 1. Use Node.js 24+ base image 2. Ensure sufficient disk space during build 3. Check that `@soulcraft/brainy-models` installs correctly 4. Verify npm scripts are present in package.json ### Environment Detection Issues **Symptoms:** - Models not auto-detected - Wrong storage adapter chosen **Debug commands:** ```bash # Check if models directory exists docker run -it your-image ls -la /app/models # Check marker file docker run -it your-image cat /app/models/.brainy-models-extracted # Test model loading docker run -it your-image node -e " import('./dist/unified.js').then(brainy => { const db = new brainy.BrainyData({skipEmbeddings: true}); console.log('Brainy loaded successfully'); }) " ``` ## Advanced Configuration ### Custom Models Path If you need to override the auto-detection: ```javascript const brainy = new BrainyData({ customModelsPath: '/custom/path/to/models' }) ``` Or use environment variable: ```dockerfile ENV BRAINY_MODELS_PATH=/custom/path/to/models ``` ### Multiple Model Versions Support multiple model versions in the same image: ```dockerfile # Extract different model versions RUN npm run extract-models RUN mkdir -p ./models/v1 ./models/v2 RUN cp -r ./models/universal-sentence-encoder ./models/v1/ # Copy v2 models to ./models/v2/ ``` ### Custom Extraction Script Create your own extraction logic: ```javascript // custom-extract.js import { extractModels } from './node_modules/@soulcraft/brainy/scripts/extract-models.js' // Custom extraction with additional processing await extractModels() // Add custom models or processing // ... ``` ## Security Considerations ### Best Practices 1. **Use non-root user**: Always run containers as non-root 2. **Minimal base image**: Use Alpine Linux for smaller attack surface 3. **No secrets in models**: Models are public, but ensure no credentials 4. **Read-only filesystem**: Mount models directory as read-only if possible ### Network Security - **No external calls**: Models load locally, reducing network exposure - **Offline capability**: Works in air-gapped environments - **Consistent versions**: No risk of model tampering during download ## CI/CD Integration ### GitHub Actions ```yaml name: Build and Deploy Brainy App on: push: branches: [main] jobs: build-and-deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Build Docker image run: | docker build -t brainy-app . # Models are automatically extracted during build - name: Deploy to Cloud Run run: | gcloud run deploy brainy-app \ --image brainy-app \ --platform managed \ --memory 2Gi ``` ### GitLab CI ```yaml stages: - build - deploy build: stage: build script: - docker build -t brainy-app . # Models extracted automatically deploy: stage: deploy script: - aws ecs update-service --service brainy-service ``` ## Multi-Stage Optimization ### Minimize Image Size ```dockerfile FROM node:24-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run extract-models RUN npm run build # Clean up unnecessary files RUN rm -rf node_modules/@soulcraft/brainy-models/docs \ node_modules/@soulcraft/brainy-models/examples \ node_modules/@soulcraft/brainy-models/.git* FROM node:24-alpine AS production WORKDIR /app COPY package*.json ./ RUN npm ci --only=production --omit=optional && npm cache clean --force COPY --from=builder /app/dist ./dist COPY --from=builder /app/models ./models # Only essential model files RUN addgroup -g 1001 -S nodejs && adduser -S brainy -u 1001 RUN chown -R brainy:nodejs /app USER brainy CMD ["node", "dist/server.js"] ``` ### Layer Caching Optimization ```dockerfile # Optimize for layer caching FROM node:24-alpine AS builder WORKDIR /app # Cache dependencies layer COPY package*.json ./ RUN npm ci # Cache extraction layer (only changes when models update) RUN npm run extract-models # Application layer (changes frequently) COPY . . RUN npm run build # Production optimizations... ``` This comprehensive guide covers everything needed for successful Docker deployments across all cloud providers while maintaining the zero-configuration approach!