MogensR commited on
Commit
dd4248f
Β·
1 Parent(s): 3c3f63e

Create scripts/deploy.sh

Browse files
Files changed (1) hide show
  1. scripts/deploy.sh +379 -0
scripts/deploy.sh ADDED
@@ -0,0 +1,379 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+ # Deployment script for BackgroundFX Pro
3
+ # Handles deployment to various environments
4
+
5
+ set -e
6
+
7
+ # Configuration
8
+ SCRIPT_DIR=$(dirname $(realpath $0))
9
+ PROJECT_ROOT=$(dirname $SCRIPT_DIR)
10
+ TIMESTAMP=$(date +%Y%m%d_%H%M%S)
11
+
12
+ # Colors
13
+ RED='\033[0;31m'
14
+ GREEN='\033[0;32m'
15
+ YELLOW='\033[1;33m'
16
+ BLUE='\033[0;34m'
17
+ NC='\033[0m'
18
+
19
+ # Default values
20
+ ENVIRONMENT="production"
21
+ DEPLOY_METHOD="docker"
22
+ REGISTRY=""
23
+ VERSION="latest"
24
+ BACKUP=true
25
+
26
+ # Parse arguments
27
+ while [[ $# -gt 0 ]]; do
28
+ case $1 in
29
+ --env)
30
+ ENVIRONMENT="$2"
31
+ shift 2
32
+ ;;
33
+ --method)
34
+ DEPLOY_METHOD="$2"
35
+ shift 2
36
+ ;;
37
+ --registry)
38
+ REGISTRY="$2"
39
+ shift 2
40
+ ;;
41
+ --version)
42
+ VERSION="$2"
43
+ shift 2
44
+ ;;
45
+ --no-backup)
46
+ BACKUP=false
47
+ shift
48
+ ;;
49
+ --help)
50
+ show_help
51
+ exit 0
52
+ ;;
53
+ *)
54
+ echo -e "${RED}Unknown option: $1${NC}"
55
+ show_help
56
+ exit 1
57
+ ;;
58
+ esac
59
+ done
60
+
61
+ show_help() {
62
+ cat << EOF
63
+ Usage: $0 [OPTIONS]
64
+
65
+ Deploy BackgroundFX Pro to various environments
66
+
67
+ Options:
68
+ --env ENV Environment (development, staging, production) [default: production]
69
+ --method METHOD Deployment method (docker, kubernetes, server) [default: docker]
70
+ --registry REGISTRY Container registry URL
71
+ --version VERSION Version to deploy [default: latest]
72
+ --no-backup Skip backup before deployment
73
+ --help Show this help message
74
+
75
+ Examples:
76
+ $0 --env production --method docker
77
+ $0 --env staging --registry myregistry.com --version 1.0.0
78
+ $0 --env development --no-backup
79
+ EOF
80
+ }
81
+
82
+ # Deployment functions
83
+ deploy_docker() {
84
+ echo -e "${BLUE}Deploying with Docker to ${ENVIRONMENT}...${NC}"
85
+
86
+ cd "$PROJECT_ROOT"
87
+
88
+ # Build images
89
+ echo "Building Docker images..."
90
+ if [ "$ENVIRONMENT" = "production" ]; then
91
+ docker build -f docker/Dockerfile.prod -t backgroundfx-pro:$VERSION .
92
+ else
93
+ docker build -f docker/Dockerfile -t backgroundfx-pro:$VERSION .
94
+ fi
95
+
96
+ # Tag for registry if specified
97
+ if [ -n "$REGISTRY" ]; then
98
+ docker tag backgroundfx-pro:$VERSION $REGISTRY/backgroundfx-pro:$VERSION
99
+ docker push $REGISTRY/backgroundfx-pro:$VERSION
100
+ echo -e "${GREEN}βœ“ Pushed to registry: $REGISTRY${NC}"
101
+ fi
102
+
103
+ # Deploy with docker-compose
104
+ if [ "$ENVIRONMENT" = "production" ]; then
105
+ docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
106
+ else
107
+ docker-compose up -d
108
+ fi
109
+
110
+ echo -e "${GREEN}βœ“ Docker deployment complete${NC}"
111
+ }
112
+
113
+ deploy_kubernetes() {
114
+ echo -e "${BLUE}Deploying to Kubernetes cluster...${NC}"
115
+
116
+ cd "$PROJECT_ROOT/kubernetes"
117
+
118
+ # Check kubectl
119
+ if ! command -v kubectl &> /dev/null; then
120
+ echo -e "${RED}kubectl not found${NC}"
121
+ exit 1
122
+ fi
123
+
124
+ # Apply configurations
125
+ echo "Applying Kubernetes configurations..."
126
+
127
+ # Create namespace if not exists
128
+ kubectl create namespace backgroundfx --dry-run=client -o yaml | kubectl apply -f -
129
+
130
+ # Apply configs based on environment
131
+ if [ "$ENVIRONMENT" = "production" ]; then
132
+ kubectl apply -f configmap-prod.yaml
133
+ kubectl apply -f secret-prod.yaml
134
+ kubectl apply -f deployment-prod.yaml
135
+ kubectl apply -f service-prod.yaml
136
+ kubectl apply -f ingress-prod.yaml
137
+ else
138
+ kubectl apply -f configmap.yaml
139
+ kubectl apply -f deployment.yaml
140
+ kubectl apply -f service.yaml
141
+ fi
142
+
143
+ # Wait for deployment
144
+ echo "Waiting for deployment to be ready..."
145
+ kubectl rollout status deployment/backgroundfx-pro -n backgroundfx
146
+
147
+ # Get service info
148
+ echo -e "\n${GREEN}Deployment complete!${NC}"
149
+ kubectl get services -n backgroundfx
150
+ kubectl get pods -n backgroundfx
151
+ }
152
+
153
+ deploy_server() {
154
+ echo -e "${BLUE}Deploying to server...${NC}"
155
+
156
+ # Check for required environment variables
157
+ if [ -z "$DEPLOY_HOST" ] || [ -z "$DEPLOY_USER" ]; then
158
+ echo -e "${RED}Error: DEPLOY_HOST and DEPLOY_USER must be set${NC}"
159
+ exit 1
160
+ fi
161
+
162
+ cd "$PROJECT_ROOT"
163
+
164
+ # Create deployment package
165
+ echo "Creating deployment package..."
166
+ PACKAGE_NAME="backgroundfx_${VERSION}_${TIMESTAMP}.tar.gz"
167
+
168
+ tar -czf "/tmp/$PACKAGE_NAME" \
169
+ --exclude="*.pyc" \
170
+ --exclude="__pycache__" \
171
+ --exclude=".git" \
172
+ --exclude="venv" \
173
+ --exclude="*.log" \
174
+ --exclude="outputs/*" \
175
+ --exclude="uploads/*" \
176
+ .
177
+
178
+ # Upload to server
179
+ echo "Uploading to $DEPLOY_HOST..."
180
+ scp "/tmp/$PACKAGE_NAME" "$DEPLOY_USER@$DEPLOY_HOST:/tmp/"
181
+
182
+ # Deploy on server
183
+ echo "Deploying on server..."
184
+ ssh "$DEPLOY_USER@$DEPLOY_HOST" << EOF
185
+ # Create deployment directory
186
+ mkdir -p /opt/backgroundfx/releases/$VERSION
187
+
188
+ # Extract package
189
+ tar -xzf /tmp/$PACKAGE_NAME -C /opt/backgroundfx/releases/$VERSION
190
+
191
+ # Stop current service
192
+ sudo systemctl stop backgroundfx || true
193
+
194
+ # Update symlink
195
+ rm -f /opt/backgroundfx/current
196
+ ln -s /opt/backgroundfx/releases/$VERSION /opt/backgroundfx/current
197
+
198
+ # Install dependencies
199
+ cd /opt/backgroundfx/current
200
+ python3 -m venv venv
201
+ source venv/bin/activate
202
+ pip install -r requirements.txt
203
+
204
+ # Start service
205
+ sudo systemctl start backgroundfx
206
+ sudo systemctl status backgroundfx
207
+ EOF
208
+
209
+ # Cleanup
210
+ rm "/tmp/$PACKAGE_NAME"
211
+
212
+ echo -e "${GREEN}βœ“ Server deployment complete${NC}"
213
+ }
214
+
215
+ # Health check
216
+ health_check() {
217
+ echo -e "\n${BLUE}Running health check...${NC}"
218
+
219
+ # Determine URL based on environment
220
+ if [ "$ENVIRONMENT" = "production" ]; then
221
+ URL="https://app.backgroundfx.com/health"
222
+ elif [ "$ENVIRONMENT" = "staging" ]; then
223
+ URL="https://staging.backgroundfx.com/health"
224
+ else
225
+ URL="http://localhost:7860/health"
226
+ fi
227
+
228
+ # Check health endpoint
229
+ if curl -f -s "$URL" > /dev/null; then
230
+ echo -e "${GREEN}βœ“ Application is healthy${NC}"
231
+ curl -s "$URL" | python -m json.tool
232
+ else
233
+ echo -e "${RED}βœ— Health check failed${NC}"
234
+ return 1
235
+ fi
236
+ }
237
+
238
+ # Backup function
239
+ create_backup() {
240
+ if [ "$BACKUP" = false ]; then
241
+ return
242
+ fi
243
+
244
+ echo -e "${BLUE}Creating backup...${NC}"
245
+
246
+ BACKUP_DIR="$PROJECT_ROOT/backups/$TIMESTAMP"
247
+ mkdir -p "$BACKUP_DIR"
248
+
249
+ # Backup database if exists
250
+ if [ -f "$PROJECT_ROOT/database.db" ]; then
251
+ cp "$PROJECT_ROOT/database.db" "$BACKUP_DIR/"
252
+ fi
253
+
254
+ # Backup configurations
255
+ cp -r "$PROJECT_ROOT/config" "$BACKUP_DIR/" 2>/dev/null || true
256
+
257
+ # Backup docker volumes if using Docker
258
+ if [ "$DEPLOY_METHOD" = "docker" ]; then
259
+ docker run --rm \
260
+ -v backgroundfx-pro_model-cache:/data \
261
+ -v "$BACKUP_DIR":/backup \
262
+ alpine tar czf /backup/models.tar.gz -C /data . 2>/dev/null || true
263
+ fi
264
+
265
+ echo -e "${GREEN}βœ“ Backup created: $BACKUP_DIR${NC}"
266
+ }
267
+
268
+ # Rollback function
269
+ rollback() {
270
+ echo -e "${YELLOW}Rolling back deployment...${NC}"
271
+
272
+ if [ "$DEPLOY_METHOD" = "docker" ]; then
273
+ # Docker rollback
274
+ docker-compose down
275
+ docker tag backgroundfx-pro:previous backgroundfx-pro:$VERSION
276
+ docker-compose up -d
277
+ elif [ "$DEPLOY_METHOD" = "kubernetes" ]; then
278
+ # Kubernetes rollback
279
+ kubectl rollout undo deployment/backgroundfx-pro -n backgroundfx
280
+ elif [ "$DEPLOY_METHOD" = "server" ]; then
281
+ # Server rollback
282
+ ssh "$DEPLOY_USER@$DEPLOY_HOST" << EOF
283
+ rm /opt/backgroundfx/current
284
+ ln -s /opt/backgroundfx/releases/previous /opt/backgroundfx/current
285
+ sudo systemctl restart backgroundfx
286
+ EOF
287
+ fi
288
+
289
+ echo -e "${GREEN}βœ“ Rollback complete${NC}"
290
+ }
291
+
292
+ # Pre-deployment checks
293
+ pre_deploy_checks() {
294
+ echo -e "${BLUE}Running pre-deployment checks...${NC}"
295
+
296
+ # Check git status
297
+ if [ -d .git ]; then
298
+ if [ -n "$(git status --porcelain)" ]; then
299
+ echo -e "${YELLOW}Warning: Uncommitted changes detected${NC}"
300
+ read -p "Continue anyway? (y/n): " -n 1 -r
301
+ echo
302
+ if [[ ! $REPLY =~ ^[Yy]$ ]]; then
303
+ exit 1
304
+ fi
305
+ fi
306
+ fi
307
+
308
+ # Run tests
309
+ echo "Running tests..."
310
+ if command -v pytest &> /dev/null; then
311
+ pytest tests/ -m "not slow" --quiet || {
312
+ echo -e "${RED}Tests failed${NC}"
313
+ read -p "Deploy anyway? (y/n): " -n 1 -r
314
+ echo
315
+ if [[ ! $REPLY =~ ^[Yy]$ ]]; then
316
+ exit 1
317
+ fi
318
+ }
319
+ else
320
+ echo -e "${YELLOW}pytest not found, skipping tests${NC}"
321
+ fi
322
+
323
+ echo -e "${GREEN}βœ“ Pre-deployment checks passed${NC}"
324
+ }
325
+
326
+ # Main deployment flow
327
+ main() {
328
+ echo -e "${BLUE}========================================${NC}"
329
+ echo -e "${BLUE}BackgroundFX Pro Deployment${NC}"
330
+ echo -e "${BLUE}========================================${NC}"
331
+ echo "Environment: $ENVIRONMENT"
332
+ echo "Method: $DEPLOY_METHOD"
333
+ echo "Version: $VERSION"
334
+ echo
335
+
336
+ # Run pre-deployment checks
337
+ pre_deploy_checks
338
+
339
+ # Create backup
340
+ create_backup
341
+
342
+ # Deploy based on method
343
+ case $DEPLOY_METHOD in
344
+ docker)
345
+ deploy_docker
346
+ ;;
347
+ kubernetes)
348
+ deploy_kubernetes
349
+ ;;
350
+ server)
351
+ deploy_server
352
+ ;;
353
+ *)
354
+ echo -e "${RED}Invalid deployment method: $DEPLOY_METHOD${NC}"
355
+ exit 1
356
+ ;;
357
+ esac
358
+
359
+ # Run health check
360
+ sleep 5
361
+ if health_check; then
362
+ echo -e "\n${GREEN}========================================${NC}"
363
+ echo -e "${GREEN}Deployment Successful!${NC}"
364
+ echo -e "${GREEN}========================================${NC}"
365
+ else
366
+ echo -e "\n${RED}Deployment may have issues${NC}"
367
+ read -p "Rollback? (y/n): " -n 1 -r
368
+ echo
369
+ if [[ $REPLY =~ ^[Yy]$ ]]; then
370
+ rollback
371
+ fi
372
+ fi
373
+ }
374
+
375
+ # Trap errors
376
+ trap 'echo -e "${RED}Deployment failed!${NC}"; exit 1' ERR
377
+
378
+ # Run main function
379
+ main