Flexible Docker Compose / Podman Compose deployment for SAM that allows you to bring your own infrastructure (broker, database, storage) or use fully managed services.
- Prerequisites
- Quick Start
- Architecture
- How It Works
- Deployment Profiles
- Operations
- Accessing SAM
- Troubleshooting
- File Structure
- Requirements
- Configuration Reference
- Security Considerations
- Examples
SAM container images require authentication. Choose one of the following options:
-
Download the image pull secret from Solace Cloud:
- Follow the instructions at: Download Image Pull Secret
- You'll receive a Kubernetes secret YAML file (e.g.,
gcr-reg-secret.yaml)
-
Configure your container engine with the credentials:
For Docker:
# Backup existing Docker config cp ~/.docker/config.json ~/.docker/config.json.backup # Extract and merge the Solace credentials grep '\.dockerconfigjson:' gcr-reg-secret.yaml | awk '{print $2}' | base64 -d > /tmp/solace-creds.json jq -s '.[0] * .[1]' ~/.docker/config.json /tmp/solace-creds.json > ~/.docker/config.json.new mv ~/.docker/config.json.new ~/.docker/config.json rm /tmp/solace-creds.json
For Podman:
# Podman uses the same config format, just in a different location mkdir -p ${XDG_RUNTIME_DIR}/containers cp ${XDG_RUNTIME_DIR}/containers/auth.json ${XDG_RUNTIME_DIR}/containers/auth.json.backup 2>/dev/null || true # Extract and merge the Solace credentials grep '\.dockerconfigjson:' gcr-reg-secret.yaml | awk '{print $2}' | base64 -d > /tmp/solace-creds.json # If auth.json exists, merge; otherwise, just copy if [ -f "${XDG_RUNTIME_DIR}/containers/auth.json" ]; then jq -s '.[0] * .[1]' ${XDG_RUNTIME_DIR}/containers/auth.json /tmp/solace-creds.json > /tmp/auth.json.new mv /tmp/auth.json.new ${XDG_RUNTIME_DIR}/containers/auth.json else mv /tmp/solace-creds.json ${XDG_RUNTIME_DIR}/containers/auth.json fi rm -f /tmp/solace-creds.json
If you've copied SAM images to your own registry:
-
Authenticate with your registry:
# For Docker: docker login your-registry.example.com # For Podman: podman login your-registry.example.com # Or for specific registries: docker login gcr.io/your-project # or: podman login gcr.io/your-project docker login ghcr.io # or: podman login ghcr.io
-
Update image references in
.env:SAM_IMAGE=your-registry.example.com/sam:latest SAM_DEPLOYER_IMAGE=your-registry.example.com/sam-deployer:latest
Note: Docker/Podman Compose doesn't support per-service pull secrets. All authentication is handled at the container engine level:
- Docker:
~/.docker/config.json - Podman:
${XDG_RUNTIME_DIR}/containers/auth.json(typically/run/user/<uid>/containers/auth.json)
Run the setup wizard to configure your deployment:
./setup.shThe wizard will:
- Ask about your deployment mode (Full Managed / BYO Everything / Custom)
- Collect required LLM API credentials
- Generate
.envfile with appropriate defaults - Create convenience scripts (
start.sh,stop.sh,logs.sh) - Show you the exact command to start SAM
If you prefer to configure manually:
# 1. Copy template
cp .env.template .env
# 2. Edit configuration (at minimum, set SAM_LLM_API_KEY)
nano .env
# 3. Deploy based on your needs:
# BYO Everything (Minimal)
docker compose -f compose.yml up -d
# Or with Podman: podman compose -f compose.yml up -d
# Full Managed Stack (Local Development)
docker compose -f compose.yml -f compose.broker.yml -f compose.database.yml -f compose.storage.yml up -d
# Mix and Match (example: managed broker + database only)
docker compose -f compose.yml -f compose.broker.yml -f compose.database.yml up -dSAM consists of:
- SAM Application - Web UI (port 8000) and orchestration engine
- Deployer Service - Dynamic agent deployment via container-in-container (Docker-in-Docker or Podman-in-Podman)
- Solace Broker - Event mesh for agent communication (managed or external)
- PostgreSQL - Session and metadata storage (managed or external)
- S3 Storage - Artifact storage via SeaweedFS or external S3 (managed or external)
Each component can be managed (deployed by compose) or external (bring your own).
The deployment uses compose file stacking - you combine multiple compose files to build your deployment:
compose.yml- Base file with SAM only, assumes BYO everythingcompose.broker.yml- Add managed Solace PubSub+ brokercompose.database.yml- Add managed PostgreSQLcompose.storage.yml- Add managed S3 storage (SeaweedFS)
Stack them together using multiple -f flags:
docker compose -f compose.yml -f compose.broker.yml -f compose.database.yml up -d
# Or with Podman:
podman compose -f compose.yml -f compose.broker.yml -f compose.database.yml up -dBenefits:
- ✅ No templating tools required - pure compose
- ✅ Services are only included when needed
- ✅ Easy to understand and debug
- ✅ Standard compose approach
- ✅ Works with both Docker and Podman
# .env configuration
EXTERNAL_BROKER_URL=tcp://broker.example.com:55555
EXTERNAL_BROKER_URL_WS=ws://broker.example.com:8008
EXTERNAL_BROKER_USERNAME=sam-user
EXTERNAL_BROKER_PASSWORD=your-password
EXTERNAL_BROKER_VPN=default
# Deploy (use docker compose or podman compose)
docker compose -f compose.yml up -d# .env configuration
EXTERNAL_WEB_UI_DATABASE_URL=postgresql+psycopg2://user:pass@host:5432/sam_webui
EXTERNAL_ORCHESTRATOR_DATABASE_URL=postgresql+psycopg2://user:pass@host:5432/sam_orchestrator
# Deploy (use docker compose or podman compose)
docker compose -f compose.yml up -d# .env configuration
EXTERNAL_S3_ENDPOINT_URL=https://s3.amazonaws.com
EXTERNAL_S3_BUCKET_NAME=my-sam-artifacts
EXTERNAL_S3_REGION=us-east-1
EXTERNAL_S3_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
EXTERNAL_S3_SECRET_ACCESS_KEY=your-secret-key
# Deploy (use docker compose or podman compose)
docker compose -f compose.yml up -dTo use managed services, simply add the appropriate compose file:
# Managed broker (use docker compose or podman compose)
docker compose -f compose.yml -f compose.broker.yml up -d
# Managed broker + database
docker compose -f compose.yml -f compose.broker.yml -f compose.database.yml up -d
# Full managed stack
docker compose -f compose.yml -f compose.broker.yml -f compose.database.yml -f compose.storage.yml up -dNote: All commands below work with both docker compose and podman compose. Simply replace docker compose with podman compose if using Podman.
# Minimal - BYO everything
docker compose -f compose.yml up -d
# With managed services (example: broker + database)
docker compose -f compose.yml -f compose.broker.yml -f compose.database.yml up -ddocker compose -f compose.yml logs -f sam
# Or all services
docker compose -f compose.yml -f compose.broker.yml logs -fdocker compose -f compose.yml ps# Stop but keep data
docker compose -f compose.yml -f compose.broker.yml down
# Stop and remove all data
docker compose -f compose.yml -f compose.broker.yml down -vSAM's deployer creates agent containers outside of compose:
# For Docker:
docker ps -a -q --filter "name=agent-" | xargs -r docker rm -f
rm -f ~/.sam-deployer/agent-*
# For Podman:
podman ps -a -q --filter "name=agent-" | xargs -r podman rm -f
rm -f ~/.sam-deployer/agent-*# 1. Stop SAM
docker compose -f compose.yml down
# 2. Edit configuration
nano .env
# 3. Restart SAM
docker compose -f compose.yml up -dOnce started:
- Web UI: http://localhost:8000
# Check logs
docker compose -f compose.yml logs sam
# Check container engine
docker info # For Docker
podman info # For Podman# Test broker
nc -zv broker.example.com 55555
# Test database
psql "postgresql://user:pass@host:5432/dbname"
# Test S3
curl -v https://s3.amazonaws.comSee what services will be deployed:
docker compose -f compose.yml -f compose.broker.yml config --servicesSee full merged configuration:
docker compose -f compose.yml -f compose.broker.yml configIf port 8000 is already in use, you can modify the port mappings in the compose files.
customer-compose/
├── compose.yml # Base: SAM only (BYO everything)
├── compose.broker.yml # Add-on: Managed broker
├── compose.database.yml # Add-on: Managed database
├── compose.storage.yml # Add-on: Managed storage
├── setup.sh # Interactive setup wizard
├── .env.template # Configuration template
├── .env # Your configuration (created by setup.sh)
├── .gitignore # Git ignore rules
└── README.md # This file
Generated by setup.sh:
├── start.sh # Convenience script to start SAM
├── stop.sh # Convenience script to stop SAM
└── logs.sh # Convenience script to view logs
- Container Engine (choose one):
- Docker 20.10+ with Docker Compose v2.0+
- Podman 4.0+ with Podman Compose
- LLM API (OpenAI, Anthropic, or compatible endpoint)
SAM supports both Docker and Podman. The setup script will automatically detect which one is available.
If using Podman, you may need to set these environment variables in your .env file:
CONTAINER_ENGINE=podman
CONTAINER_SOCKET=${XDG_RUNTIME_DIR}/podman/podman.sockThe setup script handles this automatically, but if configuring manually, uncomment these lines in .env.template.
See .env file for all available configuration options. Key sections:
- Image Configuration: SAM container image tags
- LLM Configuration: Required for all deployments
- External Services: Connection details for BYO infrastructure
- Managed Services: Configuration for managed components
- Never commit
.envwith real credentials - Use secrets management for production (Docker secrets, Vault)
- Change default passwords before deploying
- Use HTTPS for external endpoints
- Restrict network access with firewalls/security groups
# Full managed stack for local development
# (Works with both docker compose and podman compose)
docker compose \
-f compose.yml \
-f compose.broker.yml \
-f compose.database.yml \
-f compose.storage.yml \
up -d# Configure .env with production credentials
# Deploy SAM only (use docker compose or podman compose)
docker compose -f compose.yml up -d# Use managed broker for simplicity, but production database and S3
# (Use docker compose or podman compose)
docker compose -f compose.yml -f compose.broker.yml up -d