All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
- Add OpenBao services to docker-compose.yml with profiles (openbao, full) - Add docker-compose.build.yml for local builds vs registry pulls - Make PostgreSQL and Valkey optional via profiles (database, cache) - Create example compose files for common deployment scenarios: - docker/docker-compose.example.turnkey.yml (all bundled) - docker/docker-compose.example.external.yml (all external) - docker/docker.example.hybrid.yml (mixed deployment) - Update documentation: - Enhance .env.example with profiles and external service examples - Update README.md with deployment mode quick starts - Add deployment scenarios to docs/OPENBAO.md - Create docker/DOCKER-COMPOSE-GUIDE.md with comprehensive guide - Clean up repository structure: - Move shell scripts to scripts/ directory - Move documentation to docs/ directory - Move docker compose examples to docker/ directory - Configure for external Authentik with internal services: - Comment out Authentik services (using external OIDC) - Comment out unused volumes for disabled services - Keep postgres, valkey, openbao as internal services This provides a flexible deployment architecture supporting turnkey, production (all external), and hybrid configurations via Docker Compose profiles. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
147 lines
4.6 KiB
Bash
Executable File
147 lines
4.6 KiB
Bash
Executable File
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
# Mosaic Stack - Docker Swarm Deployment Script
|
|
# Usage: ./deploy-swarm.sh [stack-name]
|
|
|
|
STACK_NAME="${1:-mosaic}"
|
|
COMPOSE_FILE="docker-compose.swarm.yml"
|
|
IMAGE_TAG="${IMAGE_TAG:-latest}"
|
|
|
|
echo "🚀 Deploying Mosaic Stack to Docker Swarm..."
|
|
echo "Stack name: $STACK_NAME"
|
|
echo "Compose file: $COMPOSE_FILE"
|
|
echo "Image tag: $IMAGE_TAG"
|
|
echo ""
|
|
|
|
# Check if .env exists
|
|
if [ ! -f .env ]; then
|
|
echo "❌ Error: .env file not found"
|
|
echo "📝 Run the setup wizard to create it:"
|
|
echo " ./setup-wizard.sh"
|
|
echo ""
|
|
echo "Or copy from example:"
|
|
echo " cp .env.example .env"
|
|
echo " nano .env"
|
|
exit 1
|
|
fi
|
|
|
|
# Check required environment variables
|
|
echo "🔍 Checking required environment variables..."
|
|
missing_vars=()
|
|
|
|
# Check critical variables
|
|
for var in POSTGRES_PASSWORD JWT_SECRET OIDC_CLIENT_ID OIDC_CLIENT_SECRET ENCRYPTION_KEY BETTER_AUTH_SECRET; do
|
|
if ! grep -q "^${var}=" .env || grep -q "^${var}=.*REPLACE" .env || [ -z "$(grep "^${var}=" .env | cut -d= -f2)" ]; then
|
|
missing_vars+=("$var")
|
|
fi
|
|
done
|
|
|
|
# Check AI provider configuration
|
|
AI_PROVIDER=$(grep "^AI_PROVIDER=" .env 2>/dev/null | cut -d= -f2 || echo "ollama")
|
|
|
|
if [ "$AI_PROVIDER" = "claude" ]; then
|
|
if ! grep -q "^CLAUDE_API_KEY=" .env || grep -q "^CLAUDE_API_KEY=.*REPLACE" .env; then
|
|
missing_vars+=("CLAUDE_API_KEY (required when AI_PROVIDER=claude)")
|
|
fi
|
|
elif [ "$AI_PROVIDER" = "openai" ]; then
|
|
if ! grep -q "^OPENAI_API_KEY=" .env || grep -q "^OPENAI_API_KEY=.*REPLACE" .env; then
|
|
missing_vars+=("OPENAI_API_KEY (required when AI_PROVIDER=openai)")
|
|
fi
|
|
fi
|
|
|
|
if [ ${#missing_vars[@]} -gt 0 ]; then
|
|
echo "❌ Missing or placeholder values for:"
|
|
printf " - %s\n" "${missing_vars[@]}"
|
|
echo ""
|
|
echo "Run the setup wizard to configure:"
|
|
echo " ./setup-wizard.sh"
|
|
echo ""
|
|
echo "Or manually edit .env"
|
|
exit 1
|
|
fi
|
|
|
|
echo "✅ All required variables configured"
|
|
echo " AI Provider: $AI_PROVIDER"
|
|
echo ""
|
|
|
|
# Check if traefik-public network exists
|
|
if ! docker network ls --filter name=traefik-public --format '{{.Name}}' | grep -q '^traefik-public$'; then
|
|
echo "⚠️ traefik-public network not found. Creating it..."
|
|
docker network create --driver=overlay traefik-public
|
|
echo "✅ traefik-public network created"
|
|
else
|
|
echo "✅ traefik-public network already exists"
|
|
fi
|
|
|
|
# Check if using registry images or local images
|
|
echo ""
|
|
REGISTRY="git.mosaicstack.dev"
|
|
USE_REGISTRY=true
|
|
|
|
# If IMAGE_TAG is set to "local", use local images
|
|
if [ "$IMAGE_TAG" = "local" ]; then
|
|
USE_REGISTRY=false
|
|
echo "🔍 Using local images (IMAGE_TAG=local)"
|
|
IMAGES_MISSING=0
|
|
for img in stack-postgres stack-openbao stack-api stack-orchestrator stack-web; do
|
|
if ! docker images --format "{{.Repository}}" | grep -q "^${img}$"; then
|
|
echo " ⚠️ Missing: $img"
|
|
IMAGES_MISSING=1
|
|
fi
|
|
done
|
|
|
|
if [ $IMAGES_MISSING -eq 1 ]; then
|
|
echo ""
|
|
echo "❌ Some local images are missing. Build them first:"
|
|
echo " ./build-images.sh"
|
|
echo ""
|
|
read -p "Build images now? [Y/n]: " BUILD_NOW
|
|
BUILD_NOW=${BUILD_NOW:-Y}
|
|
if [[ $BUILD_NOW =~ ^[Yy]$ ]]; then
|
|
./build-images.sh || exit 1
|
|
else
|
|
echo "Aborting deployment. Build images first."
|
|
exit 1
|
|
fi
|
|
else
|
|
echo "✅ All local images are built"
|
|
fi
|
|
else
|
|
echo "🔍 Using registry images from $REGISTRY"
|
|
echo " Tag: $IMAGE_TAG"
|
|
echo ""
|
|
echo " Images will be pulled from:"
|
|
echo " - $REGISTRY/mosaic/stack-postgres:$IMAGE_TAG"
|
|
echo " - $REGISTRY/mosaic/stack-openbao:$IMAGE_TAG"
|
|
echo " - $REGISTRY/mosaic/stack-api:$IMAGE_TAG"
|
|
echo " - $REGISTRY/mosaic/stack-orchestrator:$IMAGE_TAG"
|
|
echo " - $REGISTRY/mosaic/stack-web:$IMAGE_TAG"
|
|
echo ""
|
|
echo " Note: Ensure you're logged in to the registry:"
|
|
echo " docker login $REGISTRY"
|
|
fi
|
|
|
|
# Deploy the stack
|
|
echo ""
|
|
echo "📦 Deploying stack..."
|
|
IMAGE_TAG=$IMAGE_TAG docker stack deploy -c $COMPOSE_FILE --with-registry-auth $STACK_NAME
|
|
|
|
echo ""
|
|
echo "✅ Stack deployed successfully!"
|
|
echo ""
|
|
echo "📊 Stack status:"
|
|
docker stack ps $STACK_NAME --format "table {{.Name}}\t{{.CurrentState}}\t{{.Error}}"
|
|
|
|
echo ""
|
|
echo "🔍 To check stack services:"
|
|
echo " docker stack services $STACK_NAME"
|
|
echo ""
|
|
echo "🔍 To check stack logs:"
|
|
echo " docker service logs ${STACK_NAME}_api"
|
|
echo " docker service logs ${STACK_NAME}_web"
|
|
echo " docker service logs ${STACK_NAME}_postgres"
|
|
echo ""
|
|
echo "🗑️ To remove the stack:"
|
|
echo " docker stack rm $STACK_NAME"
|