Docker Deployment Guide#
This guide covers building, testing, and deploying the SousChef UI as a Docker container.
Overview#
The SousChef project includes a production-ready Dockerfile for containerising the Streamlit UI. The Docker image is:
- Secure: Runs as non-root user, minimal dependencies, security scanning
- Robust: Multi-stage build, health checks, proper signal handling
- Efficient: Optimised for caching, supports multiple architectures (amd64, arm64)
- Observable: Comprehensive logging, health checks, metadata labels
Quick Start#
Prerequisites#
- Docker 20.10+ or Docker Desktop
- Docker Compose 2.0+ (for local development)
- Make (for convenience commands)
Building the Image Locally#
# Build the image with all supported tags
make docker-build
# Or directly with Docker
docker build -t ghcr.io/mcp-souschef:latest .
Running Locally#
# Start with docker-compose (recommended for development)
make docker-run
# Access the UI at: http://localhost:9999
# View logs
make docker-logs
# Stop the container
make docker-stop
Published Images on GitHub Container Registry (GHCR)#
The SousChef project automatically publishes Docker images to GitHub Container Registry on each release.
Finding the Image#
- Direct URL: https://ghcr.io/mcp-souschef
- GitHub Package Page: https://github.com/kpeacocke/souschef/pkgs/container/mcp-souschef
- Command Line:
What's Displayed on GHCR#
The image metadata includes:
- Title: "SousChef - MCP AI Migration Platform"
- Description: "AI-powered Model Context Protocol server and web UI for migrating automation assets to Ansible"
- License: MIT
- Vendor: SousChef Project
- Documentation: https://kpeacocke.github.io/souschef/
- Source: https://github.com/kpeacocke/souschef
Available Tags#
latest- Most recent release3.2.0- Specific version (semver)3.2- Latest patch of minor version3- Latest patch of major version
Pulling and Running Images#
# Pull latest release
docker pull ghcr.io/mcp-souschef:latest
# Pull specific version
docker pull ghcr.io/mcp-souschef:3.2.0
# Run with environment configuration
docker run -p 9999:9999 \
--env-file .env \
ghcr.io/mcp-souschef:latest
# Check image details
docker inspect ghcr.io/mcp-souschef:latest
Image Architecture#
Multi-Stage Build#
The Dockerfile uses three build stages for optimal efficiency:
- Base Stage (
base) - Python slim image with security updates
- System dependencies (curl, git, ca-certificates)
- Non-root user creation
-
OCI metadata labels
-
Builder Stage (
builder) - Build dependencies (gcc, python3-dev)
- Poetry installation and configuration
- Dependency compilation and installation
-
Discarded in final image (keeps image small)
-
Production Stage (
production) - Minimal base image
- Pre-compiled dependencies from builder
- Application code
- Security hardening (read-only filesystem, reduced tmpfs)
Image Size Optimisation#
- Uses
python:3.14-sliminstead of full image (~40MB vs 900MB) - Multi-stage build discards build dependencies
- Aggressive apt cleanup (
rm -rf /var/lib/apt/lists/*) - Layer caching for faster rebuilds
Building for Production#
Automated Publishing (GitHub Actions)#
The repository includes automated Docker publishing via GitHub Actions:
Triggers:
- Tags matching v[0-9]+.[0-9]+.[0-9]+ (releases)
- Pushes to main branch (tags with latest)
- Manual workflow dispatch for testing
Features: - Multi-platform builds (amd64, arm64) - Automatic tagging (version-based) - Push to GitHub Container Registry (GHCR) - Vulnerability scanning with Trivy - SBOM generation - Image testing
Manual Publishing#
# Login to registry (GHCR)
docker login ghcr.io
# Build for multiple platforms
docker buildx build \
--platform linux/amd64,linux/arm64 \
-t ghcr.io/mcp-souschef:v1.0.0 \
--push .
Configuration#
Environment Variables#
Standard Streamlit environment variables can be set via:
.envfile in project rootdocker run -e VARIABLE=VALUEdocker-compose.ymlenvironment section
Key variables:
# Streamlit Configuration
STREAMLIT_SERVER_PORT=9999 # UI port
STREAMLIT_SERVER_HEADLESS=true # No browser auto-open
STREAMLIT_BROWSER_GATHER_USAGE_STATS=false # Disable telemetry
STREAMLIT_SERVER_ENABLE_CORS=true # Enable CORS
STREAMLIT_SERVER_ENABLE_XSRF_PROTECTION=true # Enable XSRF protection
PYTHONUNBUFFERED=1 # Immediate log output
# AI Configuration (for automatic AI model setup)
SOUSCHEF_AI_PROVIDER=Anthropic (Claude) # AI provider
SOUSCHEF_AI_MODEL=claude-3-5-sonnet-20241022 # AI model
SOUSCHEF_AI_API_KEY=your-api-key-here # API key for provider
SOUSCHEF_AI_BASE_URL= # Optional: Custom API endpoint
SOUSCHEF_AI_PROJECT_ID= # For IBM Watsonx
SOUSCHEF_AI_TEMPERATURE=0.7 # Model temperature
SOUSCHEF_AI_MAX_TOKENS=4000 # Max response tokens
# Chef Server Configuration (for dynamic inventory queries)
CHEF_SERVER_URL=https://chef.example.com # Chef Server URL
CHEF_ORG=default # Chef organisation name
CHEF_CLIENT_NAME=my-client # Chef client/user name
CHEF_CLIENT_KEY_PATH=/path/to/client.pem # Chef client key path (PEM)
Docker Compose Configuration#
The docker-compose.yml file provides:
services:
souschef-ui:
# Security options
security_opt:
- no-new-privileges:true # Prevent escalation
read_only: true # Read-only filesystem
tmpfs: # Temporary filesystems with restrictions
- /tmp:noexec,nosuid
- /run:noexec,nosuid
# Resource limits
deploy:
resources:
limits:
memory: 1G
cpus: 0.5
# Health monitoring
healthcheck:
test: python -m souschef.ui.health_check
interval: 30s
timeout: 10s
retries: 3
Persistent Storage Configuration#
The Docker Compose setup uses configurable bind mounts for persistent storage. All storage paths can be customised via environment variables in the .env file:
# Docker Compose Volume Configuration
# Configure persistent storage paths (relative or absolute paths)
SOUSCHEF_DATA_DIR=./data/souschef # SQLite database and analysis history
SOUSCHEF_STORAGE_DIR=./data/storage # Generated artefacts and conversions
POSTGRES_DATA_DIR=./data/postgres # PostgreSQL database files
MINIO_DATA_DIR=./data/minio # MinIO object storage data
Storage Overview:
| Volume | Default Path | Purpose | Container Mount Point |
|---|---|---|---|
souschef-data |
./data/souschef |
SQLite database, analysis results, conversion history | /tmp/.souschef/data |
souschef-storage |
./data/storage |
Generated playbooks, templates, artefacts (fallback) | /tmp/.souschef/storage |
postgres-data |
./data/postgres |
PostgreSQL database files | /var/lib/postgresql/data |
minio-data |
./data/minio |
MinIO object storage buckets | /data |
Key Features:
- Configurable Paths: All storage directories can be customised via
.env - Automatic Creation: Directories are created automatically on first run
- Persistent Data: Data survives container restarts and recreations
- Flexible Location: Use relative paths (e.g.,
./data) or absolute paths (e.g.,/mnt/storage) - Backup Friendly: Host-mounted directories are easy to backup and migrate
Example Configurations:
-
Default (Relative Paths):
-
Absolute Paths:
-
Network Storage:
Important Notes:
- Ensure the directories are writable by the container users (UIDs: 1000 for souschef-ui, 999 for postgres, root for minio)
- The
data/directory is automatically ignored by Git (added to.gitignore) - For production deployments, consider using dedicated volumes or network storage
- Back up these directories regularly, especially
postgres-dataandsouschef-data
Deployment#
Kubernetes#
Example deployment manifest:
apiVersion: apps/v1
kind: Deployment
metadata:
name: souschef-ui
spec:
replicas: 2
selector:
matchLabels:
app: souschef-ui
template:
metadata:
labels:
app: souschef-ui
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1001
containers:
- name: souschef-ui
image: ghcr.io/mcp-souschef:v1.0.0
ports:
- containerPort: 9999
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "1Gi"
cpu: "500m"
livenessProbe:
httpGet:
path: /healthz
port: 9999
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /healthz
port: 9999
initialDelaySeconds: 5
periodSeconds: 5
Docker Swarm#
# Pull image from registry
docker pull ghcr.io/mcp-souschef:v1.0.0
# Create service
docker service create \
--name souschef-ui \
--publish 9999:9999 \
--limit-memory 1G \
--limit-cpus 0.5 \
ghcr.io/mcp-souschef:v1.0.0
Plain Docker#
# Pull image
docker pull ghcr.io/mcp-souschef:v1.0.0
# Run container
docker run -d \
--name souschef-ui \
-p 9999:9999 \
--memory 1g \
--cpus 0.5 \
--restart unless-stopped \
-e STREAMLIT_SERVER_HEADLESS=true \
ghcr.io/mcp-souschef:v1.0.0
Testing#
Local Testing#
# Build and test image
make docker-test
# Manually test with docker run
docker run --rm \
-p 9999:9999 \
ghcr.io/mcp-souschef:latest
# Test health check
docker run --rm \
ghcr.io/mcp-souschef:latest \
python -m souschef.ui.health_check
Security Scanning#
# Scan with Trivy (requires Trivy installation)
make docker-scan
# Or manually
trivy image ghcr.io/mcp-souschef:latest
Troubleshooting#
Container won't start#
# Check logs
docker logs <container_id>
# Run with verbose logging
docker run -e STREAMLIT_LOGGER_LEVEL=debug ghcr.io/mcp-souschef:latest
Permission denied errors#
Ensure the container runs with proper permissions:
# Check running user
docker exec <container_id> whoami
# Should output: app
# Check file permissions
docker exec <container_id> ls -la /app
Health check failing#
# Test health check manually
docker run --rm \
ghcr.io/mcp-souschef:latest \
python -m souschef.ui.health_check
# Expected output:
# {"status": "healthy", "service": "souschef-ui", "version": "X.Y.Z"}
Memory/CPU issues#
Adjust resource limits in docker-compose.yml or deployment:
deploy:
resources:
limits:
memory: 2G # Increase from 1G
cpus: '1' # Increase from 0.5
reservations:
memory: 512M # Increase from 256M
cpus: '0.5' # Increase from 0.25
Best Practices#
-
Always use version tags
-
Run as non-root user
-
Use health checks
- Configured in image and compose
- Validates application readiness
-
Enables orchestration decisions
-
Set resource limits
- Prevents resource exhaustion
- Improves orchestration efficiency
-
See docker-compose.yml for examples
-
Monitor logs
-
Use read-only filesystem
- Configured in docker-compose.yml
- Reduces attack surface
- tmpfs used for temporary data
Image Metadata#
The image includes comprehensive OCI metadata:
org.opencontainers.image.title=SousChef UI
org.opencontainers.image.description=AI-powered UI for multi-platform to Ansible migration
org.opencontainers.image.authors=SousChef Contributors
org.opencontainers.image.licenses=MIT
org.opencontainers.image.url=https://github.com/kpeacocke/souschef
org.opencontainers.image.documentation=https://kpeacocke.github.io/souschef/
org.opencontainers.image.source=https://github.com/kpeacocke/souschef
View metadata:
Registry Information#
GitHub Container Registry (GHCR)#
- Registry:
ghcr.io - Image:
ghcr.io/mcp-souschef - Documentation: https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry
- Authentication: GitHub token or personal access token