- Remove Rollup bundling in favor of direct TypeScript compilation - Move from bundled models to dynamic model loading with configurable paths - Add Docker deployment examples and documentation - Implement robust model loader with fallback mechanisms - Update storage adapters for better cross-environment compatibility - Add comprehensive tests for model loading and package installation - Simplify package.json scripts and remove complex build configurations - Clean up deprecated demo files and old bundling scripts BREAKING CHANGE: Models are no longer bundled with the package. They are now loaded dynamically from CDN or custom paths.
235 lines
No EOL
5.6 KiB
Markdown
235 lines
No EOL
5.6 KiB
Markdown
# Docker Deployment for Brainy
|
|
|
|
This guide shows how to deploy Brainy applications with embedded models in Docker containers, avoiding the need to download models at runtime.
|
|
|
|
## Problem
|
|
|
|
When deploying Node.js applications to Docker containers, `node_modules` is often ignored in `.dockerignore` to reduce image size. However, this means the `@soulcraft/brainy-models` package (containing pre-trained models) won't be included in the container, forcing runtime model downloads from the internet.
|
|
|
|
## Solution
|
|
|
|
Brainy now supports loading models from custom directories using:
|
|
|
|
1. **Environment variable**: `BRAINY_MODELS_PATH` or `MODELS_PATH`
|
|
2. **Configuration option**: `customModelsPath` in `RobustModelLoader`
|
|
|
|
## Deployment Strategies
|
|
|
|
### Strategy 1: Embed Models in Docker Image (Recommended)
|
|
|
|
This approach copies models from `node_modules` to a custom location during the Docker build process.
|
|
|
|
```dockerfile
|
|
# Multi-stage build to extract models
|
|
FROM node:24-alpine AS builder
|
|
WORKDIR /app
|
|
COPY package*.json ./
|
|
RUN npm ci --only=production
|
|
COPY . .
|
|
|
|
# Extract models from node_modules
|
|
RUN mkdir -p /app/models && \
|
|
if [ -d "./node_modules/@soulcraft/brainy-models" ]; then \
|
|
cp -r ./node_modules/@soulcraft/brainy-models/models/* /app/models/; \
|
|
fi
|
|
|
|
# Production stage
|
|
FROM node:24-alpine AS production
|
|
WORKDIR /app
|
|
COPY package*.json ./
|
|
RUN npm ci --only=production --omit=optional
|
|
COPY . .
|
|
COPY --from=builder /app/models /app/models
|
|
|
|
# Set environment variable
|
|
ENV BRAINY_MODELS_PATH=/app/models
|
|
|
|
CMD ["node", "dist/your-app.js"]
|
|
```
|
|
|
|
### Strategy 2: Mount Models as Volume
|
|
|
|
Mount pre-downloaded models as a Docker volume:
|
|
|
|
```yaml
|
|
services:
|
|
brainy-app:
|
|
image: your-brainy-app
|
|
environment:
|
|
- BRAINY_MODELS_PATH=/models
|
|
volumes:
|
|
- ./models:/models:ro
|
|
```
|
|
|
|
### Strategy 3: Init Container Pattern
|
|
|
|
Use an init container to download models before starting your application:
|
|
|
|
```yaml
|
|
services:
|
|
model-downloader:
|
|
image: node:24-alpine
|
|
volumes:
|
|
- brainy-models:/models
|
|
command: |
|
|
sh -c "
|
|
npm install @soulcraft/brainy-models
|
|
cp -r node_modules/@soulcraft/brainy-models/models/* /models/
|
|
"
|
|
|
|
brainy-app:
|
|
image: your-brainy-app
|
|
environment:
|
|
- BRAINY_MODELS_PATH=/models
|
|
volumes:
|
|
- brainy-models:/models:ro
|
|
depends_on:
|
|
- model-downloader
|
|
|
|
volumes:
|
|
brainy-models:
|
|
```
|
|
|
|
## Configuration Options
|
|
|
|
### Environment Variables
|
|
|
|
```bash
|
|
# Primary environment variable
|
|
BRAINY_MODELS_PATH=/app/models
|
|
|
|
# Alternative variable name
|
|
MODELS_PATH=/app/models
|
|
```
|
|
|
|
### Programmatic Configuration
|
|
|
|
```javascript
|
|
import { BrainyData, RobustModelLoader } from '@soulcraft/brainy'
|
|
|
|
// Option 1: Configure via RobustModelLoader
|
|
const loader = new RobustModelLoader({
|
|
customModelsPath: '/app/models'
|
|
})
|
|
|
|
// Option 2: Environment variable (automatic)
|
|
// Just set BRAINY_MODELS_PATH and it will be used automatically
|
|
```
|
|
|
|
## Model Directory Structure
|
|
|
|
Brainy will search for models in the following subdirectories (in order):
|
|
|
|
```
|
|
/app/models/
|
|
├── universal-sentence-encoder/ # Direct path
|
|
├── models/universal-sentence-encoder/ # @soulcraft/brainy-models structure
|
|
├── tfhub/universal-sentence-encoder/ # TensorFlow Hub structure
|
|
├── use/ # Short name
|
|
└── model.json # Root directory
|
|
```
|
|
|
|
## Cloud Run Deployment
|
|
|
|
For Google Cloud Run, use the embedded models strategy:
|
|
|
|
```dockerfile
|
|
FROM node:24-alpine
|
|
WORKDIR /app
|
|
COPY package*.json ./
|
|
RUN npm ci --only=production
|
|
COPY . .
|
|
|
|
# Copy models during build
|
|
RUN if [ -d "./node_modules/@soulcraft/brainy-models" ]; then \
|
|
mkdir -p /app/models && \
|
|
cp -r ./node_modules/@soulcraft/brainy-models/models/* /app/models/; \
|
|
fi
|
|
|
|
ENV BRAINY_MODELS_PATH=/app/models
|
|
ENV PORT=8080
|
|
EXPOSE 8080
|
|
|
|
CMD ["node", "dist/server.js"]
|
|
```
|
|
|
|
Deploy with:
|
|
|
|
```bash
|
|
gcloud run deploy brainy-app \
|
|
--source . \
|
|
--platform managed \
|
|
--region us-central1 \
|
|
--allow-unauthenticated \
|
|
--memory 2Gi \
|
|
--cpu 1
|
|
```
|
|
|
|
## AWS Lambda/ECS Deployment
|
|
|
|
Similar approach works for AWS services:
|
|
|
|
```dockerfile
|
|
FROM public.ecr.aws/lambda/nodejs:24
|
|
|
|
# Copy models during build
|
|
COPY package*.json ./
|
|
RUN npm ci --only=production
|
|
COPY . .
|
|
RUN mkdir -p /var/task/models && \
|
|
cp -r ./node_modules/@soulcraft/brainy-models/models/* /var/task/models/
|
|
|
|
ENV BRAINY_MODELS_PATH=/var/task/models
|
|
|
|
CMD ["index.handler"]
|
|
```
|
|
|
|
## Verification
|
|
|
|
Your application logs should show:
|
|
|
|
```
|
|
✅ Found model at custom path: /app/models/universal-sentence-encoder/model.json
|
|
✅ Successfully loaded model from custom directory
|
|
Using custom model path for Docker/production deployment
|
|
```
|
|
|
|
Instead of:
|
|
|
|
```
|
|
⚠️ Local model not found. Falling back to remote model loading.
|
|
```
|
|
|
|
## Benefits
|
|
|
|
1. **Faster startup**: No model download time
|
|
2. **Offline deployment**: Works without internet access
|
|
3. **Predictable performance**: No network dependency
|
|
4. **Smaller runtime image**: Can exclude dev dependencies
|
|
5. **Security**: No external network calls required
|
|
|
|
## Troubleshooting
|
|
|
|
### Models not found
|
|
|
|
1. Check the environment variable is set: `echo $BRAINY_MODELS_PATH`
|
|
2. Verify models directory exists: `ls -la /app/models`
|
|
3. Check model structure: `find /app/models -name "model.json"`
|
|
|
|
### Memory issues
|
|
|
|
Models require approximately 500MB of RAM. Ensure your container has sufficient memory:
|
|
|
|
```yaml
|
|
deploy:
|
|
resources:
|
|
limits:
|
|
memory: 2G
|
|
```
|
|
|
|
### Build failures
|
|
|
|
If `@soulcraft/brainy-models` is not available during build:
|
|
1. Ensure it's in `dependencies`, not `devDependencies`
|
|
2. Use `npm ci --only=production` instead of `npm install`
|
|
3. Check the package is properly published and accessible |