openpencil/docker/entrypoint.sh
Vitali sharp8n c6a65c4878 feat(web): ship the Vue editor web build with online font providers
- Add Dockerfile.web-vue + docker/ container: static SPA on :3100 and the
  MCP Streamable-HTTP server on :7600 in one image, replacing the retired
  Rust web host used by the w4c iframe integration
- Allow online font providers (Google Fonts, Fontsource, Bunny, Fontshare)
  to load in the browser via native CORS-enabled fetch instead of gating
  them on the Tauri fetch proxy
- Rename webFontProvidersRequireDesktopApp to webFontLoadFailed and reword
  the toast for connection failures; drop the unconditional toast from the
  font family picker
- Support OPENPENCIL_MCP_HOST so the MCP server binds 0.0.0.0 in containers
2026-08-22 00:33:54 +03:00

61 lines
2.3 KiB
Bash
Executable file

#!/bin/sh
# Entrypoint for the OpenPencil Vue container: runs the static SPA server on
# :3100 and the @open-pencil/mcp Streamable-HTTP server on :7600 in the same
# container. Forwards SIGTERM/SIGINT to both so docker stop is clean.
# POSIX sh only (no `wait -n`) — the runtime image is Alpine/dash.
set -eu
WEB_PORT="${OPENPENCIL_WEB_PORT:-3100}"
MCP_PORT="${OPENPENCIL_MCP_PORT:-7600}"
# The MCP server creates a Unix socket + discovery file by default. In the
# container we direct them under /data (writable volume) so the socket never
# collides with /run/user/... and documents land on the persisted volume.
export OPENPENCIL_MCP_ROOT="${OPENPENCIL_MCP_ROOT:-/data}"
export OPENPENCIL_MCP_SOCKET="${OPENPENCIL_MCP_SOCKET:-/data/mcp.sock}"
export OPENPENCIL_MCP_DISCOVERY_PATH="${OPENPENCIL_MCP_DISCOVERY_PATH:-/data/mcp.json}"
export OPENPENCIL_MCP_CORS_ORIGIN="${OPENPENCIL_MCP_CORS_ORIGIN:-}"
# Bind MCP on all interfaces so sibling containers (chatapi) can reach it by
# service name (openpencil:7600), not just via localhost port-forwarding.
export OPENPENCIL_MCP_HOST="${OPENPENCIL_MCP_HOST:-0.0.0.0}"
mkdir -p "$OPENPENCIL_MCP_ROOT" "$(dirname "$OPENPENCIL_MCP_SOCKET")" "$(dirname "$OPENPENCIL_MCP_DISCOVERY_PATH")"
echo "[openpencil] starting static SPA on :${WEB_PORT} and MCP on :${MCP_PORT}"
# Static SPA.
OPENPENCIL_WEB_PORT="$WEB_PORT" bun static-server.mjs &
WEB_PID=$!
# MCP server (Streamable HTTP at /mcp). Bun runs the node-targeted bin.
PORT="$MCP_PORT" bun packages/mcp/bin/openpencil-mcp-http.js &
MCP_PID=$!
shutdown() {
echo "[openpencil] shutting down (MCP=$MCP_PID, web=$WEB_PID) ..."
kill -TERM "$MCP_PID" "$WEB_PID" 2>/dev/null || true
exit 0
}
trap shutdown TERM INT
# Wait for both processes; stop the container when either exits.
STATUS=0
while :; do
WEB_ALIVE=0; MCP_ALIVE=0
kill -0 "$WEB_PID" 2>/dev/null && WEB_ALIVE=1
kill -0 "$MCP_PID" 2>/dev/null && MCP_ALIVE=1
if [ "$WEB_ALIVE" = "0" ] || [ "$MCP_ALIVE" = "0" ]; then
STATUS=1
break
fi
# Poll every second; a SIGTERM/SIGINT wakes the loop via the trap's exit.
sleep 1
done
echo "[openpencil] a child process exited; stopping the container"
kill -TERM "$MCP_PID" "$WEB_PID" 2>/dev/null || true
wait "$MCP_PID" 2>/dev/null || true
wait "$WEB_PID" 2>/dev/null || true
exit "$STATUS"