#!/bin/bash # Basil Deployment Script # This script pulls the latest Docker images and restarts the containers set -e # Exit on error # Configuration SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_DIR="$(dirname "$SCRIPT_DIR")" LOG_FILE="$PROJECT_DIR/deploy.log" BACKUP_DIR="$PROJECT_DIR/backups" DOCKER_REGISTRY="${DOCKER_REGISTRY:-docker.io}" DOCKER_USERNAME="${DOCKER_USERNAME}" IMAGE_TAG="${IMAGE_TAG:-latest}" # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color # Logging function log() { echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1" | tee -a "$LOG_FILE" } error() { echo -e "${RED}[$(date +'%Y-%m-%d %H:%M:%S')] ERROR:${NC} $1" | tee -a "$LOG_FILE" } warning() { echo -e "${YELLOW}[$(date +'%Y-%m-%d %H:%M:%S')] WARNING:${NC} $1" | tee -a "$LOG_FILE" } # Check if Docker is running check_docker() { if ! docker info > /dev/null 2>&1; then error "Docker is not running. Please start Docker and try again." exit 1 fi log "Docker is running" } # Create backup before deployment create_backup() { log "Creating pre-deployment backup..." # Ensure backup directory exists mkdir -p "$BACKUP_DIR" # Create backup using the API if running if docker ps | grep -q basil-api; then log "Creating database backup via API..." curl -X POST http://localhost:3001/api/backup -o "$BACKUP_DIR/pre-deploy-$(date +%Y%m%d-%H%M%S).zip" 2>/dev/null || warning "API backup failed, continuing anyway" else warning "API container not running, skipping automatic backup" fi } # Pull latest images from registry pull_images() { log "Pulling latest Docker images..." if [ -z "$DOCKER_USERNAME" ]; then error "DOCKER_USERNAME environment variable not set" exit 1 fi # Pull API image log "Pulling API image: ${DOCKER_REGISTRY}/${DOCKER_USERNAME}/basil-api:${IMAGE_TAG}" docker pull "${DOCKER_REGISTRY}/${DOCKER_USERNAME}/basil-api:${IMAGE_TAG}" || { error "Failed to pull API image" exit 1 } # Pull Web image log "Pulling Web image: ${DOCKER_REGISTRY}/${DOCKER_USERNAME}/basil-web:${IMAGE_TAG}" docker pull "${DOCKER_REGISTRY}/${DOCKER_USERNAME}/basil-web:${IMAGE_TAG}" || { error "Failed to pull Web image" exit 1 } log "Successfully pulled all images" } # Update docker-compose.yml to use registry images update_docker_compose() { log "Updating docker-compose configuration..." # Create docker-compose.override.yml to use registry images cat > "$PROJECT_DIR/docker-compose.override.yml" < /dev/null 2>&1; then log "API is healthy" break fi RETRY_COUNT=$((RETRY_COUNT + 1)) if [ $RETRY_COUNT -eq $MAX_RETRIES ]; then error "API health check failed after $MAX_RETRIES attempts" docker-compose logs api exit 1 fi sleep 2 done # Check web container if docker ps | grep -q basil-web; then log "Web container is running" else error "Web container is not running" docker-compose logs web exit 1 fi log "All health checks passed" } # Cleanup old images cleanup_old_images() { log "Cleaning up old Docker images..." docker image prune -f > /dev/null 2>&1 || warning "Failed to prune some images" log "Cleanup complete" } # Main deployment flow main() { log "=========================================" log "Starting Basil deployment" log "Registry: ${DOCKER_REGISTRY}" log "Username: ${DOCKER_USERNAME}" log "Tag: ${IMAGE_TAG}" log "=========================================" check_docker create_backup pull_images update_docker_compose restart_containers health_check cleanup_old_images log "=========================================" log "Deployment completed successfully!" log "=========================================" } # Run main function main "$@"