Files
book-tac/entrypoint.sh
T

111 lines
4.4 KiB
Bash
Executable File

#!/bin/sh
set -e
# ---- OpenCode agent server (background, best-effort) ----
# Start `opencode serve` inside the same container so the deployed tac-app can
# reach it on :4096, in the SAME working directory (/app) — sharing
# opencode.json, the skill library and .opencode/. The browser talks to it via
# the app's OPENCODE_BASE_URL; --cors must allow the app's own origin.
#
# opencode MUST NOT gate app startup. It used to: the entrypoint blocked on an
# unbounded probe, so when opencode's HTTP layer accepted the TCP connection
# but never answered (slow MCP cold-start) the curl hung forever, the container
# never listened on :3000, Coolify's healthcheck failed, and the site stayed
# down until `next start` was started manually in the terminal.
OPENCODE_PORT="${OPENCODE_PORT:-4096}"
OPENCODE_HOSTNAME="${OPENCODE_HOSTNAME:-0.0.0.0}"
cors_origins=""
cors_args=""
add_cors() {
for existing in $cors_origins; do
[ "$existing" = "$1" ] && return
done
cors_origins="$cors_origins $1"
cors_args="$cors_args --cors $1"
}
if [ -n "${OPENCODE_CORS:-}" ]; then
for origin in $(echo "$OPENCODE_CORS" | tr ',' ' '); do
[ -n "$origin" ] && add_cors "$origin"
done
else
for origin in "http://localhost:3000" "https://localhost:3000" \
"${BETTER_AUTH_URL:-}" "${APP_URL:-}"; do
[ -n "$origin" ] && add_cors "$origin"
done
fi
echo "> Starting opencode serve on :$OPENCODE_PORT (auto-restart; log: /tmp/opencode-serve.log) ..."
(
while :; do
# shellcheck disable=SC2086 # intentional word splitting for --cors flags
opencode serve --hostname "$OPENCODE_HOSTNAME" --port "$OPENCODE_PORT" $cors_args \
|| echo "> opencode serve exited ($?) — restarting in 2s ..."
sleep 2
done
) >/tmp/opencode-serve.log 2>&1 &
OPENCODE_PID=$!
# Best-effort readiness probe: bounded (10s) and every curl capped with
# --max-time, so a half-open listen can never stall the container again. If
# opencode is slow or down, the app still starts — agent features just degrade.
i=0
while [ "$i" -lt 10 ]; do
if curl -sS --max-time 2 -o /dev/null "http://127.0.0.1:$OPENCODE_PORT/"; then
echo "> opencode serve ready on :$OPENCODE_PORT (pid $OPENCODE_PID)"
break
fi
i=$((i + 1))
sleep 1
done
if [ "$i" -ge 10 ]; then
echo "> WARNING: opencode serve not ready after 10s — continuing anyway (tail -f /tmp/opencode-serve.log)"
fi
# ---- Experiments submodule (git lineage) ----
# The `experiments` submodule lives in the ephemeral container layer — it is
# re-created at runtime by `trace.sh init` and is wiped on every redeploy. Ensure
# it exists on each boot so /rd/graph and trace.sh work right after a deploy.
# Idempotent (validates/creates against $GIT_REPO_URL) and best-effort: never
# gate app startup.
if [ -n "${GIT_REPO_URL:-}" ] && [ -n "${GIT_USER:-}" ]; then
if [ -f /app/tac-qlib/skills/tac-qlib-custom/lib/git_exp.sh ]; then
(
cd /app
GIT_REPO_URL="$GIT_REPO_URL" GIT_USER="$GIT_USER" GIT_PASS="${GIT_PASS:-}" \
bash tac-qlib/skills/tac-qlib-custom/lib/git_exp.sh ensure_repo >/dev/null 2>&1 \
&& GIT_REPO_URL="$GIT_REPO_URL" GIT_USER="$GIT_USER" GIT_PASS="${GIT_PASS:-}" \
bash tac-qlib/skills/tac-qlib-custom/lib/git_exp.sh ensure_base main >/dev/null 2>&1
) || echo "> WARNING: could not ensure experiments submodule — run trace.sh init in the container"
fi
fi
# Default: serve HTTP with `next start` (production mode).
if [ "${SERVER_TLS:-false}" != "true" ]; then
exec node node_modules/next/dist/bin/next start tac-app
fi
# ---- HTTPS mode (self-signed certificate) ----
# Set SERVER_TLS=true to serve the app over HTTPS. A self-signed cert is
# generated on first start and kept under TLS_DIR; override TLS_KEY / TLS_CERT
# to mount your own certificates.
TLS_HOST="${TLS_HOST:-localhost}"
TLS_DIR="${TLS_DIR:-/tmp/tls}"
TLS_KEY="${TLS_KEY:-$TLS_DIR/key.pem}"
TLS_CERT="${TLS_CERT:-$TLS_DIR/cert.pem}"
if [ ! -s "$TLS_KEY" ] || [ ! -s "$TLS_CERT" ]; then
echo "> Generating self-signed certificate for $TLS_HOST ..."
echo "> (Browsers will warn ERR_CERT_AUTHORITY_INVALID. For a trusted cert, generate one with"
echo "> mkcert on the host and mount it via TLS_KEY/TLS_CERT.)"
mkdir -p "$TLS_DIR"
openssl req -x509 -newkey rsa:2048 -nodes \
-keyout "$TLS_KEY" -out "$TLS_CERT" -days 825 \
-subj "/CN=$TLS_HOST" \
-addext "subjectAltName=DNS:localhost,DNS:$TLS_HOST,IP:127.0.0.1" \
>/dev/null 2>&1
fi
export TLS_KEY TLS_CERT TLS_HOST
exec node /app/tls-server.cjs