mirror of
https://github.com/hanzoai/bootnode.git
synced 2026-09-30 20:46:32 +00:00
279 lines
7.8 KiB
Bash
Executable File
279 lines
7.8 KiB
Bash
Executable File
#!/bin/bash
|
|
# Bootnode Cloud Deployment Script
|
|
# Usage: ./deploy.sh <provider> <environment>
|
|
# Example: ./deploy.sh aws production
|
|
|
|
set -euo pipefail
|
|
|
|
PROVIDER="${1:-docker}"
|
|
ENVIRONMENT="${2:-development}"
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
ROOT_DIR="$(dirname "$(dirname "$SCRIPT_DIR")")"
|
|
|
|
echo "=== Bootnode Deployment ==="
|
|
echo "Provider: $PROVIDER"
|
|
echo "Environment: $ENVIRONMENT"
|
|
echo ""
|
|
|
|
# Colors
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
NC='\033[0m' # No Color
|
|
|
|
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
|
|
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
|
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
|
|
|
# Check prerequisites
|
|
check_prerequisites() {
|
|
case $PROVIDER in
|
|
aws)
|
|
command -v aws >/dev/null 2>&1 || { log_error "AWS CLI required"; exit 1; }
|
|
command -v eksctl >/dev/null 2>&1 || { log_error "eksctl required"; exit 1; }
|
|
;;
|
|
gcp)
|
|
command -v gcloud >/dev/null 2>&1 || { log_error "gcloud CLI required"; exit 1; }
|
|
;;
|
|
azure)
|
|
command -v az >/dev/null 2>&1 || { log_error "Azure CLI required"; exit 1; }
|
|
;;
|
|
digitalocean)
|
|
command -v doctl >/dev/null 2>&1 || { log_error "doctl required"; exit 1; }
|
|
;;
|
|
docker)
|
|
command -v docker >/dev/null 2>&1 || { log_error "Docker required"; exit 1; }
|
|
;;
|
|
esac
|
|
command -v kubectl >/dev/null 2>&1 || { log_error "kubectl required"; exit 1; }
|
|
}
|
|
|
|
# Build Docker images
|
|
build_images() {
|
|
log_info "Building Docker images..."
|
|
|
|
cd "$ROOT_DIR"
|
|
|
|
# Build API
|
|
docker build -t ghcr.io/hanzoai/bootnode:api-latest -f api/Dockerfile api/
|
|
|
|
# Build Web
|
|
docker build -t ghcr.io/hanzoai/bootnode:web-latest -f web/Dockerfile web/
|
|
|
|
# Build Indexer (if exists)
|
|
if [ -d "indexer" ]; then
|
|
docker build -t ghcr.io/hanzoai/bootnode:indexer-latest -f indexer/Dockerfile indexer/
|
|
fi
|
|
|
|
log_info "Images built successfully"
|
|
}
|
|
|
|
# Deploy to Docker Compose (local/development)
|
|
deploy_docker() {
|
|
log_info "Deploying with Docker Compose..."
|
|
cd "$ROOT_DIR/infra"
|
|
|
|
if [ "$ENVIRONMENT" = "production" ]; then
|
|
docker compose --profile monitoring up -d
|
|
else
|
|
docker compose up -d
|
|
fi
|
|
|
|
log_info "Waiting for services to be healthy..."
|
|
sleep 10
|
|
|
|
docker compose ps
|
|
log_info "Deployment complete!"
|
|
echo ""
|
|
echo "Services available at:"
|
|
echo " - API: http://localhost:8000"
|
|
echo " - Web: http://localhost:3001"
|
|
echo " - Docs: http://localhost:8000/docs"
|
|
}
|
|
|
|
# Deploy to AWS EKS
|
|
deploy_aws() {
|
|
log_info "Deploying to AWS EKS..."
|
|
|
|
# Create cluster if it doesn't exist
|
|
if ! eksctl get cluster --name bootnode-cluster 2>/dev/null; then
|
|
log_info "Creating EKS cluster..."
|
|
eksctl create cluster -f "$SCRIPT_DIR/aws/eks-cluster.yaml"
|
|
fi
|
|
|
|
# Update kubeconfig
|
|
aws eks update-kubeconfig --name bootnode-cluster
|
|
|
|
# Push images to ECR
|
|
log_info "Pushing images to ECR..."
|
|
AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
|
|
AWS_REGION=${AWS_REGION:-us-east-1}
|
|
ECR_REGISTRY="$AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com"
|
|
|
|
aws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin $ECR_REGISTRY
|
|
|
|
for image in api web indexer; do
|
|
aws ecr describe-repositories --repository-names hanzoai/bootnode 2>/dev/null || \
|
|
aws ecr create-repository --repository-name hanzoai/bootnode
|
|
docker tag ghcr.io/hanzoai/bootnode:$image-latest $ECR_REGISTRY/hanzoai/bootnode:$image-latest
|
|
docker push $ECR_REGISTRY/hanzoai/bootnode:$image-latest
|
|
done
|
|
|
|
# Deploy to Kubernetes
|
|
deploy_kubernetes
|
|
}
|
|
|
|
# Deploy to GCP GKE
|
|
deploy_gcp() {
|
|
log_info "Deploying to GCP GKE..."
|
|
|
|
PROJECT_ID=$(gcloud config get-value project)
|
|
REGION=${GCP_REGION:-us-central1}
|
|
|
|
# Create cluster if it doesn't exist
|
|
if ! gcloud container clusters describe bootnode-cluster --region $REGION 2>/dev/null; then
|
|
log_info "Creating GKE cluster..."
|
|
gcloud container clusters create bootnode-cluster \
|
|
--region $REGION \
|
|
--num-nodes 3 \
|
|
--machine-type e2-standard-4 \
|
|
--enable-autoscaling --min-nodes 2 --max-nodes 10 \
|
|
--workload-pool=$PROJECT_ID.svc.id.goog
|
|
fi
|
|
|
|
# Get credentials
|
|
gcloud container clusters get-credentials bootnode-cluster --region $REGION
|
|
|
|
# Push images to GCR
|
|
log_info "Pushing images to GCR..."
|
|
for image in api web indexer; do
|
|
docker tag ghcr.io/hanzoai/bootnode:$image-latest gcr.io/$PROJECT_ID/hanzoai-bootnode:$image-latest
|
|
docker push gcr.io/$PROJECT_ID/hanzoai-bootnode:$image-latest
|
|
done
|
|
|
|
# Deploy to Kubernetes
|
|
deploy_kubernetes
|
|
}
|
|
|
|
# Deploy to Azure AKS
|
|
deploy_azure() {
|
|
log_info "Deploying to Azure AKS..."
|
|
|
|
RESOURCE_GROUP=${AZURE_RESOURCE_GROUP:-bootnode-rg}
|
|
LOCATION=${AZURE_LOCATION:-eastus}
|
|
|
|
# Create resource group
|
|
az group create --name $RESOURCE_GROUP --location $LOCATION 2>/dev/null || true
|
|
|
|
# Deploy cluster
|
|
az deployment group create \
|
|
--resource-group $RESOURCE_GROUP \
|
|
--template-file "$SCRIPT_DIR/azure/aks-cluster.bicep"
|
|
|
|
# Get credentials
|
|
az aks get-credentials --resource-group $RESOURCE_GROUP --name bootnode-cluster
|
|
|
|
# Push images to ACR
|
|
log_info "Pushing images to ACR..."
|
|
ACR_NAME="${RESOURCE_GROUP}acr"
|
|
az acr create --resource-group $RESOURCE_GROUP --name $ACR_NAME --sku Standard 2>/dev/null || true
|
|
az acr login --name $ACR_NAME
|
|
|
|
for image in api web indexer; do
|
|
docker tag ghcr.io/hanzoai/bootnode:$image-latest $ACR_NAME.azurecr.io/hanzoai/bootnode:$image-latest
|
|
docker push $ACR_NAME.azurecr.io/hanzoai/bootnode:$image-latest
|
|
done
|
|
|
|
# Deploy to Kubernetes
|
|
deploy_kubernetes
|
|
}
|
|
|
|
# Deploy to DigitalOcean DOKS
|
|
deploy_digitalocean() {
|
|
log_info "Deploying to DigitalOcean Kubernetes..."
|
|
|
|
# Create cluster if it doesn't exist
|
|
if ! doctl kubernetes cluster get bootnode-cluster 2>/dev/null; then
|
|
log_info "Creating DOKS cluster..."
|
|
doctl kubernetes cluster create bootnode-cluster \
|
|
--region nyc1 \
|
|
--version 1.29.1-do.0 \
|
|
--node-pool "name=api-pool;size=s-4vcpu-8gb;count=3;auto-scale=true;min-nodes=2;max-nodes=10"
|
|
fi
|
|
|
|
# Get credentials
|
|
doctl kubernetes cluster kubeconfig save bootnode-cluster
|
|
|
|
# Push images to DO Container Registry
|
|
log_info "Pushing images to DO Container Registry..."
|
|
doctl registry login
|
|
REGISTRY=$(doctl registry get --format RegistryName --no-header)
|
|
|
|
for image in api web indexer; do
|
|
docker tag ghcr.io/hanzoai/bootnode:$image-latest registry.digitalocean.com/$REGISTRY/hanzoai-bootnode:$image-latest
|
|
docker push registry.digitalocean.com/$REGISTRY/hanzoai-bootnode:$image-latest
|
|
done
|
|
|
|
# Deploy to Kubernetes
|
|
deploy_kubernetes
|
|
}
|
|
|
|
# Deploy Kubernetes resources
|
|
deploy_kubernetes() {
|
|
log_info "Deploying Kubernetes resources..."
|
|
|
|
K8S_DIR="$ROOT_DIR/infra/k8s"
|
|
|
|
# Create namespace
|
|
kubectl apply -f "$K8S_DIR/namespace.yaml"
|
|
|
|
# Create secrets (you should use external secrets manager in production)
|
|
kubectl apply -f "$K8S_DIR/secrets.yaml"
|
|
|
|
# Deploy services
|
|
kubectl apply -f "$K8S_DIR/api-deployment.yaml"
|
|
kubectl apply -f "$K8S_DIR/indexer-deployment.yaml"
|
|
kubectl apply -f "$K8S_DIR/ingress.yaml"
|
|
|
|
# Wait for deployments
|
|
log_info "Waiting for deployments to be ready..."
|
|
kubectl rollout status deployment/bootnode-api -n bootnode --timeout=300s
|
|
kubectl rollout status deployment/bootnode-indexer -n bootnode --timeout=300s
|
|
|
|
log_info "Deployment complete!"
|
|
kubectl get pods -n bootnode
|
|
kubectl get svc -n bootnode
|
|
}
|
|
|
|
# Main execution
|
|
check_prerequisites
|
|
|
|
# Build images for cloud deployments
|
|
if [ "$PROVIDER" != "docker" ]; then
|
|
build_images
|
|
fi
|
|
|
|
# Deploy based on provider
|
|
case $PROVIDER in
|
|
docker)
|
|
deploy_docker
|
|
;;
|
|
aws)
|
|
deploy_aws
|
|
;;
|
|
gcp)
|
|
deploy_gcp
|
|
;;
|
|
azure)
|
|
deploy_azure
|
|
;;
|
|
digitalocean)
|
|
deploy_digitalocean
|
|
;;
|
|
*)
|
|
log_error "Unknown provider: $PROVIDER"
|
|
echo "Supported providers: docker, aws, gcp, azure, digitalocean"
|
|
exit 1
|
|
;;
|
|
esac
|