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.