Files
copilotkit__copilotkit/showcase/scripts/dev-local.sh
Atai Barkai 099c105272 feat(showcase): Docker-based local dev for Railway parity
Adds a single command to spin up the exact image Railway deploys,
for any of the 17 showcase packages, with a single shared .env:

  ./showcase/scripts/dev-local.sh up [<slug> ...]   # all if empty
  ./showcase/scripts/dev-local.sh down|build|logs|ps|ports

Pieces:
- `docker-compose.local.yml` with a service per package. Ports come
  from `shared/local-ports.json` (langgraph-python -> 3100, ...).
- `.env.example` as a commit-safe template. Real `.env` is gitignored
  and fed to every container via `env_file`, so keys (OPENAI_API_KEY,
  etc.) live in one place.
- `dev-local.sh` wraps `docker compose` and handles the
  `shared_python/` / `shared_typescript/` staging step that CI does
  before `docker build` (see showcase_deploy.yml).
- Staged `shared_*` dirs added to .gitignore.

Shell wiring:
- `shell/next.config.ts` reads `shared/local-ports.json` when
  `SHOWCASE_LOCAL=1` is set and injects it as a public env.
- `/integrations/[slug]/[demo]/preview` uses that map to iframe
  `http://localhost:<port>` instead of `integration.backend_url`.
  Per-slug; any slug not running locally falls back to Railway.
  Unset SHOWCASE_LOCAL -> prod behavior, unchanged.

Full workflow + prerequisites (Colima / Docker Desktop) documented in
showcase/README.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 17:37:37 -07:00

73 lines
1.9 KiB
Bash
Executable File

#!/usr/bin/env bash
# Run the Railway-equivalent Docker image for one or more showcase packages.
# Uses showcase/docker-compose.local.yml. API keys come from showcase/.env.
#
# Usage:
# scripts/dev-local.sh up [<slug> ...] # empty = all
# scripts/dev-local.sh down [<slug> ...]
# scripts/dev-local.sh build [<slug> ...]
# scripts/dev-local.sh logs <slug>
# scripts/dev-local.sh ps
# scripts/dev-local.sh ports
set -euo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SHOWCASE_DIR="$(dirname "$HERE")"
COMPOSE_FILE="$SHOWCASE_DIR/docker-compose.local.yml"
ENV_FILE="$SHOWCASE_DIR/.env"
PORTS_FILE="$SHOWCASE_DIR/shared/local-ports.json"
stage_shared() {
local src_py="$SHOWCASE_DIR/shared/python"
local src_ts="$SHOWCASE_DIR/shared/typescript/tools"
for pkg_dir in "$SHOWCASE_DIR"/packages/*/; do
local pkg="$(basename "$pkg_dir")"
if [ -d "$src_py" ] && grep -q "shared_python" "$pkg_dir/Dockerfile" 2>/dev/null; then
rsync -a --delete "$src_py/" "$pkg_dir/shared_python/"
fi
if [ -d "$src_ts" ] && grep -q "shared_typescript" "$pkg_dir/Dockerfile" 2>/dev/null; then
mkdir -p "$pkg_dir/shared_typescript"
rsync -a --delete "$src_ts/" "$pkg_dir/shared_typescript/tools/"
fi
done
}
require_env() {
if [ ! -f "$ENV_FILE" ]; then
echo "Missing $ENV_FILE. Copy showcase/.env.example to showcase/.env and fill in keys." >&2
exit 1
fi
}
cmd="${1:-}"
shift || true
case "$cmd" in
up)
require_env
stage_shared
docker compose -f "$COMPOSE_FILE" up -d --build "$@"
;;
build)
stage_shared
docker compose -f "$COMPOSE_FILE" build "$@"
;;
down)
docker compose -f "$COMPOSE_FILE" down "$@"
;;
logs)
docker compose -f "$COMPOSE_FILE" logs -f "$@"
;;
ps)
docker compose -f "$COMPOSE_FILE" ps
;;
ports)
cat "$PORTS_FILE"
;;
*)
sed -n '2,13p' "${BASH_SOURCE[0]}"
exit 1
;;
esac