Skip to main content

Environment Variables

Local development only. Each service reads its configuration from environment variables. Defaults are designed to work out-of-the-box for local dev.


Local Startup — .env.local

Copy from .env.local.example.

VariableDefaultDescription
WEB_PORT3100Port used by both the setup app and the normal web app
DOCS_PORT3104Port used by the local Docusaurus docs site started by ./start-local.sh
SETUP_INSTALLER_PORT3103Port used by the local setup installer service
POSTGRES_PORT5432Host port mapped to the Docker-backed Postgres container
POSTGRES_HOST127.0.0.1Hostname used when deriving the default local Prisma connection
POSTGRES_DBplayrunnerDatabase name for the standard local Postgres container
POSTGRES_USERpostgresUsername for the standard local Postgres container
POSTGRES_PASSWORDpostgresPassword for the standard local Postgres container
PUBSUB_EMULATOR_PORT8084Host port mapped to fixed container port 8085 for the Docker-backed Pub/Sub emulator
PUBSUB_EMULATOR_HOST127.0.0.1:8084Host-facing Pub/Sub emulator endpoint used by the API
LOCAL_PUBSUB_PROJECT_IDplayrunner-localProject ID used for local Pub/Sub emulator topics and subscriptions
DATABASE_URL(optional)Explicit Prisma datasource URL override for both setup defaults and the normal API startup path
VITE_DEFAULT_DATABASE_URL(optional)Override only the database URL prefilled in the setup form
VITE_DOCS_URLDerived from DOCS_PORT by defaultOptional full override for the header Docs link during repo-root local startup

./start-local.sh loads this file first, uses it to start Docker-backed services, and passes the derived defaults into the setup app. If a legacy repo-root .env still exists and .env.local does not, the script renames it to .env.local automatically.


API Server — apps/api/.env

Created from apps/api/.env.example during setup when needed, then updated by the setup installer. During normal local startup, ./start-local.sh also keeps DATABASE_URL aligned with the repo-root .env.local when you are still using the standard Docker-backed Postgres settings.

The GCP variables in this file are only needed when this API instance should trigger GCP-backed workflow executions. Standard local Docker workflows can leave them unset.

VariableDefaultDescription
PORT3011Port the Express API server listens on
DATABASE_URLDerived from repo-root .env.local by defaultPrisma datasource used for app data and workflow execution events. In the standard local flow this resolves to postgresql://postgres:postgres@127.0.0.1:<POSTGRES_PORT>/playrunner?schema=public unless you explicitly override DATABASE_URL in the repo-root .env.local.
GCP_PROJECTlocal-devGCP project ID used for Cloud Storage / Cloud Run integrations
ORCHESTRATOR_PORT3012Host port the Orchestrator Docker container is mapped to
ORCHESTRATOR_URLhttp://localhost:3012Full URL used by the API to communicate with the Orchestrator
LOCAL_ORCHESTRATOR_IMAGEplayrunner-orchestratorDocker image name for the local Orchestrator container built by start-local.sh. Remote GCP runs use the image URI template saved in the GCP integration settings instead.
EDITOR_API_URL_DOCKERhttp://host.docker.internal:3011API server URL as seen from inside Docker containers; local Playwright runners still use it to upload compressed output archives
PUBSUB_EMULATOR_HOSTInherited from repo-root .env.localHost-facing Pub/Sub emulator endpoint used by the API for local workflow event ingest
PUBSUB_EMULATOR_HOST_DOCKERhost.docker.internal:<PUBSUB_EMULATOR_PORT>Container-facing Pub/Sub emulator endpoint injected into local Orchestrator and Playwright runner containers
LOCAL_PUBSUB_PROJECT_IDplayrunner-localProject ID used by the API when creating local emulator topics and subscriptions
PLAYRUNNER_CREDENTIAL_ENCRYPTION_KEYSGenerated locallyJSON object mapping positive integer versions to base64-encoded 32-byte keys. Used to encrypt integration and cloud credential secrets at rest.
PLAYRUNNER_CREDENTIAL_ENCRYPTION_KEY_VERSION1 for a new local setupActive key version used for new credential writes. The matching key must exist in PLAYRUNNER_CREDENTIAL_ENCRYPTION_KEYS.
GCP_PUBSUB_WORKFLOW_EVENTS_TOPICplayrunner-workflow-eventsPub/Sub topic name used for workflow execution events. Local runs create/use this topic in the emulator; GCP runs use the managed GCP topic created by Terraform.
GCS_BUCKET_PREFIX(required for GCP)Required only for GCP-backed workflow execution. Prefix used when the API creates per-workflow GCS output buckets before triggering Cloud Run.
GCS_PROJECT_ID(optional fallback for GCP)Optional fallback project for GCS clients when a selected project is not supplied by the GCP workflow request.

Remote GCP runner settings such as Cloud Run region, Orchestrator service name, Orchestrator min/max instances, CPU idle policy, and generated image URI templates are stored in the GCP connection config, not in apps/api/.env.

./start-local.sh creates a random credential-encryption key in apps/api/.env before starting the API when no keyring exists, and retains it across restarts. Do not commit this file or replace the key while saved connections still depend on it: without the matching version, the API cannot decrypt those credentials. Production and shared environments must inject and back up their own stable keyring.


Web App — apps/frontend/.env

Optional. The standard local flow does not require this file.

