| | #!/bin/bash |
| |
|
| | |
| | |
| |
|
| | set -e |
| |
|
| | |
| | PROJECT_NAME="transformer-sentiment" |
| | DOCKER_IMAGE="${PROJECT_NAME}:latest" |
| | BACKUP_DIR="./backups" |
| | LOG_DIR="./logs" |
| |
|
| | |
| | RED='\033[0;31m' |
| | GREEN='\033[0;32m' |
| | YELLOW='\033[1;33m' |
| | NC='\033[0m' |
| |
|
| | |
| | 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_dependencies() { |
| | log_info "Checking dependencies..." |
| | |
| | if ! command -v docker &> /dev/null; then |
| | log_error "Docker is not installed" |
| | exit 1 |
| | fi |
| | |
| | if ! command -v docker-compose &> /dev/null; then |
| | log_error "Docker Compose is not installed" |
| | exit 1 |
| | fi |
| | |
| | log_info "Dependencies check passed" |
| | } |
| |
|
| | |
| | setup_directories() { |
| | log_info "Setting up directories..." |
| | mkdir -p $BACKUP_DIR |
| | mkdir -p $LOG_DIR |
| | mkdir -p ./monitoring |
| | } |
| |
|
| | |
| | build_image() { |
| | log_info "Building Docker image..." |
| | docker build -t $DOCKER_IMAGE . |
| | log_info "Docker image built successfully" |
| | } |
| |
|
| | |
| | run_tests() { |
| | log_info "Running tests..." |
| | |
| | |
| | docker run --rm -v $(pwd):/app -w /app $DOCKER_IMAGE pytest tests/ -v |
| | |
| | if [ $? -eq 0 ]; then |
| | log_info "All tests passed" |
| | else |
| | log_error "Tests failed" |
| | exit 1 |
| | fi |
| | } |
| |
|
| | |
| | backup_deployment() { |
| | if [ -f "docker-compose.yml" ]; then |
| | log_info "Creating backup..." |
| | TIMESTAMP=$(date +%Y%m%d_%H%M%S) |
| | cp docker-compose.yml $BACKUP_DIR/docker-compose_$TIMESTAMP.yml |
| | log_info "Backup created: $BACKUP_DIR/docker-compose_$TIMESTAMP.yml" |
| | fi |
| | } |
| |
|
| | |
| | deploy() { |
| | local environment=${1:-production} |
| | |
| | log_info "Deploying to $environment environment..." |
| | |
| | |
| | case $environment in |
| | "production") |
| | export MODEL_PATH="./results" |
| | export WORKERS=4 |
| | ;; |
| | "staging") |
| | export MODEL_PATH="distilbert-base-uncased-finetuned-sst-2-english" |
| | export WORKERS=2 |
| | ;; |
| | "development") |
| | export MODEL_PATH="distilbert-base-uncased-finetuned-sst-2-english" |
| | export WORKERS=1 |
| | ;; |
| | *) |
| | log_error "Unknown environment: $environment" |
| | exit 1 |
| | ;; |
| | esac |
| | |
| | |
| | log_info "Stopping existing containers..." |
| | docker-compose down || true |
| | |
| | |
| | log_info "Starting new deployment..." |
| | docker-compose up -d |
| | |
| | |
| | log_info "Waiting for health check..." |
| | sleep 30 |
| | |
| | |
| | for i in {1..10}; do |
| | if curl -f http://localhost:8000/health &> /dev/null; then |
| | log_info "Deployment successful! API is responding" |
| | return 0 |
| | fi |
| | log_warn "Attempt $i: API not responding yet, waiting..." |
| | sleep 10 |
| | done |
| | |
| | log_error "Deployment failed: API not responding after 100 seconds" |
| | docker-compose logs |
| | exit 1 |
| | } |
| |
|
| | |
| | rollback() { |
| | log_warn "Rolling back deployment..." |
| | |
| | |
| | LATEST_BACKUP=$(ls -t $BACKUP_DIR/docker-compose_*.yml 2>/dev/null | head -n1) |
| | |
| | if [ -z "$LATEST_BACKUP" ]; then |
| | log_error "No backup found for rollback" |
| | exit 1 |
| | fi |
| | |
| | log_info "Rolling back to: $LATEST_BACKUP" |
| | |
| | |
| | docker-compose down |
| | |
| | |
| | cp $LATEST_BACKUP docker-compose.yml |
| | |
| | |
| | docker-compose up -d |
| | |
| | log_info "Rollback completed" |
| | } |
| |
|
| | |
| | show_status() { |
| | log_info "Deployment Status:" |
| | docker-compose ps |
| | |
| | echo "" |
| | log_info "API Health:" |
| | curl -s http://localhost:8000/health | python -m json.tool || echo "API not responding" |
| | |
| | echo "" |
| | log_info "Container Logs (last 20 lines):" |
| | docker-compose logs --tail=20 |
| | } |
| |
|
| | |
| | monitor() { |
| | log_info "Monitoring deployment..." |
| | docker-compose logs -f |
| | } |
| |
|
| | |
| | update_model() { |
| | local model_path=$1 |
| | |
| | if [ -z "$model_path" ]; then |
| | log_error "Model path required" |
| | exit 1 |
| | fi |
| | |
| | log_info "Updating model to: $model_path" |
| | |
| | |
| | export MODEL_PATH=$model_path |
| | |
| | |
| | docker-compose restart transformer-api |
| | |
| | log_info "Model updated successfully" |
| | } |
| |
|
| | |
| | cleanup() { |
| | log_info "Cleaning up old resources..." |
| | |
| | |
| | docker image prune -f |
| | |
| | |
| | ls -t $BACKUP_DIR/docker-compose_*.yml 2>/dev/null | tail -n +11 | xargs rm -f |
| | |
| | |
| | find $LOG_DIR -name "*.log" -mtime +7 -delete 2>/dev/null || true |
| | |
| | log_info "Cleanup completed" |
| | } |
| |
|
| | |
| | main() { |
| | local command=${1:-deploy} |
| | local environment=${2:-production} |
| | |
| | case $command in |
| | "deploy") |
| | check_dependencies |
| | setup_directories |
| | build_image |
| | run_tests |
| | backup_deployment |
| | deploy $environment |
| | ;; |
| | "rollback") |
| | rollback |
| | ;; |
| | "status") |
| | show_status |
| | ;; |
| | "monitor") |
| | monitor |
| | ;; |
| | "update-model") |
| | update_model $2 |
| | ;; |
| | "cleanup") |
| | cleanup |
| | ;; |
| | "build") |
| | build_image |
| | ;; |
| | "test") |
| | run_tests |
| | ;; |
| | *) |
| | echo "Usage: $0 {deploy|rollback|status|monitor|update-model|cleanup|build|test} [environment|model_path]" |
| | echo "" |
| | echo "Commands:" |
| | echo " deploy [env] - Deploy application (env: production|staging|development)" |
| | echo " rollback - Rollback to previous deployment" |
| | echo " status - Show deployment status" |
| | echo " monitor - Monitor deployment logs" |
| | echo " update-model - Update model path" |
| | echo " cleanup - Clean up old resources" |
| | echo " build - Build Docker image only" |
| | echo " test - Run tests only" |
| | echo "" |
| | echo "Examples:" |
| | echo " $0 deploy production" |
| | echo " $0 update-model ./new-model" |
| | echo " $0 status" |
| | exit 1 |
| | ;; |
| | esac |
| | } |
| |
|
| | |
| | main "$@" |