PHP SDK guide

Deployment

Deploy the web client, worker process, and runtime as separate roles. Keep task queue routing and protocol compatibility observable during every rollout.

Cloud

Cloud provisioning returns a namespace runtime URL and role credentials. Configure each process from secrets rather than baking credentials into the image:

DURABLE_WORKFLOW_RUNTIME_URL=https://provisioned-runtime.example/api/runtime/v1/namespaces/runtime-id
DURABLE_WORKFLOW_NAMESPACE=orders-production
DURABLE_WORKFLOW_CLIENT_TOKEN=...
DURABLE_WORKFLOW_WORKER_TOKEN=...

Deploy web/API processes with the client role. Deploy worker processes with the worker role and only the application dependencies required by their task queues. Treat the provisioned runtime URL as opaque; retain its path prefix and let the SDK append /api.

Self-hosted Server

Use the Server image qualified by this SDK release:

export DW_SERVER_IMAGE="$(
  curl -fsSL https://php.durable-workflow.com/quickstart-contract.json \
    | php -r '$contract = json_decode(stream_get_contents(STDIN), true, 512, JSON_THROW_ON_ERROR); echo $contract["runtime_targets"]["server"]["image"];'
)"
docker pull "$DW_SERVER_IMAGE"

Production Server deployment also needs durable database storage, explicit authentication, bootstrap/migrations, readiness checks, queue-processing roles, TLS at the ingress boundary, backups, and retention policy. Follow the self-hosted Server guide rather than copying the single-container development topology into production.

Package the PHP worker

A minimal production image should:

  1. install Composer dependencies with --no-dev --prefer-dist --classmap-authoritative;
  2. include pcntl for managed signal handling;
  3. run one foreground worker command;
  4. expose no HTTP port unless the container also owns a separate health process;
  5. identify the application release through buildId.

Do not use the SDK repository's main branch as a production Composer source. Install durable-workflow/sdk:^3.18 to follow the supported 3.18 release line, then commit the resolved version in composer.lock.

Roll out compatible workers

Start new workers before draining the old pool. Keep old and new builds registered only when both can replay the histories routed to that queue. If a change is not replay-compatible, use a new task queue or a worker build-routing plan rather than hoping restarts choose the right code. Deploy each release atomically, as a new image or release directory, and restart workers onto it. Do not replace workflow source files under a running worker: condition-wait replay identity reads the deployed source, so an in-place swap can raise a false replay mismatch.

A new queue is not a migration of existing runs or activities. Previously scheduled activities, delayed retries and repaired tasks retain their recorded queue. Passive runs and continuation chains can still need old workers. Deploy the new pool and routing first, then keep compatible old pools available until their dependencies are accounted for and new work no longer creates them. An empty ready-task count or a fresh registration is not proof of safe retirement. Use the recorded-queue procedure and existing run/queue diagnostics. Repair does not relocate work or extend its original total deadline. Server #519 tracks the separate guarded retirement capability.

Preserve workflow entry arguments

Recorded start input must still bind to the deployed workflow entry method. Adding a required parameter or changing its type can prevent the method from starting, before a version branch inside it can run. The worker reports WorkflowEntryArgumentsMismatch as a nonterminal workflow-task replay refusal, with reason workflow_entry_arguments_mismatch. It leaves the original run, input, history and deadlines intact.

Restore a compatible entry method and use the runtime's run-scoped repair operation to resume the same run. Inspect the refused task before repairing it; repeated incompatible deployments do not fix its input. A compatible optional parameter is allowed. A TypeError thrown after valid entry binding remains an application failure, rather than being relabelled as a deployment mismatch.

Readiness and shutdown

Runtime readiness, worker admission, and process liveness are different signals:

On termination, stop accepting tasks, allow the active synchronous task to settle, then let the process exit. See graceful shutdown.

Compatibility floor

This portal follows the 3.18 SDK and 2.5 Server lines with worker protocol 1.20. Confirm the live runtime's discovery response during deployment.