This document provides comprehensive guidance for running iHub Apps in Docker containers for both development and production environments.
The fastest way to try iHub Apps — no .env file, no pre-configuration required:
docker compose -f docker-compose.quickstart.yml upThen open http://localhost:3000 and navigate to Admin → Configuration to add your LLM API keys via the browser UI.
This uses the pre-built image from the registry and mounts a local ./contents/ folder so your configuration persists between restarts. Nothing else is needed to get started.
Images are published to two registries:
| Registry | Image |
|---|---|
| GitHub Container Registry | ghcr.io/intrafind/ihub-apps:latest |
| Docker Hub | intrafind/ihub-apps:latest |
# Pull from GHCR
docker pull ghcr.io/intrafind/ihub-apps:latest
# Pull from Docker Hub
docker pull intrafind/ihub-apps:latestThe Docker development setup automatically uses your local contents/ folder - no additional configuration needed!
-
Copy environment file:
cp .env.example .env # Edit .env with your API keys and configuration -
Start development with automatic local contents:
npm run docker:up
This automatically:
- ✅ Mounts your entire local
contents/folder into the container - ✅ Any changes to files in
contents/appear immediately in the container - ✅ No rebuilding or restarting required for content changes
- ✅ Edit configs, apps, models, pages directly on your machine
- ✅ Mounts your entire local
-
Access the application:
- Main app: http://localhost:3000 (Node.js server + static files)
- Vite dev server: http://localhost:5173 (Hot reload development server)
In development, both the Node.js server and Vite dev server run simultaneously for the best development experience.
Volume Strategy:
- Local contents: Your entire
contents/folder is mounted read-write - Persistent data:
contents/data/,contents/uploads/, and logs use Docker volumes for persistence - Best of both: Edit configs locally, keep runtime data persistent
-
Prepare production environment:
cp .env.production .env.production # Configure with production secrets (use secrets management in real deployment) -
Build and start production:
npm run docker:build:prod npm run docker:prod:up
-
Access the production application:
- Main app: http://localhost:3000 (Node.js server with built client)
In production, the Node.js server serves the pre-built client files directly.
# Build development image locally
npm run docker:build:dev
# Build production image locally
npm run docker:build:prod
# Build and start development environment
npm run docker:up:build# Development build
docker build -f docker/Dockerfile -t ihub-apps:dev --target development .
# Production build
docker build -f docker/Dockerfile -t ihub-apps:prod --target production .
# Multi-platform build (requires Docker Buildx)
docker buildx build -f docker/Dockerfile --platform linux/amd64,linux/arm64 -t ihub-apps:multi .The Docker build process uses multi-stage builds:
- Base Stage: Sets up Node.js environment and creates non-root user
- Dependencies Stage: Installs npm dependencies with caching
- Development Stage: Includes dev dependencies and source code mounting
- Production Stage: Optimized build with only production dependencies
# Build with custom arguments
docker build -f docker/Dockerfile \
--build-arg BUILDTIME="$(date -u +'%Y-%m-%dT%H:%M:%SZ')" \
--build-arg VERSION="1.0.0" \
--build-arg REVISION="$(git rev-parse HEAD)" \
-t ihub-apps:custom .# Test development build
docker run --rm -p 3000:3000 -p 5173:5173 \
-v $(pwd)/contents:/app/contents \
-e JWT_SECRET=test-secret \
ihub-apps:dev
# Test production build (serves built client + API on port 3000)
docker run --rm -p 3000:3000 \
-v $(pwd)/contents:/app/contents \
-e JWT_SECRET=test-secret \
-e NODE_ENV=production \
ihub-apps:prod
# Check image details
docker image inspect ihub-apps:prodExpected behavior:
- Development: Both Node.js server (3000) and Vite dev server (5173) should start
- Production: Only Node.js server (3000) should start, serving the built client files
### Development Workflow
```bash
# Start development environment
npm run docker:up
# Start with rebuilding images
npm run docker:up:build
# View logs
npm run docker:logs
# Access container shell
npm run docker:shell
# Stop development environment
npm run docker:down
# Stop and remove volumes
npm run docker:down:volumes
# Start production environment
npm run docker:prod:up
# View production logs
npm run docker:prod:logs
# Access production container shell
npm run docker:prod:shell
# Stop production environment
npm run docker:prod:downDocker images are automatically built and published to both GitHub Container Registry (ghcr.io) and Docker Hub in the following scenarios:
- On Release Creation: When you create a GitHub release
- On Version Tags: When you push a tag starting with
v(e.g.,v1.0.0) - Manual Trigger: Comment
@build docker imageson any issue or PR - Manual Workflow: Use GitHub Actions "Run workflow" button
To manually trigger a Docker build, comment on any GitHub issue or pull request:
@build docker images
This will automatically start the CI/CD pipeline and publish new images to the registry.
Images are published to both GitHub Container Registry (GHCR) and Docker Hub:
GitHub Container Registry:
ghcr.io/intrafind/ihub-apps:latest
ghcr.io/intrafind/ihub-apps:v1.0.0
ghcr.io/intrafind/ihub-apps:main
Docker Hub:
intrafind/ihub-apps:latest
intrafind/ihub-apps:v1.0.0
# Quickstart — zero-config, configure via admin UI after startup
docker compose -f docker-compose.quickstart.yml up
# Run directly with Docker (GHCR)
# Note: JWT_SECRET is optional - auto-generated if not provided
docker run -p 3000:3000 \
-v $(pwd)/contents:/app/contents \
ghcr.io/intrafind/ihub-apps:latest
# Run directly with Docker (Docker Hub)
docker run -p 3000:3000 \
-v $(pwd)/contents:/app/contents \
intrafind/ihub-apps:latest
# Use specific version with custom JWT secret
docker run -p 3000:3000 \
-v $(pwd)/contents:/app/contents \
-e JWT_SECRET=your-secret \
ghcr.io/intrafind/ihub-apps:v1.0.0# Clean up unused Docker resources
npm run docker:clean
# Clean up everything (be careful!)
npm run docker:clean:all
# Run tests in container
npm run docker:test- Source Code: Bind mounted for hot reloading
- Configuration: Bind mounted for easy editing
- Data: Docker volumes for persistence
- Node Modules: Cached volumes for performance
- Contents: Single named volume (
ihub-contents) mounted read-write at/app/contents— config, apps, models, prompts, locales, pages, sources, data, and uploads all live here. Seeded from the image's bundled defaults on first boot when empty (sameperformInitialSetuplogic as the quickstart/dev setups), and written to at runtime by config migrations and admin-UI saves. - Logs: Separate persistent volume (
ihub-logs) for application logs
# LLM API Keys (at least one required for AI functionality)
OPENAI_API_KEY=your-openai-key
ANTHROPIC_API_KEY=your-anthropic-key
GOOGLE_API_KEY=your-google-key
MISTRAL_API_KEY=your-mistral-key# Security Configuration
# JWT_SECRET: Auto-generated and persisted if not set
# Only required for multi-node deployments to share the same secret
JWT_SECRET=your-secure-jwt-secret
# Admin Configuration
ADMIN_SECRET=your-admin-secret# Enable PostgreSQL service
docker-compose --profile database up -d
# Environment variables
DB_HOST=ihub-db
DB_NAME=ihub
DB_USER=ihub
DB_PASSWORD=your-db-password# Enable Redis service
docker-compose --profile cache up -d
# Environment variables
REDIS_HOST=ihub-redis
REDIS_PASSWORD=your-redis-password# Enable Nginx for development
docker-compose --profile nginx up -d
# Access via proxy
http://localhost:8080- Non-root user: Containers run as UID 1000
- Read-only filesystem: Root filesystem is read-only
- No privileged access: Containers drop all capabilities
- Resource limits: CPU and memory limits enforced
- Volume encryption: Use encrypted volumes in production
- Secret management: Never store secrets in images
- Network isolation: Use Docker networks for service isolation
- Regular updates: Keep base images updated
- Use secrets management system (not .env files)
- Enable HTTPS with valid certificates
- Configure proper CORS settings
- Enable rate limiting and security headers
- Use read-only volumes where possible
- Implement proper backup strategy
- Monitor and log security events
- Bridge network:
ihub-network - Port mappings: 3000 (app), 5173 (vite), 5432 (postgres), 6379 (redis)
- Service discovery: Containers communicate by service name
- Isolated network:
ihub-prod-network - External access: Only through reverse proxy
- Internal communication: Services communicate privately
- Load balancing: Multiple app replicas supported
- Application:
http://localhost:3000/api/health - Container: Built-in Docker health checks
- Dependencies: PostgreSQL and Redis health checks
# View all logs
docker-compose logs -f
# View specific service logs
docker-compose logs -f ihub-dev
# Production logs with rotation
docker-compose -f docker-compose.prod.yml logs -f- Prometheus metrics: Available at
/api/metrics - Container metrics: Docker stats and cAdvisor
- Custom dashboards: Grafana configurations available
# Backup the whole contents/ volume (config, apps, models, prompts, data, uploads, ...)
docker run --rm -v ihub-contents:/data -v $(pwd)/backups:/backup alpine tar czf /backup/contents-$(date +%Y%m%d).tar.gz -C /data .
# Backup database (if using PostgreSQL)
docker-compose exec ihub-db pg_dump -U ihub ihub > backup-$(date +%Y%m%d).sql# 1. Stop current application
npm run server:stop
# 2. Backup current contents (optional, belt-and-suspenders)
cp -r contents contents.backup
# 3. Create the Docker volume
docker volume create ihub-contents
# 4. Copy contents/ into the volume
docker run --rm -v $(pwd)/contents:/source -v ihub-contents:/dest alpine cp -r /source/* /dest/
# 5. Start Docker environment
npm run docker:up# Check logs
docker-compose logs ihub-dev
# Check if required environment variables are set
docker-compose config
# Verify image exists
docker images | grep ihub-apps# Fix volume permissions
docker-compose exec ihub-dev chown -R ihub:nodejs /app/contents /app/logs
# Check user inside container
docker-compose exec ihub-dev id# Check what's using the port
lsof -i :3000
# Use different ports
AI_HUB_PORT=3001 docker-compose up -d# List volumes
docker volume ls
# Inspect volume
docker volume inspect ihub-data
# Check mount points
docker-compose exec ihub-dev df -h# Use BuildKit for faster builds
DOCKER_BUILDKIT=1 docker build -t ihub-apps:latest .
# Use multi-stage caching
docker build --target production --cache-from ihub-apps:latest -t ihub-apps:latest .# Adjust resource limits in docker-compose.yml
deploy:
resources:
limits:
cpus: '2.0'
memory: 2GThe repository includes a comprehensive GitHub Actions workflow that:
- Builds multi-platform Docker images
- Runs security scans with Trivy
- Publishes to GitHub Container Registry
- Supports automated deployments
# Tag and push to GHCR
docker tag ihub-apps:latest ghcr.io/intrafind/ihub-apps:latest
docker push ghcr.io/intrafind/ihub-apps:latest
# Tag and push to Docker Hub
docker tag ihub-apps:latest intrafind/ihub-apps:latest
docker push intrafind/ihub-apps:latest
# Pull from either registry
docker pull ghcr.io/intrafind/ihub-apps:latest
docker pull intrafind/ihub-apps:latestFor customized deployments, you can extend the base Dockerfile:
FROM ghcr.io/intrafind/ihub-apps:latest
# Add custom certificates
COPY custom-ca.crt /usr/local/share/ca-certificates/
RUN update-ca-certificates
# Add custom configuration
COPY custom-config/ /app/contents/config/
USER ihubFor Kubernetes deployments, see the concepts/docker-support/ directory for comprehensive Kubernetes manifests and Helm charts.
# Initialize swarm
docker swarm init
# Deploy stack
docker stack deploy -c docker-compose.prod.yml ihub-apps
# Scale services
docker service scale ihub-apps_ihub-app=3- Documentation: See
docs/directory for comprehensive guides - Examples: Check
examples/for sample configurations - Issues: Report Docker-related issues on GitHub
- Security: Follow security best practices in production
For more detailed information, refer to the specifications in concepts/docker-support/.