# docker-compose.dev.yml — Dev testability stack (no custom Dockerfile) # # Usage (from repo root): # docker compose -f packaging/docker/docker-compose.dev.yml up # # Then open http://localhost:5173 — already wired to headless, no config needed. # # Env overrides (optional, via .env or export): # OPENWORK_TOKEN — shared client token (auto-generated if unset) # OPENWORK_HOST_TOKEN — host/admin token (auto-generated if unset) # OPENWORK_WORKSPACE — host path to mount as workspace (default: ./workspace) # OPENWORK_PORT — host port to map to container :8787 (default: 8787) # WEB_PORT — host port to map to container :5173 (default: 5173) # OPENWORK_DEV_ID — unique ID for this stack (default: default) x-shared: &shared image: node:22-bookworm-slim working_dir: /app volumes: # Mount the entire repo so both services share node_modules + source - ../../:/app - pnpm-store:/root/.local/share/pnpm/store - bun-install:/root/.bun - ${OPENWORK_WORKSPACE:-./workspace}:/workspace services: headless: <<: *shared entrypoint: ["/bin/sh", "-c"] command: - | set -e # --- Ensure workspace dir is writable --- mkdir -p /workspace && touch /workspace/.keep 2>/dev/null || true # --- Install system deps --- apt-get update -qq && apt-get install -y -qq --no-install-recommends \ curl ca-certificates unzip git >/dev/null 2>&1 # --- Install bun (cached in named volume) --- export BUN_INSTALL="/root/.bun" export PATH="$$BUN_INSTALL/bin:$$PATH" if ! command -v bun >/dev/null 2>&1; then echo "[headless] Installing bun..." curl -fsSL https://bun.sh/install | bash fi # --- Enable pnpm via corepack --- corepack enable && corepack prepare pnpm@10.27.0 --activate # --- Install deps --- echo "[headless] Installing dependencies..." pnpm install --no-frozen-lockfile # --- Build Linux binaries into container-local path --- # Avoids overwriting macOS-native binaries on the host mount. export OPENWORK_SERVER_BIN="/tmp/openwork-bins/openwork-server" export OWPENBOT_BIN="/tmp/openwork-bins/owpenbot" mkdir -p /tmp/openwork-bins # --- Compile sidecars for the container architecture --- case "$(uname -m)" in x86_64|amd64) BUN_TARGET="bun-linux-x64" ;; aarch64|arm64) BUN_TARGET="bun-linux-arm64" ;; *) echo "Unsupported container architecture: $(uname -m)" >&2 exit 1 ;; esac echo "[headless] Building openwork-server binary (linux)..." cd /app/packages/server && bun build --compile --target "$$BUN_TARGET" src/cli.ts --outfile "$$OPENWORK_SERVER_BIN" echo "[headless] Building owpenbot binary (linux)..." OWPENBOT_VERSION=$$(node -p "require('/app/packages/owpenbot/package.json').version") cd /app/packages/owpenbot && bun build --compile --target "$$BUN_TARGET" src/cli.ts \ --define "__OWPENBOT_VERSION__=\"$${OWPENBOT_VERSION}\"" --outfile "$$OWPENBOT_BIN" cd /app # --- Resolve tokens --- if [ -z "$$OPENWORK_TOKEN" ]; then OPENWORK_TOKEN=$$(cat /proc/sys/kernel/random/uuid) export OPENWORK_TOKEN fi if [ -z "$$OPENWORK_HOST_TOKEN" ]; then OPENWORK_HOST_TOKEN=$$(cat /proc/sys/kernel/random/uuid) export OPENWORK_HOST_TOKEN fi # Write tokens so the web service can source them mkdir -p /app/tmp printf 'OPENWORK_TOKEN=%s\nOPENWORK_HOST_TOKEN=%s\n' \ "$$OPENWORK_TOKEN" "$$OPENWORK_HOST_TOKEN" > "/app/tmp/.dev-env-${OPENWORK_DEV_ID:-default}" echo "" echo "============================================" echo " OpenWork headless" echo " Server: http://localhost:${OPENWORK_PORT:-8787}" echo " Health: http://localhost:${OPENWORK_PORT:-8787}/health" echo " Token: $$OPENWORK_TOKEN" echo " Host token: $$OPENWORK_HOST_TOKEN" echo "============================================" echo "" exec pnpm --filter openwrk dev -- start \ --workspace /workspace \ --openwork-host 0.0.0.0 \ --openwork-port 8787 \ --openwork-token "$$OPENWORK_TOKEN" \ --openwork-host-token "$$OPENWORK_HOST_TOKEN" \ --openwork-server-bin "$$OPENWORK_SERVER_BIN" \ --owpenbot-bin "$$OWPENBOT_BIN" \ --approval auto \ --allow-external \ --no-opencode-auth \ --cors "*" ports: - "${OPENWORK_PORT:-8787}:8787" healthcheck: test: ["CMD-SHELL", "curl -sf http://localhost:8787/health || exit 1"] interval: 5s timeout: 5s retries: 30 start_period: 90s environment: CI: "true" OPENWORK_TOKEN: ${OPENWORK_TOKEN:-} OPENWORK_HOST_TOKEN: ${OPENWORK_HOST_TOKEN:-} OPENWORK_DEV_ID: ${OPENWORK_DEV_ID:-default} OPENWRK_SIDECAR_SOURCE: external web: <<: *shared depends_on: headless: condition: service_healthy entrypoint: ["/bin/sh", "-c"] command: - | set -e # --- Install system deps --- apt-get update -qq && apt-get install -y -qq --no-install-recommends \ curl ca-certificates >/dev/null 2>&1 # --- Bun + pnpm --- export BUN_INSTALL="/root/.bun" export PATH="$$BUN_INSTALL/bin:$$PATH" if ! command -v bun >/dev/null 2>&1; then curl -fsSL https://bun.sh/install | bash fi corepack enable && corepack prepare pnpm@10.27.0 --activate # --- Read token written by headless --- if [ -f "/app/tmp/.dev-env-${OPENWORK_DEV_ID:-default}" ]; then . "/app/tmp/.dev-env-${OPENWORK_DEV_ID:-default}" export VITE_OPENWORK_TOKEN="$$OPENWORK_TOKEN" fi echo "" echo "============================================" echo " OpenWork web UI" echo " URL: http://localhost:${WEB_PORT:-5173}" echo " Token: $${VITE_OPENWORK_TOKEN:-}" echo "============================================" echo "" export VITE_OPENWORK_URL="http://localhost:${OPENWORK_PORT:-8787}" export VITE_OPENWORK_PORT="${OPENWORK_PORT:-8787}" export VITE_ALLOWED_HOSTS="all" export HOST="0.0.0.0" export PORT="5173" exec pnpm --filter @different-ai/openwork-ui exec vite \ --host 0.0.0.0 \ --port 5173 \ --strictPort ports: - "${WEB_PORT:-5173}:5173" environment: OPENWORK_DEV_ID: ${OPENWORK_DEV_ID:-default} volumes: pnpm-store: name: openwork-dev-pnpm-store bun-install: name: openwork-dev-bun-install