name: qloo-design-demo services: app: build: context: .. dockerfile: deploy/Dockerfile args: KIRO_RELEASE_CHANNEL: ${KIRO_RELEASE_CHANNEL:-stable} KIRO_EXPECTED_VERSION: ${KIRO_EXPECTED_VERSION:-} # The build stops on a Kiro major version other than this one; set it empty to accept any. KIRO_EXPECTED_MAJOR: ${KIRO_EXPECTED_MAJOR-2} MOUSA_COMMIT: ${MOUSA_COMMIT:-} image: qloo-design-demo:local platform: linux/amd64 init: true restart: unless-stopped # Loopback by default, for Caddy on the same host. Behind CloudFront with no domain, DEMO_BIND=0.0.0.0 lets it reach # the ports, and the instance's security group admits only CloudFront's origin-facing addresses. ports: - "${DEMO_BIND:-127.0.0.1}:${DEMO_PORT:-8787}:8787" - "${DEMO_BIND:-127.0.0.1}:${DEMO_PREVIEW_PORT:-8788}:8788" environment: HOST: 0.0.0.0 PORT: "8787" PREVIEW_PORT: "8788" PUBLIC_PREVIEW_BASE_URL: ${PUBLIC_PREVIEW_BASE_URL:?Set the browser-reachable preview origin} NODE_ENV: production DEMO_ACCESS_TOKEN: ${DEMO_ACCESS_TOKEN:?Set a private review access token before starting the container} KIRO_API_KEY: ${KIRO_API_KEY:-} KIRO_MODEL: ${KIRO_MODEL:-} KIRO_EFFORT: ${KIRO_EFFORT:-medium} QLOO_API_KEY: ${QLOO_API_KEY:-} QLOO_API_BASE_URL: ${QLOO_API_BASE_URL:-https://hackathon.api.qloo.com} KIRO_RUN_TIMEOUT_MS: ${KIRO_RUN_TIMEOUT_MS:-900000} # Recorded jobs copied into the volume count toward this limit too. MAX_JOBS: ${MAX_JOBS:-30} DATA_DIR: /data/jobs # No Codex here: the Studio offers no image generator, and plans make imagery without one. MOUSA_ENVIRONMENT: hosted PRODUCTION_STAGES: ${PRODUCTION_STAGES:-on} MOUSA_CAPTURE: ${MOUSA_CAPTURE:-auto} # Empty keeps Chromium's own sandbox, which the seccomp profile below lets it start. Read docs/aws-deployment.md # before setting 1: the container is then the only boundary around the captured pages. MOUSA_CAPTURE_NO_SANDBOX: ${MOUSA_CAPTURE_NO_SANDBOX:-} # The public site: the vote's ballots and the try's access are signed with SITE_SECRET. One proxy stands in # front (CloudFront or Caddy), so the client's address is the last one in X-Forwarded-For; 2 for both. SITE_SECRET: ${SITE_SECRET:?Set a long random SITE_SECRET for the vote and the try} TRUST_PROXY: ${TRUST_PROXY:-1} # The app's public address, such as https://d111111abcdef8.cloudfront.net, which forms may post from when the # proxy sends its own Host. PUBLIC_APP_BASE_URL: ${PUBLIC_APP_BASE_URL:-} SITE_REPOSITORY_URL: ${SITE_REPOSITORY_URL:-} # The jury's live try; empty keeps it closed unless TRY_ACCESS is open, which asks for no code. Two first steps # and one pair (two Kiro sessions) run at a time. TRY_ACCESS_CODE: ${TRY_ACCESS_CODE:-} TRY_ACCESS: ${TRY_ACCESS:-code} TRY_ARMS_PARALLEL: ${TRY_ARMS_PARALLEL:-on} TRY_QLOO_BUDGET: ${TRY_QLOO_BUDGET:-24} # Optional caps on the server's own day for the try (first steps, pairs, Kiro credits); all off at 0, the default. TRY_DAILY_RUNS: ${TRY_DAILY_RUNS:-0} TRY_DAILY_PAIRS: ${TRY_DAILY_PAIRS:-0} TRY_DAILY_CREDITS: ${TRY_DAILY_CREDITS:-0} # A finished try older than this keeps its record, reports and designs; its Kiro homes and session streams go. TRY_PRIVATE_RETENTION_DAYS: ${TRY_PRIVATE_RETENTION_DAYS:-14} # The longer side of a review capture handed to the model; empty is 1024 pixels on a hosted server. MOUSA_CAPTURE_INLINE_SIDE: ${MOUSA_CAPTURE_INLINE_SIDE:-} # One JSON object a line for the log collector, with each request's route pattern (never an id or a token). LOG_FORMAT: ${LOG_FORMAT:-json} REQUEST_LOG: ${REQUEST_LOG:-on} # The Studio's own paid job runs take no new work here; their recorded jobs stay readable, and /mcp and the job # bridge are closed. LEGACY_JOBS: ${LEGACY_JOBS:-off} volumes: - demo-data:/data read_only: true tmpfs: - /tmp:rw,noexec,nosuid,size=1g,uid=1000,gid=1000 # Chromium's renderer uses shared memory beyond Docker's 64 MB default; two arms may capture at once. shm_size: 512m cap_drop: - ALL security_opt: - no-new-privileges:true # Docker's default profile with what Chromium's sandbox needs: clone may create namespaces, unshare and chroot # are allowed (scripts/build-seccomp.mjs, deploy/seccomp-chromium.NOTICE). - seccomp=./seccomp-chromium.json # Threads count toward this limit: a headless Chromium alone runs well over a hundred, and a pair runs two Kiro # sessions, each with Moƻsa's server and its captures, beside two first steps. pids_limit: 1024 mem_limit: 6g cpus: 2.0 stop_grace_period: 20s volumes: demo-data: