-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdeploy.sh
More file actions
323 lines (285 loc) · 8.97 KB
/
Copy pathdeploy.sh
File metadata and controls
323 lines (285 loc) · 8.97 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
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
#!/bin/bash
# Minder AI Deployment Script
# Uses global Caddy (caddy-proxy) for HTTPS via proxy-net
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
echo -e "${BLUE}========================================${NC}"
echo -e "${BLUE} Minder AI Deployment Script ${NC}"
echo -e "${BLUE}========================================${NC}"
echo ""
# Check if Docker is installed
if ! command -v docker &> /dev/null; then
echo -e "${RED}Error: Docker is not installed. Please install Docker first.${NC}"
exit 1
fi
# Check if Docker Compose is installed
if ! command -v docker-compose &> /dev/null && ! docker compose version &> /dev/null; then
echo -e "${RED}Error: Docker Compose is not installed. Please install Docker Compose first.${NC}"
exit 1
fi
# Determine docker compose command
if docker compose version &> /dev/null 2>&1; then
COMPOSE_CMD="docker compose"
else
COMPOSE_CMD="docker-compose"
fi
# Global Caddy config
CADDY_CADDYFILE="/data/user/xiao/nginx/Caddyfile"
CADDY_CONTAINER="caddy-proxy"
# Function to display usage
usage() {
echo "Usage: $0 [command]"
echo ""
echo "Commands:"
echo " start Start all services"
echo " stop Stop all services"
echo " restart Restart all services"
echo " rebuild Rebuild and restart all services"
echo " logs Show logs (use -f for follow)"
echo " status Show status of services"
echo " clean Stop and remove all containers, volumes"
echo " setup Initial setup (create .env from template)"
echo " setup-domain Add domain to global Caddy and reload"
echo " caddy-reload Reload global Caddy config"
echo ""
}
# Function to check .env file
check_env() {
if [ ! -f ".env" ]; then
echo -e "${YELLOW}Warning: .env file not found.${NC}"
echo -e "Run '${GREEN}$0 setup${NC}' to create one from template."
return 1
fi
return 0
}
# Check proxy-net network exists
check_proxy_net() {
if ! docker network inspect proxy-net &> /dev/null; then
echo -e "${RED}Error: Docker network 'proxy-net' not found.${NC}"
echo -e "${YELLOW}The global Caddy (caddy-proxy) must be running first.${NC}"
return 1
fi
return 0
}
# Function for initial setup
setup() {
echo -e "${BLUE}Setting up Minder AI...${NC}"
if [ -f ".env" ]; then
echo -e "${YELLOW}.env file already exists.${NC}"
read -p "Do you want to overwrite it? (y/N) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo "Setup cancelled."
return
fi
fi
cp .env.docker .env
echo -e "${GREEN}.env file created from template.${NC}"
echo -e "${YELLOW}Please edit .env and fill in your configuration.${NC}"
echo ""
echo "Required configuration:"
echo " - POSTGRES_PASSWORD: Set a secure database password"
echo " - JWT_SECRET: Set a secure JWT secret"
echo " - SILICONFLOW_API_KEY or QWEN_API_KEY: At least one for AI features"
echo " - MINDERAI_DOMAIN: Your domain (default: minderai.heywhale.com)"
echo ""
echo -e "${GREEN}HTTPS is managed by the global Caddy (caddy-proxy).${NC}"
echo -e "Run '${GREEN}$0 setup-domain${NC}' to register the domain with Caddy."
}
# Function to setup domain in global Caddy
setup_domain() {
echo -e "${BLUE}Setting up domain in global Caddy...${NC}"
# Get domain from .env
if [ -f ".env" ]; then
DOMAIN=$(grep -E "^MINDERAI_DOMAIN=" .env | cut -d '=' -f2 | tr -d ' ')
fi
DOMAIN=${DOMAIN:-minderai.heywhale.com}
echo -e "Domain: ${GREEN}${DOMAIN}${NC}"
echo -e "Caddyfile: ${GREEN}${CADDY_CADDYFILE}${NC}"
echo ""
# Check if domain already configured
if grep -q "${DOMAIN}" "${CADDY_CADDYFILE}" 2>/dev/null; then
echo -e "${GREEN}Domain ${DOMAIN} is already configured in Caddyfile.${NC}"
echo ""
read -p "Reload Caddy anyway? (y/N) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
caddy_reload
fi
return 0
fi
# Append config to Caddyfile
echo -e "${BLUE}Adding ${DOMAIN} to Caddyfile...${NC}"
cat >> "${CADDY_CADDYFILE}" <<CADDYEOF
${DOMAIN} {
reverse_proxy /* minderai-frontend:80
tls liyy@heywhale.com
encode gzip
header {
X-Frame-Options "SAMEORIGIN"
X-Content-Type-Options "nosniff"
Strict-Transport-Security "max-age=63072000; includeSubDomains"
}
}
CADDYEOF
echo -e "${GREEN}Domain config added!${NC}"
echo ""
# Reload Caddy
caddy_reload
echo ""
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN} Domain setup complete! ${NC}"
echo -e "${GREEN}========================================${NC}"
echo ""
echo -e " Site: ${BLUE}https://${DOMAIN}${NC}"
echo -e " API Docs: ${BLUE}https://${DOMAIN}/api/docs${NC}"
echo ""
}
# Function to start services
start() {
check_env || return 1
check_proxy_net || return 1
echo -e "${BLUE}Starting Minder AI services...${NC}"
# Check if using external database
if grep -q "^DATABASE_URL=" .env 2>/dev/null; then
echo -e "${YELLOW}Using external database from DATABASE_URL${NC}"
$COMPOSE_CMD up -d --remove-orphans backend frontend
else
echo -e "${YELLOW}Using local PostgreSQL container${NC}"
$COMPOSE_CMD --profile local-db up -d --remove-orphans
fi
echo -e "${GREEN}Services started!${NC}"
echo ""
show_access_info
}
# Function to stop services
stop() {
echo -e "${BLUE}Stopping Minder AI services...${NC}"
$COMPOSE_CMD down --remove-orphans
echo -e "${GREEN}Services stopped.${NC}"
}
# Function to restart services
restart() {
check_env || return 1
echo -e "${BLUE}Restarting Minder AI services...${NC}"
$COMPOSE_CMD restart
echo -e "${GREEN}Services restarted.${NC}"
}
# Function to rebuild and restart
rebuild() {
check_env || return 1
check_proxy_net || return 1
echo -e "${BLUE}Rebuilding Minder AI services...${NC}"
$COMPOSE_CMD down --remove-orphans
$COMPOSE_CMD build --no-cache
# Check if using external database
if grep -q "^DATABASE_URL=" .env 2>/dev/null; then
$COMPOSE_CMD up -d --remove-orphans backend frontend
else
$COMPOSE_CMD --profile local-db up -d --remove-orphans
fi
echo -e "${GREEN}Services rebuilt and started!${NC}"
echo ""
show_access_info
}
# Function to show logs
logs() {
$COMPOSE_CMD logs "$@"
}
# Function to show status
status() {
echo -e "${BLUE}Minder AI Services Status:${NC}"
echo ""
$COMPOSE_CMD ps
echo ""
echo -e "${BLUE}Global Caddy Status:${NC}"
docker ps --filter name=${CADDY_CONTAINER} --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
}
# Function to clean everything
clean() {
echo -e "${RED}WARNING: This will remove all containers, networks, and volumes!${NC}"
echo -e "${RED}All data including the database will be lost!${NC}"
read -p "Are you sure? (y/N) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
echo -e "${BLUE}Cleaning up...${NC}"
$COMPOSE_CMD down -v --remove-orphans
echo -e "${GREEN}Cleanup complete.${NC}"
else
echo "Cancelled."
fi
}
# Function to reload global Caddy config
caddy_reload() {
echo -e "${BLUE}Reloading global Caddy (${CADDY_CONTAINER})...${NC}"
if docker exec ${CADDY_CONTAINER} caddy reload --config /etc/caddy/Caddyfile 2>&1; then
echo -e "${GREEN}Caddy config reloaded!${NC}"
else
echo -e "${RED}Failed to reload Caddy. Check logs: docker logs ${CADDY_CONTAINER}${NC}"
return 1
fi
}
# Function to show access info
show_access_info() {
# Get domain from .env
if [ -f ".env" ]; then
DOMAIN=$(grep -E "^MINDERAI_DOMAIN=" .env | cut -d '=' -f2 | tr -d ' ')
fi
DOMAIN=${DOMAIN:-minderai.heywhale.com}
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN} Minder AI is now running! ${NC}"
echo -e "${GREEN}========================================${NC}"
echo ""
echo -e " Site: ${BLUE}https://${DOMAIN}${NC}"
echo -e " API Docs: ${BLUE}https://${DOMAIN}/api/docs${NC}"
echo -e " Health: ${BLUE}https://${DOMAIN}/api/health${NC}"
echo ""
echo -e "${YELLOW}HTTPS managed by global Caddy (${CADDY_CONTAINER}).${NC}"
echo ""
echo "To view logs: $0 logs -f"
echo "Caddy logs: docker logs -f ${CADDY_CONTAINER}"
echo ""
}
# Main command handler
case "${1:-}" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
rebuild)
rebuild
;;
logs)
shift
logs "$@"
;;
status)
status
;;
clean)
clean
;;
setup)
setup
;;
setup-domain)
setup_domain
;;
caddy-reload)
caddy_reload
;;
*)
usage
exit 1
;;
esac