-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdeploy.sh
More file actions
executable file
·192 lines (162 loc) · 5.88 KB
/
deploy.sh
File metadata and controls
executable file
·192 lines (162 loc) · 5.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
#!/bin/bash
# PBSMON 2.0 Deployment Script
# This script pulls the latest code and restarts Docker containers
# Usage: ./deploy.sh [--skip-pull]
# --skip-pull: Skip pulling the latest code from git
# it should be run on the production server
set -e # Exit on any error
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Get the directory where the script is located
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd "$SCRIPT_DIR"
# Check if --skip-pull flag is present
SKIP_PULL=false
for arg in "$@"; do
if [ "$arg" = "--skip-pull" ]; then
SKIP_PULL=true
break
fi
done
# Check if git is available
if ! command -v git &> /dev/null; then
echo -e "${RED}Error: git is not installed${NC}"
exit 1
fi
# Pull latest code (unless --skip-pull flag is set)
if [ "$SKIP_PULL" = false ]; then
echo -e "${YELLOW}Pulling latest code from git...${NC}"
if git pull; then
echo -e "${GREEN}✓ Code updated successfully${NC}"
echo -e "${YELLOW}Restarting script with --skip-pull flag...${NC}"
# Kill current process and restart script with --skip-pull
exec "$0" --skip-pull
else
echo -e "${RED}✗ Failed to pull code from git${NC}"
exit 1
fi
fi
# Load environment variables from .env file if it exists
ENV_FILE="$SCRIPT_DIR/.env"
if [ -f "$ENV_FILE" ]; then
echo -e "${YELLOW}Loading environment variables from .env file...${NC}"
# Export variables from .env file (handles comments and empty lines)
set -a
source "$ENV_FILE"
set +a
echo -e "${GREEN}✓ Environment variables loaded${NC}"
else
echo -e "${YELLOW}⚠️ No .env file found at $ENV_FILE${NC}"
echo -e "${YELLOW} Make sure API_AUTH_USERNAME and API_AUTH_PASSWORD are set${NC}"
fi
echo -e "${GREEN}Starting deployment...${NC}"
# Check if docker-compose or docker compose is available
if command -v docker-compose &> /dev/null; then
DOCKER_COMPOSE="docker-compose"
elif docker compose version &> /dev/null; then
DOCKER_COMPOSE="docker compose"
else
echo -e "${RED}Error: docker-compose is not installed${NC}"
exit 1
fi
# Set the docker compose file
COMPOSE_FILE="docker-compose.prod.yml"
# Pre-generate OpenAPI spec and web API client before any service build/start
OPENAPI_SPEC_PATH="$SCRIPT_DIR/web/openapi/openapi.json"
echo -e "${YELLOW}Pre-generating OpenAPI spec and web API client...${NC}"
mkdir -p "$(dirname "$OPENAPI_SPEC_PATH")"
echo -e "${YELLOW}Generating OpenAPI spec from API source...${NC}"
if [ -f "$ENV_FILE" ]; then
if docker run --rm \
--env-file "$ENV_FILE" \
-v "$SCRIPT_DIR:/workspace" \
-w /workspace/api \
node:24-alpine \
sh -c "npm ci && npm run generate:openapi -- --output /workspace/web/openapi/openapi.json"; then
echo -e "${GREEN}✓ OpenAPI spec generated${NC}"
else
echo -e "${RED}✗ Failed to generate OpenAPI spec${NC}"
exit 1
fi
else
if docker run --rm \
-v "$SCRIPT_DIR:/workspace" \
-w /workspace/api \
node:24-alpine \
sh -c "npm ci && npm run generate:openapi -- --output /workspace/web/openapi/openapi.json"; then
echo -e "${GREEN}✓ OpenAPI spec generated${NC}"
else
echo -e "${RED}✗ Failed to generate OpenAPI spec${NC}"
exit 1
fi
fi
echo -e "${YELLOW}Generating web API client from local OpenAPI spec...${NC}"
if docker run --rm \
-e OPENAPI_SPEC_FILE=/workspace/web/openapi/openapi.json \
-v "$SCRIPT_DIR:/workspace" \
-w /workspace/web \
node:24-alpine \
sh -c "npm ci && npm run generate:api"; then
echo -e "${GREEN}✓ Web API client generated${NC}"
else
echo -e "${RED}✗ Failed to generate web API client${NC}"
exit 1
fi
# Build and start API first
echo -e "${YELLOW}Building and starting API container first...${NC}"
if $DOCKER_COMPOSE -f "$COMPOSE_FILE" up -d --build api; then
echo -e "${GREEN}✓ API container started${NC}"
else
echo -e "${RED}✗ Failed to start API container${NC}"
exit 1
fi
# Wait for API to be ready (check health endpoint)
echo -e "${YELLOW}Waiting for API to be ready...${NC}"
API_READY=false
MAX_ATTEMPTS=30
ATTEMPT=0
# Try to connect to API health endpoint
while [ $ATTEMPT -lt $MAX_ATTEMPTS ]; do
ATTEMPT=$((ATTEMPT + 1))
echo -e "${YELLOW}Attempt $ATTEMPT/$MAX_ATTEMPTS: Checking API health...${NC}"
# Check if API container is running
if docker ps | grep -q pbsmon-api; then
# Try to hit the health endpoint inside the container
if docker exec pbsmon-api node -e "require('http').get('http://localhost:3000/status', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})" 2>/dev/null; then
API_READY=true
echo -e "${GREEN}✓ API is ready${NC}"
break
fi
fi
if [ $ATTEMPT -lt $MAX_ATTEMPTS ]; then
sleep 2
fi
done
if [ "$API_READY" = false ]; then
echo -e "${YELLOW}⚠️ API health check failed after $MAX_ATTEMPTS attempts${NC}"
echo -e "${YELLOW} Continuing anyway - web build will try to fetch OpenAPI spec${NC}"
fi
# Now build and start web service
echo -e "${YELLOW}Building and starting web container...${NC}"
if $DOCKER_COMPOSE -f "$COMPOSE_FILE" up -d --build web; then
echo -e "${GREEN}✓ Web container started${NC}"
else
echo -e "${RED}✗ Failed to start web container${NC}"
exit 1
fi
# Wait a moment for containers to start
sleep 5
# Check container status
echo -e "${YELLOW}Checking container status...${NC}"
$DOCKER_COMPOSE -f "$COMPOSE_FILE" ps
# Show logs for the last 20 lines
echo -e "${YELLOW}Recent logs:${NC}"
$DOCKER_COMPOSE -f "$COMPOSE_FILE" logs --tail=20
echo -e "${GREEN}Deployment completed successfully!${NC}"
echo -e "${GREEN}Services should be available at:${NC}"
echo -e " - Frontend: http://localhost"
echo -e " - API: http://localhost/api"
echo -e " - Swagger: http://localhost/api/docs"