diff --git a/build-images.sh b/build-images.sh new file mode 100755 index 0000000..ba56e85 --- /dev/null +++ b/build-images.sh @@ -0,0 +1,43 @@ +#!/bin/bash +set -euo pipefail + +# Mosaic Stack - Build Images for Swarm Deployment +# This script builds all Docker images needed for the stack + +echo "🔨 Building Mosaic Stack images for swarm deployment..." +echo "" + +# Build postgres with pgvector +echo "📦 Building postgres..." +docker build -t mosaic-stack-postgres:latest -f docker/postgres/Dockerfile docker/postgres/ + +# Build openbao +echo "📦 Building openbao..." +docker build -t mosaic-stack-openbao:latest -f docker/openbao/Dockerfile docker/openbao/ + +# Build API +echo "📦 Building API..." +docker build -t mosaic-stack-api:latest -f apps/api/Dockerfile . --build-arg NODE_ENV=production + +# Build orchestrator +echo "📦 Building orchestrator..." +docker build -t mosaic-stack-orchestrator:latest -f apps/orchestrator/Dockerfile . + +# Build web (using NEXT_PUBLIC_API_URL from .env if available) +echo "📦 Building web..." +if [ -f .env ]; then + NEXT_PUBLIC_API_URL=$(grep "^NEXT_PUBLIC_API_URL=" .env | cut -d= -f2 || echo "https://api.mosaicstack.dev") +else + NEXT_PUBLIC_API_URL="https://api.mosaicstack.dev" +fi +docker build -t mosaic-stack-web:latest -f apps/web/Dockerfile . --build-arg NEXT_PUBLIC_API_URL="$NEXT_PUBLIC_API_URL" + +echo "" +echo "✅ All images built successfully!" +echo "" +echo "Built images:" +docker images | grep mosaic-stack + +echo "" +echo "Next step:" +echo " Deploy to swarm: ./deploy-swarm.sh mosaic" diff --git a/deploy-swarm.sh b/deploy-swarm.sh index 8008a48..9e4e760 100755 --- a/deploy-swarm.sh +++ b/deploy-swarm.sh @@ -72,10 +72,33 @@ else echo "✅ traefik-public network already exists" fi -# Build images (optional - uncomment if you want to build before deploying) -# echo "" -# echo "🔨 Building images..." -# docker compose -f $COMPOSE_FILE build +# Check if images exist, offer to build if not +echo "" +echo "🔍 Checking if images are built..." +IMAGES_MISSING=0 +for img in mosaic-stack-postgres mosaic-stack-openbao mosaic-stack-api mosaic-stack-orchestrator mosaic-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 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 images are built" +fi # Deploy the stack echo "" diff --git a/docker-compose.swarm.yml b/docker-compose.swarm.yml index 3103cfa..0584043 100644 --- a/docker-compose.swarm.yml +++ b/docker-compose.swarm.yml @@ -3,9 +3,7 @@ services: # PostgreSQL Database # ====================== postgres: - build: - context: ./docker/postgres - dockerfile: Dockerfile + image: mosaic-stack-postgres:latest env_file: .env environment: POSTGRES_USER: ${POSTGRES_USER:-mosaic} @@ -58,9 +56,7 @@ services: # OpenBao Secrets Vault # ====================== openbao: - build: - context: ./docker/openbao - dockerfile: Dockerfile + image: mosaic-stack-openbao:latest env_file: .env environment: OPENBAO_ADDR: ${OPENBAO_ADDR:-http://0.0.0.0:8200} @@ -230,11 +226,6 @@ services: # ====================== api: image: mosaic-stack-api:latest - build: - context: . - dockerfile: ./apps/api/Dockerfile - args: - - NODE_ENV=production env_file: .env environment: NODE_ENV: production @@ -278,9 +269,6 @@ services: # ====================== orchestrator: image: mosaic-stack-orchestrator:latest - build: - context: . - dockerfile: ./apps/orchestrator/Dockerfile env_file: .env user: "1000:1000" environment: @@ -305,8 +293,8 @@ services: start_period: 40s networks: - internal - security_opt: - - no-new-privileges:true + # Note: security_opt not supported in swarm mode + # Security hardening done via cap_drop/cap_add cap_drop: - ALL cap_add: @@ -322,11 +310,6 @@ services: # ====================== web: image: mosaic-stack-web:latest - build: - context: . - dockerfile: ./apps/web/Dockerfile - args: - - NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL:-http://localhost:3001} env_file: .env environment: NODE_ENV: production