Run EncodeFlow locally

Bring up the infrastructure, start the control plane, connect a worker, and submit a first transcoding job. The examples assume the Manager is available at http://localhost:4400 and the Admin console at http://localhost:4500.

Prerequisites

  • Node.js 24 and Corepack
  • Yarn 4.18 or newer
  • Docker with Compose
  • FFmpeg and ffprobe on the Worker host
  • Enough local disk space for the Worker spool and active media

1. Install dependencies

From the repository root:

corepack enable
yarn install

Use Nx for every workspace task so project dependencies and generated TypeScript references stay synchronized.

2. Configure infrastructure

Create the local Compose environment and start PostgreSQL, NATS, MinIO, and the observability stack:

cp docker/.compose.env.sample docker/.compose.env
docker compose up -d postgres nats minio otel-collector tempo prometheus loki grafana

The sample environment is for local development. Rotate every token, password, and signing secret before using a shared environment.

3. Apply database migrations

Populate apps/manager/.env, set TRANSCODE_CPU_ONLY=true for a CPU-only local installation, then apply the committed TypeORM migrations. The Manager deliberately does not synchronize the schema or run migrations during startup.

yarn nx run @encode-flow/manager:migration:run

4. Start the Manager

yarn nx run @encode-flow/manager:serve

Confirm both probes. Liveness only checks the process; readiness also verifies PostgreSQL and NATS.

curl --fail http://localhost:4400/api/health/live
curl --fail http://localhost:4400/api/health/ready

5. Start a Worker

Enroll the Worker with a one-time Manager enrollment token as described in the Worker guide, then run:

yarn nx run @encode-flow/worker:serve

The Worker probes FFmpeg capabilities during registration. The CPU-only Manager setting dispatches transcoding work to the certified CPU path. Set the Worker profile capacity cap to one job when all apps share a machine. The Worker receives storage and work-directory settings in its Manager lease.

6. Open the Admin console

Copy apps/admin/.env.sample to apps/admin/.env and configure the Admin OIDC client. Its access token must have the dedicated Admin audience configured as OIDC_OPERATIONS_ADMIN_AUDIENCE on the Manager. Restrict issuance of that audience to authorized operators in the identity provider.

yarn nx run @encode-flow/admin:dev

Open http://localhost:4500 and sign in. The Admin server proxies protected Manager operations and event requests; the browser never connects directly to the Manager, PostgreSQL, or NATS.

7. Submit a job

curl --request POST http://localhost:4400/api/v1/operations/jobs \
  --header 'authorization: Bearer ADMIN_ACCESS_TOKEN' \
  --header 'content-type: application/json' \
  --data '{
    "projectId": "c16e77c7-27d3-4b6b-9d93-4bd57b7d0d4d",
    "priority": 10,
    "requirements": { "requiredCapabilities": ["libx264", "aac"] },
    "executionPlan": {
      "input": { "uri": "s3://media/input/source.mp4" },
      "outputs": [{
        "id": "main",
        "kind": "FILE",
        "container": "mp4",
        "destinationUri": "s3://media/output/video.mp4",
        "video": { "codec": "libx264", "height": 720, "preset": "medium" },
        "audio": { "codec": "aac", "bitrateKbps": 128 }
      }],
      "transforms": { "removedSegments": [], "subtitles": [], "audioTracks": [] },
      "workspace": { "rootDirectory": "/var/lib/encode-flow/work" },
      "manifestUri": "s3://media/output/manifest.json"
    }
  }'

The response is 201 Created with an initial QUEUED state. Copy its id, then inspect it with GET /api/v1/operations/jobs/{id} or follow it in the Admin console.

Next steps