This document provides instructions for deploying the MCP Context Engine using Docker.
The project uses a single Dockerfile that builds both Go and Node.js services in a multi-stage build. Docker Compose orchestrates all services with profile-based configuration.
# Start backend + database
docker-compose up
# Start with MCP server
docker-compose --profile with-mcp up
# Start with Slack bot
docker-compose --profile with-slack up
# Full stack
docker-compose --profile with-mcp --profile with-slack up
# With Redis cache
docker-compose --profile with-cache up# Build images
docker-compose build
# Start all services
docker-compose -f docker-compose.yml up -d
# Or with profiles
docker-compose --profile with-mcp --profile with-slack up -dThe Dockerfile uses multi-stage builds:
- go-builder: Builds Go backend binary
- node-builder: Builds TypeScript/Node.js services
- production: Final minimal Alpine image with both runtimes
- postgres: PostgreSQL 15 database
- redis: Redis cache (optional, use
--profile with-cache) - backend: Go API server (port 8080)
- mcp-server: MCP server (port 3001, use
--profile with-mcp) - slack-bot: Slack bot (port 3002, use
--profile with-slack)
Create a .env file in the project root:
# Database
POSTGRES_PASSWORD=your-secure-password
# GitHub OAuth
GITHUB_CLIENT_ID=your-github-client-id
GITHUB_CLIENT_SECRET=your-github-client-secret
GITHUB_REDIRECT_URL=http://localhost:8080/api/auth/github
# Google OAuth
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
# Slack
SLACK_CLIENT_ID=your-slack-client-id
SLACK_CLIENT_SECRET=your-slack-client-secret
SLACK_SIGNING_SECRET=your-slack-signing-secret
SLACK_REDIRECT_URL=http://localhost:8080/api/auth/slack
# AI Service
AI_SERVICE_URL=http://ai-service:8000
# CORS
ALLOWED_ORIGINS=http://localhost:3000,http://localhost:8080For production, use Docker secrets:
# Create secret files
echo "your-postgres-password" > secrets/postgres_password.txt
echo "your-jwt-secret" > secrets/jwt_secret.txt
echo "your-github-client-id" > secrets/github_client_id.txt
echo "your-github-client-secret" > secrets/github_client_secret.txt
echo "your-google-client-secret" > secrets/google_client_secret.txt
echo "your-slack-client-secret" > secrets/slack_client_secret.txt
echo "your-slack-signing-secret" > secrets/slack_signing_secret.txt
# Set proper permissions
chmod 600 secrets/*.txtThe docker-compose.override.yml file is automatically loaded in development and provides:
- Source code mounting for hot reload
- Debug logging
- Simple passwords (no secrets)
- Open CORS
# Backend with hot reload (requires air or similar)
docker-compose up
# Node services with hot reload
docker-compose --profile with-mcp up# Build all images
docker-compose build
# Build specific service
docker-compose build backend
# Build with no cache
docker-compose build --no-cache# Start all services
docker-compose -f docker-compose.yml up -d
# Check status
docker-compose ps
# View logs
docker-compose logs -f backend
# Stop services
docker-compose downAll services include health checks:
# Check backend health
curl http://localhost:8080/health
# Check MCP server health
curl http://localhost:3001/health
# Check Slack bot health
curl http://localhost:3002/healthUse profiles to control which services run:
- default: postgres + backend
- with-mcp: Add MCP server
- with-slack: Add Slack bot
- with-cache: Add Redis cache
# Multiple profiles
docker-compose \
--profile with-mcp \
--profile with-slack \
--profile with-cache \
up -dPersistent data is stored in Docker volumes:
postgres_data: Database dataredis_data: Cache databackend_logs: Backend logsmcp_logs: MCP server logsslack_logs: Slack bot logs
# List volumes
docker volume ls
# Inspect volume
docker volume inspect mcp-context-engine_postgres_data
# Backup volume
docker run --rm -v mcp-context-engine_postgres_data:/data -v $(pwd):/backup alpine tar czf /backup/postgres-backup.tar.gz /data
# Restore volume
docker run --rm -v mcp-context-engine_postgres_data:/data -v $(pwd):/backup alpine tar xzf /backup/postgres-backup.tar.gz -C /All services communicate via the mcp-network bridge network:
# Inspect network
docker network inspect mcp-context-engine_mcp-network
# Service DNS names:
# - postgres
# - redis
# - backend
# - mcp-server
# - slack-bot# Check logs
docker-compose logs backend
# Check container status
docker-compose ps
# Restart service
docker-compose restart backend# Check postgres is running
docker-compose ps postgres
# Check postgres logs
docker-compose logs postgres
# Connect to postgres
docker-compose exec postgres psql -U contextkeeper -d contextkeeper# Clean build
docker-compose down -v
docker-compose build --no-cache
docker-compose up# Check what's using the port
lsof -i :8080
# Change port in docker-compose.yml
ports:
- "8081:8080" # Map to different host portAdd resource limits in production:
services:
backend:
deploy:
resources:
limits:
cpus: '1.0'
memory: 1G
reservations:
cpus: '0.5'
memory: 512M# Real-time stats
docker stats
# Specific service
docker stats mcp-backend# Follow all logs
docker-compose logs -f
# Specific service
docker-compose logs -f backend
# Last 100 lines
docker-compose logs --tail=100 backend# Stop and remove containers
docker-compose down
# Remove volumes too
docker-compose down -v
# Remove images
docker-compose down --rmi all
# Full cleanup
docker system prune -a --volumesname: Docker Build
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build images
run: docker-compose build
- name: Run tests
run: docker-compose run backend go test ./...
- name: Push to registry
run: |
docker tag mcp-backend:latest registry.example.com/mcp-backend:latest
docker push registry.example.com/mcp-backend:latest- Use secrets for sensitive data in production
- Set resource limits to prevent resource exhaustion
- Enable health checks for all services
- Use volumes for persistent data
- Implement logging with proper log rotation
- Monitor container metrics and logs
- Backup volumes regularly
- Update base images regularly for security patches