commit 6493c4781f2c1213f911561eb9ee000aadd40e64
parent f39ad1e1bc9c9b91f35eba017c9e73b13fd90eb7
Author: notamitgamer2 <notamitgamer2@users.noreply.github.com>
Date: Thu, 17 Sep 2026 04:54:21 +0000
Restore Cobalt build stage; fix broken startup existence check
The old check looked for a literal file /opt/cobalt-api/src/cobalt,
but Cobalt's own CMD (node src/cobalt) resolves that path through
Node's module resolution (cobalt.js / cobalt/index.js), not a
filename with no extension - so the check could never pass and it
crashed the whole container regardless of whether Cobalt built fine.
Replaced with the existing readiness-polling loop as the real
success signal. Also re-pinned the base image to the ':11' tag
instead of a specific commit-suffixed tag for stability.
Diffstat:
| M | Dockerfile | | | 5 | +++++ |
| M | start.sh | | | 87 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- |
2 files changed, 89 insertions(+), 3 deletions(-)
diff --git a/Dockerfile b/Dockerfile
@@ -1,3 +1,5 @@
+FROM ghcr.io/imputnet/cobalt:11 AS cobalt
+
FROM node:24-bookworm-slim
WORKDIR /app
@@ -9,6 +11,9 @@ RUN apt-get update \
python3-pip \
&& rm -rf /var/lib/apt/lists/*
+# Copy the already-built Cobalt API from the official Cobalt image
+COPY --from=cobalt /app /opt/cobalt-api
+
# Install FastAPI dependencies
COPY requirements.txt .
diff --git a/start.sh b/start.sh
@@ -3,9 +3,90 @@
set -e
echo "========================================"
-echo "Starting CDN"
+echo "Starting CDN + Cobalt"
echo "========================================"
-exec uvicorn app.main:app \
+echo ""
+echo "========== COBALT ENV =========="
+echo "API_URL=${API_URL:-https://cdn.amit.is-a.dev/cobalt/}"
+echo "API_PORT=9000"
+echo "COOKIE_PATH=${COOKIE_PATH:-NOT_SET}"
+echo "================================"
+echo ""
+
+echo "Starting Cobalt..."
+
+cd /opt/cobalt-api
+
+# NOTE: we intentionally do NOT gate startup on the presence of a specific
+# file (e.g. "src/cobalt"). Cobalt's own image runs it as
+# `node src/cobalt`, which Node resolves via its module resolution
+# algorithm (src/cobalt.js or src/cobalt/index.js) - there is no literal
+# file named "cobalt" with no extension. A hard existence check on that
+# exact path previously killed the whole container on every boot even
+# when the Cobalt build itself was fine. Instead we start the process and
+# let the readiness probe below be the real success/failure signal.
+API_URL="https://cdn.amit.is-a.dev/cobalt/" \
+API_PORT=9000 \
+node src/cobalt &
+
+COBALT_PID=$!
+
+echo "Cobalt PID: $COBALT_PID"
+
+echo ""
+echo "Waiting for Cobalt to start..."
+
+COBALT_READY=0
+
+for i in $(seq 1 30); do
+ if python3 -c "import urllib.request; urllib.request.urlopen('http://127.0.0.1:9000/', timeout=1)" >/dev/null 2>&1; then
+ COBALT_READY=1
+ echo "Cobalt is ready."
+ break
+ fi
+
+ if ! kill -0 "$COBALT_PID" 2>/dev/null; then
+ echo "ERROR: Cobalt process exited unexpectedly during startup."
+ wait "$COBALT_PID"
+ exit 1
+ fi
+
+ sleep 1
+done
+
+if [ "$COBALT_READY" -ne 1 ]; then
+ echo "ERROR: Cobalt did not become ready within 30 seconds."
+ kill "$COBALT_PID" 2>/dev/null || true
+ exit 1
+fi
+
+echo ""
+echo "Starting FastAPI..."
+
+cd /app
+
+uvicorn app.main:app \
--host 0.0.0.0 \
- --port "${PORT:-8000}"
+ --port "${PORT:-8000}" &
+
+FASTAPI_PID=$!
+
+echo "FastAPI PID: $FASTAPI_PID"
+
+echo ""
+echo "========================================"
+echo "Both services started"
+echo "========================================"
+echo "Cobalt: http://127.0.0.1:9000"
+echo "FastAPI: http://0.0.0.0:${PORT:-8000}"
+echo "========================================"
+
+wait -n "$COBALT_PID" "$FASTAPI_PID"
+
+echo ""
+echo "ERROR: One of the services stopped."
+echo "Cobalt PID: $COBALT_PID"
+echo "FastAPI PID: $FASTAPI_PID"
+
+exit 1