Repository navigation
Expand file tree
/
Copy pathstart.sh
More file actions
executable file
·132 lines (126 loc) · 5.74 KB
/
Copy pathstart.sh
File metadata and controls
executable file
·132 lines (126 loc) · 5.74 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
#!/bin/sh
# Start the complete application using only Docker and the project .env.
set -eu
cd "$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
if [ "$#" -ne 0 ]; then
echo "Usage: ./start.sh" >&2
exit 2
fi
if [ ! -f .env ]; then
(umask 077; cp .env.example .env)
echo "Created .env with installation defaults. You can configure the model in Add experiment after startup."
fi
if ! command -v docker >/dev/null 2>&1; then
echo "Install Docker Desktop (or Docker Engine with Compose v2), then run ./start.sh again." >&2
exit 1
fi
if ! docker compose version >/dev/null 2>&1; then
echo "Docker Compose v2 is required. Update Docker, then run ./start.sh again." >&2
exit 1
fi
if ! docker info >/dev/null 2>&1; then
echo "Docker is not running. Start Docker Desktop or the Docker daemon, then retry." >&2
exit 1
fi
# Bootstrap without Compose: users need no project name or DB credentials.
bootstrap_image=$(mktemp)
trap 'rm -f "$bootstrap_image"' EXIT HUP INT TERM
if ! sh deployment/build-service.sh --bootstrap "$bootstrap_image"; then
echo "Could not build the installation preparer. Existing services were not changed." >&2
exit 1
fi
if ! docker run --rm --user "$(id -u):$(id -g)" --mount "type=bind,source=$(pwd),target=/project" "$(cat "$bootstrap_image")" python -m memstara.installation /project; then
echo "Could not prepare local installation settings. Do not delete existing data volumes." >&2
exit 1
fi
# Installation settings come from .env, including an automatically selected port.
unset MEMSTARA_WEB_PORT
preparer_image=$(cat "$bootstrap_image")
if ! sh deployment/select-web-port.sh "$preparer_image"; then
echo "Could not select a web port. Existing application services were not restarted." >&2
exit 1
fi
rm -f "$bootstrap_image"
# Create bind directories on the host, not through Docker Desktop's file-sharing VM.
# Resolve paths through Compose so .env interpolation and overrides stay authoritative.
mount_config=$(mktemp)
mount_paths=$(mktemp)
trap 'rm -f "$mount_config" "$mount_paths"' EXIT HUP INT TERM
if ! docker compose config --format json >"$mount_config"; then
echo "Cannot resolve Compose settings. Check COMPOSE_FILE and .env." >&2
exit 1
fi
if ! docker run --rm -i python:3.12-slim python -c "$(cat deployment/mount_directories.py)" <"$mount_config" >"$mount_paths"; then
echo "Cannot inspect bind paths. Check Docker and image availability." >&2
exit 1
fi
while IFS= read -r directory; do
if [ -e "$directory" ] && [ ! -d "$directory" ]; then
echo "Bind path is not a directory: $directory. Move the file and retry; it was not changed." >&2
exit 1
fi
if ! mkdir -p "$directory"; then
echo "Cannot create bind directory: $directory. Check host permissions." >&2
exit 1
fi
done <"$mount_paths"
echo "Checking .env and mounted inputs before building or restarting application services..."
if ! sh deployment/build-service.sh configure; then
echo "Could not build the configuration checker. Check Docker and network access." >&2
exit 1
fi
if ! docker compose run --rm --no-deps configure python /app/deployment/configure.py --check; then
echo "Preflight failed. Fix the .env fields listed above and run ./start.sh again." >&2
echo "Application services were not restarted. Do not replace .env with settings from another checkout." >&2
echo "For /host_mnt mount errors, check Docker Desktop file sharing for this checkout. Do not delete data volumes." >&2
exit 1
fi
echo "Building and starting Memstara. Existing services will restart to load .env."
echo "Finish active experiments before running this command. Saved data is retained."
# Separate service builds avoid concurrent BuildKit sessions on older Docker Desktop.
# Finish every image before replacing application containers.
for service in control initialize api web; do
if ! sh deployment/build-service.sh "$service"; then
echo "Image build failed. Existing services were not restarted." >&2
exit 1
fi
done
startup_log=$(mktemp)
trap 'rm -f "$mount_config" "$mount_paths" "$startup_log"' EXIT HUP INT TERM
startup_attempt=0
while :; do
if docker compose up -d --no-build --force-recreate >"$startup_log" 2>&1; then
cat "$startup_log"
break
fi
cat "$startup_log" >&2
startup_attempt=$((startup_attempt + 1))
# A different process can claim the tested port while images are building.
if [ "$startup_attempt" -lt 3 ] && grep -Eiq \
'address already in use|port is already allocated|port.*already.*use' "$startup_log"; then
if sh deployment/select-web-port.sh "$preparer_image"; then
continue
fi
fi
echo "Startup failed. Correct the reported error, then run ./start.sh again." >&2
echo "Inspect: docker compose logs --tail=80 configure initialize control api web" >&2
exit 1
done
# Check both backends through the same proxy the browser uses, not just containers.
echo "Checking the web application and backend connections..."
attempt=0
until docker compose exec -T web sh -c \
'wget -q -T 5 -O /dev/null http://127.0.0.1/ && wget -q -T 5 -O /dev/null http://127.0.0.1/control/health && wget -q -T 5 -O /dev/null http://127.0.0.1/api/discovery/questions' >/dev/null 2>&1; do
attempt=$((attempt + 1))
if [ "$attempt" -ge 30 ]; then
echo "Services started, but application readiness could not be confirmed." >&2
echo "Inspect: docker compose ps -a" >&2
echo "Inspect: docker compose logs --tail=80 configure initialize control api web" >&2
exit 1
fi
sleep 2
done
address=$(docker compose port web 80)
printf '\nMemstara is ready: http://%s/\n' "$address"
echo "You can close this terminal. To stop: docker compose stop"
echo "No experiment or paid model request was started."