VariableDefaultDescription
VITE_API_URLhttp://127.0.0.1:3011Target for the Vite dev-server proxy (/api/* and /outputs/*) when you run the frontend outside ./start-local.sh
VITE_SETUP_INSTALLER_URLhttp://127.0.0.1:3103Target for the Vite dev-server proxy (/setup-api/*) when you run the setup app outside ./start-local.sh
VITE_DOCS_URLhttps://docs.playrunner.devTarget for the header Docs link when you run the frontend outside ./start-local.sh
GEMINI_API_KEY(empty)API key for Gemini AI features; injected at runtime in production
APP_URL(empty)Self-referential URL; not needed for local dev

When you use ./start-local.sh, it exports the correct local proxy targets automatically, so this file is only needed for standalone frontend debugging.


Orchestrator — apps/runners/orchestrator/.env

This file is not used when the Orchestrator runs as a Docker container (all variables are injected via docker run -e flags by the API). It is provided as a reference for running the Orchestrator directly on the host during debugging.

VariableDefaultDescription
PORT3012Port the Orchestrator Express server listens on when you run it directly against the standard local API settings
EDITOR_API_URLhttp://localhost:3011API server URL used by local runners for output archive uploads
ORCHESTRATOR_EXECUTOR_TIMEOUT_MS300000Positive-integer timeout in milliseconds for one package-owned node executor. The default is five minutes. The current API-managed local container uses the default unless you inject an override into a custom launch.
PUBSUB_EMULATOR_HOST(optional)Container-facing Pub/Sub emulator endpoint when running the Orchestrator locally against the local event bus
GCP_PUBSUB_WORKFLOW_EVENTS_TOPICplayrunner-workflow-eventsPub/Sub topic name used for workflow execution events
GCP_PROJECTlocal-devGCP project ID used for Cloud Storage / Cloud Run integrations
PLAYWRIGHT_IMAGE_BASEplayrunner-playwright-runnerBase Docker image prefix for Playwright runner containers; the orchestrator appends -typescript or -python
GCP_CLOUD_RUN_API_BASE_URL(required for GCP)Cloud Run API base URL used to create/run Playwright jobs
GCP_CLOUD_RUN_LOCATION(required for GCP)Cloud Run region for GCP Playwright jobs
GCP_PLAYWRIGHT_IMAGE_URI_TEMPLATE(required for GCP)URI template for already-pushed Playwright runner images that Cloud Run Jobs can pull. Supports {projectId}, {runtime}, and {version}.
GCP_PLAYWRIGHT_JOB_NAME_TEMPLATEplayrunner-{runtime}Optional Cloud Run job name template; supports {runtime}, {version}, {cpu}, {memory}, and {nodeId}. If {nodeId} is omitted, Playrunner appends a stable node suffix so sibling Playwright nodes can run in parallel instead of sharing one Cloud Run Job.

Playwright Runner

The Playwright runner does not use a .env file. Its entire configuration is passed as a single JSON-encoded string in the PAYLOAD environment variable, injected by the Orchestrator when it runs docker run.

PAYLOAD Structure

{
"data": {
"repository": "org/repo-name",
"branch": "main",
"folder": "e2e/",
"action": "clone",
"executionAuthToken": "signed-per-execution-secret",
"testScript": null,
"nodeId": "node-abc123",
"testId": "550e8400-e29b-41d4-a716-446655440000",
"editorApiUrl": "http://host.docker.internal:3011",
"eventTransport": {
"type": "gcp_pubsub",
"projectId": "playrunner-local",
"topicName": "playrunner-workflow-events"
},
"runnerControl": {
"controlSubscriptionName": "projects/playrunner-local/subscriptions/playrunner-runner-control-...",
"statusSubscriptionName": "projects/playrunner-local/subscriptions/playrunner-runner-status-...",
"topicName": "playrunner-workflow-events",
"type": "gcp_pubsub"
}
},
"github": {
"accessToken": "gha_...",
"refreshToken": "ghr_...",
"clientId": "...",
"clientSecret": "..."
}
}

eventTransport and runnerControl use the same payload shape for local Docker and GCP. Local Docker varies only by environment: PUBSUB_EMULATOR_HOST points the Pub/Sub client at the emulator. GCP omits that emulator variable and uses the managed Pub/Sub API. The control/status subscriptions are polled with non-blocking Pub/Sub pulls; the polling interval is owned by Playrunner rather than by Pub/Sub long-poll timing.

The API constructs the github runner settings from the encrypted server-side connection immediately before execution. This payload is sent only to the relevant runner; it is not the public integration response used by the browser. Repository and branch dropdowns call the GitHub package API and receive only non-secret metadata.

The runner also receives these additional environment variables:

VariableDescription
GCP_PROJECTGCP project ID (local-dev)
PUBSUB_EMULATOR_HOSTPub/Sub emulator endpoint for local Docker workflow runs
Any user-defined env varsInjected from the Environment node's configured variables

How Variables Flow Through the Stack

.env.local
└─ PUBSUB_EMULATOR_HOST → API local Pub/Sub ingest endpoint
└─ LOCAL_PUBSUB_PROJECT_ID → local emulator project ID

.env (API)
└─ DATABASE_URL → Prisma + workflow event storage
└─ EDITOR_API_URL_DOCKER → passed to local runners for output uploads
└─ PUBSUB_EMULATOR_HOST_DOCKER → passed to local runner containers (-e)

Orchestrator container (env from API's docker run)
└─ GCP_PROJECT → passed to Playwright container (-e)
└─ PUBSUB_EMULATOR_HOST → passed to local Playwright container (-e)
└─ PAYLOAD (full config) → passed to Playwright container (-e)