-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstartup.sh
More file actions
executable file
·244 lines (204 loc) · 8.45 KB
/
startup.sh
File metadata and controls
executable file
·244 lines (204 loc) · 8.45 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
#!/bin/bash
# Computor startup script
# Coder support is controlled via CODER_ENABLED in .env
# Usage:
# ./startup.sh [dev|prod] [docker-compose-options]
# ./startup.sh dev # Development
# ./startup.sh dev -d # Development, detached
# ./startup.sh prod -d # Production, detached
# ./startup.sh prod --build -d # Production, rebuild images
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Default values
ENVIRONMENT="dev"
DOCKER_ARGS=""
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
dev|development)
ENVIRONMENT="dev"
shift
;;
prod|production)
ENVIRONMENT="prod"
shift
;;
*)
# Collect remaining arguments for docker-compose
DOCKER_ARGS="$DOCKER_ARGS $1"
shift
;;
esac
done
echo -e "${GREEN}=== Computor Startup Script ===${NC}"
echo -e "Environment: ${YELLOW}$ENVIRONMENT${NC}"
# Get script directory (should be project root)
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
OPS_DIR="${SCRIPT_DIR}/ops"
# Check if environment files exist
check_env_file() {
local file=$1
local template="${OPS_DIR}/environments/$(basename $file).template"
if [ ! -f "$file" ]; then
if [ -f "$template" ]; then
echo -e "${YELLOW}Warning: $file not found.${NC}"
echo -e "Creating from template. Please edit $file with your configuration."
cp "$template" "$file"
else
echo -e "${RED}Error: Neither $file nor $template found!${NC}"
echo -e "Please run ./setup-env.sh first to create environment files."
exit 1
fi
fi
}
# Check required environment files
if [ ! -f .env ]; then
echo -e "${RED}No .env file found!${NC}"
echo "Please create a .env file with your configuration."
echo "You can copy from .env.common if it exists: cp .env.common .env"
exit 1
fi
# Load environment file
echo -e "\n${GREEN}Loading environment file...${NC}"
set -a
# Load configuration from .env in root ONLY
source .env && echo " ✓ .env"
set +a
# Build docker-compose command
COMPOSE_FILES="-f ops/docker/docker-compose.base.yaml -f ops/docker/docker-compose.$ENVIRONMENT.yaml"
# Include web frontend in production (in dev, run `next dev` locally)
if [ "$ENVIRONMENT" = "prod" ]; then
COMPOSE_FILES="$COMPOSE_FILES -f ops/docker/docker-compose.web.yaml"
echo -e "Frontend: ${YELLOW}docker (production build)${NC}"
else
echo -e "Frontend: ${YELLOW}run locally with 'cd computor-web && npm run dev'${NC}"
fi
if [ "$CODER_ENABLED" = "true" ]; then
echo -e "Coder: ${YELLOW}enabled${NC}"
COMPOSE_FILES="$COMPOSE_FILES -f ops/docker/docker-compose.coder.yaml"
export POSTGRES_MULTIPLE_DATABASES="computor,coder"
else
echo -e "Coder: ${YELLOW}disabled${NC} (set CODER_ENABLED=true in .env to enable)"
export POSTGRES_MULTIPLE_DATABASES="computor"
fi
# Function to safely create directories
create_dir_if_needed() {
local dir_path="$1"
if [ ! -d "$dir_path" ]; then
echo " Creating: $dir_path"
mkdir -p "$dir_path"
fi
}
# Pre-create directories
echo -e "\n${GREEN}Creating necessary directories...${NC}"
# Database directories
create_dir_if_needed "${SYSTEM_DEPLOYMENT_PATH}/postgres"
create_dir_if_needed "${SYSTEM_DEPLOYMENT_PATH}/temporal-postgres"
create_dir_if_needed "${SYSTEM_DEPLOYMENT_PATH}/redis"
create_dir_if_needed "${SYSTEM_DEPLOYMENT_PATH}/redis-data"
# MinIO storage
create_dir_if_needed "${SYSTEM_DEPLOYMENT_PATH}/minio/data"
# Shared application directories
create_dir_if_needed "${SYSTEM_DEPLOYMENT_PATH}/shared"
for dir in documents courses course-contents defaults repositories; do
create_dir_if_needed "${SYSTEM_DEPLOYMENT_PATH}/shared/$dir"
done
# Traefik dynamic config directory
create_dir_if_needed "${SYSTEM_DEPLOYMENT_PATH}/traefik/dynamic"
# Clear stale maintenance mode config (if services are starting, maintenance is over)
if [ -f "${SYSTEM_DEPLOYMENT_PATH}/traefik/dynamic/maintenance.yaml" ]; then
echo -e " ${YELLOW}Clearing stale maintenance mode config${NC}"
rm -f "${SYSTEM_DEPLOYMENT_PATH}/traefik/dynamic/maintenance.yaml"
fi
# Coder directories (if enabled)
if [ "$CODER_ENABLED" = "true" ]; then
create_dir_if_needed "${SYSTEM_DEPLOYMENT_PATH}/coder"
create_dir_if_needed "${SYSTEM_DEPLOYMENT_PATH}/coder/home"
# Coder container runs as UID 1000 — ensure it can write to its home directory
chmod 777 "${SYSTEM_DEPLOYMENT_PATH}/coder/home" 2>/dev/null || true
create_dir_if_needed "${SYSTEM_DEPLOYMENT_PATH}/coder/registry"
create_dir_if_needed "${SYSTEM_DEPLOYMENT_PATH}/coder/templates"
# Seed default templates from repo (only copies missing ones, never overwrites)
if [ -d "${SCRIPT_DIR}/computor-coder/deployment/templates" ]; then
echo -e " ${GREEN}Seeding Coder templates...${NC}"
for tpl_dir in "${SCRIPT_DIR}/computor-coder/deployment/templates"/*/; do
tpl_name=$(basename "$tpl_dir")
if [ ! -d "${SYSTEM_DEPLOYMENT_PATH}/coder/templates/${tpl_name}" ]; then
echo " Copying template: ${tpl_name}"
cp -r "$tpl_dir" "${SYSTEM_DEPLOYMENT_PATH}/coder/templates/${tpl_name}"
else
echo " Template already exists: ${tpl_name} (skipping)"
fi
done
fi
# Auto-detect DOCKER_GID if not set (required for Coder to access Docker socket)
if [ -z "$DOCKER_GID" ]; then
echo -e "\n${GREEN}Auto-detecting Docker group ID...${NC}"
if [[ "$OSTYPE" == "darwin"* ]]; then
# macOS: get GID of docker.sock
DOCKER_GID=$(stat -f '%g' /var/run/docker.sock 2>/dev/null || echo "")
else
# Linux: get docker group ID
DOCKER_GID=$(getent group docker | cut -d: -f3 2>/dev/null || stat -c '%g' /var/run/docker.sock 2>/dev/null || echo "")
fi
if [ -n "$DOCKER_GID" ]; then
export DOCKER_GID
echo " DOCKER_GID=$DOCKER_GID"
else
echo -e "${RED}ERROR: Could not detect Docker group ID${NC}"
echo " Please set DOCKER_GID manually in your .env file"
echo " You can find it with: getent group docker | cut -d: -f3"
exit 1
fi
fi
fi
# Copy defaults if source exists
if [ -d "computor-backend/src/defaults" ]; then
echo -e "\n${GREEN}Copying default files...${NC}"
cp -r computor-backend/src/defaults/* "${SYSTEM_DEPLOYMENT_PATH}/shared/defaults/" 2>/dev/null || true
fi
# Optional: Create Keycloak directories if enabled
if [ "${KEYCLOAK_ENABLED}" = "true" ]; then
echo -e "\n${GREEN}Setting up Keycloak directories...${NC}"
create_dir_if_needed "${SYSTEM_DEPLOYMENT_PATH}/keycloak/imports"
create_dir_if_needed "${SYSTEM_DEPLOYMENT_PATH}/keycloak/themes"
# Copy Keycloak realm configuration if it exists
if [ -f "data/keycloak/computor-realm.json" ]; then
echo " Copying Keycloak realm configuration..."
cp data/keycloak/computor-realm.json "${SYSTEM_DEPLOYMENT_PATH}/keycloak/imports/"
fi
fi
# Make postgres init script executable
if [ -f "docker/postgres-init/01-create-multiple-databases.sh" ]; then
chmod +x docker/postgres-init/01-create-multiple-databases.sh
fi
# Start services
echo -e "\n${GREEN}Starting Computor services...${NC}"
echo "Command: docker compose $COMPOSE_FILES up $DOCKER_ARGS"
docker compose $COMPOSE_FILES up $DOCKER_ARGS
# Show status if running in detached mode
if [[ "$DOCKER_ARGS" == *"-d"* ]]; then
echo -e "\n${GREEN}Services status:${NC}"
docker compose $COMPOSE_FILES ps
echo -e "\n${GREEN}Service URLs:${NC}"
echo " • API: http://localhost:${API_PORT:-8000}"
echo " • Traefik: http://localhost:${TRAEFIK_HTTP_PORT:-8080}"
if [ "$ENVIRONMENT" = "prod" ]; then
echo " • Frontend: http://localhost:${TRAEFIK_HTTP_PORT:-8080}"
fi
if [ "$ENVIRONMENT" = "dev" ]; then
echo " • Temporal UI: http://localhost:${TEMPORAL_UI_PORT:-8088}"
echo " • MinIO Console: http://localhost:${MINIO_CONSOLE_PORT:-9001}"
fi
if [ "$CODER_ENABLED" = "true" ]; then
echo " • Coder: ${CODER_PROTOCOL:-https}://${CODER_DOMAIN}:${CODER_EXTERNAL_PORT:-8446}"
fi
echo -e "\n${GREEN}To stop services:${NC}"
echo " docker compose $COMPOSE_FILES down"
echo -e "\n${GREEN}To view logs:${NC}"
echo " docker compose $COMPOSE_FILES logs -f [service-name]"
fi