diff --git a/deploy-swarm.sh b/deploy-swarm.sh new file mode 100755 index 00000000..6244ac90 --- /dev/null +++ b/deploy-swarm.sh @@ -0,0 +1,78 @@ +#!/bin/bash + +# Deploy Hive to Docker Swarm +# This script deploys the Hive distributed AI orchestration platform to the Docker Swarm + +set -e + +# Configuration +STACK_NAME="hive" +COMPOSE_FILE="docker-compose.swarm.yml" +DOMAIN="hive.home.deepblack.cloud" + +echo "🐝 Deploying Hive to Docker Swarm" +echo "==================================" + +# Check if we're on a swarm manager +if ! docker info --format '{{.Swarm.LocalNodeState}}' | grep -q "active"; then + echo "❌ This node is not part of a Docker Swarm or not a manager" + exit 1 +fi + +# Check if tengig network exists +if ! docker network ls | grep -q "tengig"; then + echo "❌ The 'tengig' network does not exist. Please create it first." + echo "Run: docker network create --driver overlay --attachable tengig" + exit 1 +fi + +# Build images first (if needed) +echo "🔨 Building Docker images..." +docker compose -f $COMPOSE_FILE build + +# Deploy to swarm +echo "🚀 Deploying stack to swarm..." +docker stack deploy -c $COMPOSE_FILE $STACK_NAME + +# Wait for services to be ready +echo "⏳ Waiting for services to be ready..." +sleep 30 + +# Check deployment status +echo "📊 Checking deployment status..." +docker stack services $STACK_NAME + +# Show service logs +echo "📋 Recent service logs:" +docker service logs ${STACK_NAME}_hive-backend --tail 20 +docker service logs ${STACK_NAME}_hive-frontend --tail 20 + +echo "" +echo "✅ Hive deployment completed!" +echo "🌐 Access your Hive cluster at: https://$DOMAIN" +echo "📊 Grafana dashboard: https://$DOMAIN/grafana" +echo "📈 Prometheus metrics: https://$DOMAIN/prometheus" +echo "" +echo "🔧 Useful commands:" +echo " docker stack services $STACK_NAME" +echo " docker stack ps $STACK_NAME" +echo " docker service logs ${STACK_NAME}_hive-backend" +echo " docker stack rm $STACK_NAME" +echo "" + +# DNS Configuration note +echo "📝 DNS Configuration:" +echo "Make sure $DOMAIN points to your swarm manager IP" +echo "Add this to your local DNS or hosts file if needed" +echo "" + +# Test connectivity +echo "🔍 Testing connectivity..." +if curl -s --connect-timeout 5 https://$DOMAIN > /dev/null; then + echo "✅ HTTPS connection successful" +else + echo "⚠️ HTTPS connection failed - check DNS and SSL certificates" + echo "💡 It may take a few minutes for SSL certificates to be provisioned" +fi + +echo "🎉 Deployment complete! The Hive cluster is now running on Docker Swarm." \ No newline at end of file diff --git a/docker-compose.swarm.yml b/docker-compose.swarm.yml new file mode 100644 index 00000000..0bf6d8e6 --- /dev/null +++ b/docker-compose.swarm.yml @@ -0,0 +1,209 @@ +services: + # Hive Backend API + hive-backend: + image: anthonyrawlins/hive-backend:latest + build: + context: ./backend + dockerfile: Dockerfile + environment: + - DATABASE_URL=postgresql://hive:hivepass@postgres:5432/hive + - REDIS_URL=redis://redis:6379 + - ENVIRONMENT=production + - LOG_LEVEL=info + - CORS_ORIGINS=https://hive.home.deepblack.cloud + depends_on: + - postgres + - redis + networks: + - hive-network + - tengig + deploy: + replicas: 2 + restart_policy: + condition: on-failure + delay: 5s + max_attempts: 3 + resources: + limits: + memory: 512M + reservations: + memory: 256M + labels: + - "traefik.enable=true" + - "traefik.http.routers.hive-api.rule=Host(`hive.home.deepblack.cloud`) && PathPrefix(`/api`)" + - "traefik.http.routers.hive-api.entrypoints=web-secured" + - "traefik.http.routers.hive-api.tls.certresolver=letsencryptresolver" + - "traefik.http.services.hive-api.loadbalancer.server.port=8000" + - "traefik.docker.network=tengig" + + # Hive Frontend + hive-frontend: + image: anthonyrawlins/hive-frontend:latest + build: + context: ./frontend + dockerfile: Dockerfile + environment: + - REACT_APP_API_URL=https://hive.home.deepblack.cloud/api + - REACT_APP_WS_URL=wss://hive.home.deepblack.cloud/ws + depends_on: + - hive-backend + networks: + - hive-network + - tengig + deploy: + replicas: 2 + restart_policy: + condition: on-failure + delay: 5s + max_attempts: 3 + resources: + limits: + memory: 256M + reservations: + memory: 128M + labels: + - "traefik.enable=true" + - "traefik.http.routers.hive.rule=Host(`hive.home.deepblack.cloud`)" + - "traefik.http.routers.hive.entrypoints=web-secured" + - "traefik.http.routers.hive.tls.certresolver=letsencryptresolver" + - "traefik.http.services.hive.loadbalancer.server.port=3000" + - "traefik.docker.network=tengig" + # HTTP redirect to HTTPS + - "traefik.http.routers.hive-web.rule=Host(`hive.home.deepblack.cloud`)" + - "traefik.http.routers.hive-web.entrypoints=web" + - "traefik.http.routers.hive-web.middlewares=redirect-to-https@docker" + + # PostgreSQL Database + postgres: + image: postgres:15 + environment: + - POSTGRES_DB=hive + - POSTGRES_USER=hive + - POSTGRES_PASSWORD=hivepass + - PGDATA=/var/lib/postgresql/data/pgdata + volumes: + - postgres_data:/var/lib/postgresql/data + networks: + - hive-network + deploy: + replicas: 1 + restart_policy: + condition: on-failure + delay: 10s + max_attempts: 3 + resources: + limits: + memory: 512M + reservations: + memory: 256M + placement: + constraints: + - node.role == manager + + # Redis Cache + redis: + image: redis:7-alpine + command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru + volumes: + - redis_data:/data + networks: + - hive-network + deploy: + replicas: 1 + restart_policy: + condition: on-failure + delay: 5s + max_attempts: 3 + resources: + limits: + memory: 256M + reservations: + memory: 128M + + # Prometheus Metrics + prometheus: + image: prom/prometheus:latest + command: + - '--config.file=/etc/prometheus/prometheus.yml' + - '--storage.tsdb.path=/prometheus' + - '--web.console.libraries=/etc/prometheus/console_libraries' + - '--web.console.templates=/etc/prometheus/consoles' + - '--storage.tsdb.retention.time=30d' + - '--web.enable-lifecycle' + volumes: + - prometheus_data:/prometheus + networks: + - hive-network + - tengig + deploy: + replicas: 1 + restart_policy: + condition: on-failure + delay: 10s + max_attempts: 3 + resources: + limits: + memory: 512M + reservations: + memory: 256M + placement: + constraints: + - node.role == manager + labels: + - "traefik.enable=true" + - "traefik.http.routers.hive-prometheus.rule=Host(`hive.home.deepblack.cloud`) && PathPrefix(`/prometheus`)" + - "traefik.http.routers.hive-prometheus.entrypoints=web-secured" + - "traefik.http.routers.hive-prometheus.tls.certresolver=letsencryptresolver" + - "traefik.http.services.hive-prometheus.loadbalancer.server.port=9090" + - "traefik.docker.network=tengig" + + # Grafana Dashboard + grafana: + image: grafana/grafana:latest + environment: + - GF_SECURITY_ADMIN_USER=admin + - GF_SECURITY_ADMIN_PASSWORD=hiveadmin + - GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-simple-json-datasource + - GF_SERVER_ROOT_URL=https://hive.home.deepblack.cloud/grafana + - GF_SERVER_SERVE_FROM_SUB_PATH=true + volumes: + - grafana_data:/var/lib/grafana + depends_on: + - prometheus + networks: + - hive-network + - tengig + deploy: + replicas: 1 + restart_policy: + condition: on-failure + delay: 10s + max_attempts: 3 + resources: + limits: + memory: 512M + reservations: + memory: 256M + placement: + constraints: + - node.role == manager + labels: + - "traefik.enable=true" + - "traefik.http.routers.hive-grafana.rule=Host(`hive.home.deepblack.cloud`) && PathPrefix(`/grafana`)" + - "traefik.http.routers.hive-grafana.entrypoints=web-secured" + - "traefik.http.routers.hive-grafana.tls.certresolver=letsencryptresolver" + - "traefik.http.services.hive-grafana.loadbalancer.server.port=3000" + - "traefik.docker.network=tengig" + +networks: + hive-network: + driver: overlay + attachable: true + tengig: + external: true + +volumes: + postgres_data: + redis_data: + prometheus_data: + grafana_data: \ No newline at end of file diff --git a/push-images.sh b/push-images.sh new file mode 100755 index 00000000..8a9f3841 --- /dev/null +++ b/push-images.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +# Push Hive images to local registry for swarm deployment + +set -e + +REGISTRY="anthonyrawlins" +BACKEND_IMAGE="hive-backend" +FRONTEND_IMAGE="hive-frontend" +LOCAL_BACKEND="hive-hive-backend" +LOCAL_FRONTEND="hive-hive-frontend" + +echo "🏗️ Building and pushing Hive images to Docker Hub..." + +# Tag and push backend +echo "📦 Pushing backend image..." +docker tag ${LOCAL_BACKEND}:latest ${REGISTRY}/${BACKEND_IMAGE}:latest +docker push ${REGISTRY}/${BACKEND_IMAGE}:latest + +# Tag and push frontend +echo "📦 Pushing frontend image..." +docker tag ${LOCAL_FRONTEND}:latest ${REGISTRY}/${FRONTEND_IMAGE}:latest +docker push ${REGISTRY}/${FRONTEND_IMAGE}:latest + +echo "✅ Images pushed to Docker Hub successfully!" +echo "Backend: ${REGISTRY}/${BACKEND_IMAGE}:latest" +echo "Frontend: ${REGISTRY}/${FRONTEND_IMAGE}:latest" \ No newline at end of file