Deployment Worker
A Deployment Worker checks out selected branches and runs operator-defined commands in long-lived preview slots for QA, demos, or staging. It is optional when slots are not used, but every slot requires a connected worker.
Slots execute repository code on the worker host. Run workers on dedicated, least-privilege machines and do not use a preview slot as a production deployment system. Deploy commands run at below-normal process priority so they do not starve the worker's own connection handling.
Deployment model
The application stores workspace, slot, template, branch, variable, and repository settings. Each worker stores only its connection and storage configuration.
| Object | Purpose |
|---|---|
| Host | A registered worker machine, its approval state, and availability. |
| Deploy template | Reusable Initial, Startup, and Shutdown commands and variables for one workspace. |
| Slot | A named deployment on a host that selects a template and supplies per-slot values. |
Deployment hosts are not restricted by workspace: any workspace can place a slot on any enabled deployment host. Restrict who can manage slots through permissions, and restrict which machines can connect through IP restrictions.
Install a worker
Install the worker with the install script by following Installation. Before installing it:
- Create a host API key of type Deploy Worker under Hosts → API Keys → New API Key.
- Protect the key as a service credential; never commit it to a repository.
- Decide which account runs deploy commands. The install script runs the worker as LocalSystem, so deploy commands have full control of the machine; on shared hosts, switch the service to a dedicated account with write access only to its storage path and the minimum rights deploy commands need.
- Permit outbound HTTPS (including WebSocket upgrade) to the Polygent server and to the required Git hosts.
- Install every runtime used by templates — Bash, PowerShell, Node.js, or Python — for the service account.
The worker reads the shipped appsettings.json beside the installed executable, overridden by appsettings.Production.json in the same folder (or environment variables such as Agent__ApiKey). Put your settings in appsettings.Production.json: upgrades replace appsettings.json and keep it. The install script writes Name, ServerId, MainServerUrl, ApiKey, and StoragePath there; add other keys as needed, for example:
{
"Agent": {
"Name": "deploy-01",
"ServerId": "deploy-01",
"MainServerUrl": "https://polygent.example.com",
"ApiKey": "<deploy-host-api-key>",
"StoragePath": "C:\\Polygent\\deploy-worker-data",
"DisableGitSslVerification": false
},
"Logging": {
"LogLevel": {
"Default": "Information"
}
}
}
| Key | Default | Requirement |
|---|---|---|
Agent:Name | empty | Display name shown on the Hosts page. |
Agent:ServerId | empty (IP fallback) | Recommended. Stable identifier, unique across all deployment workers. |
Agent:MainServerUrl | empty | HTTPS base URL of the Polygent server, reachable from the worker. |
Agent:ApiKey | empty | Active Deploy Worker host API key. |
Agent:StoragePath | worker install folder | Dedicated local path with room for repository copies and build output. Set it explicitly. |
Agent:DisableGitSslVerification | false | Opt-out of certificate verification for worker-managed Git operations (see below). |
Agent:HeartbeatIntervalSeconds | 30 | Keep the default. The server marks a host offline after about a minute without a heartbeat, so values near 60 make the host flap. |
Agent:ReconnectDelaySeconds | [1, 2, 5, 10, 30] | Reconnect backoff sequence; the last value repeats until the server is reachable. |
Logging:LogLevel:Default | Debug in the shipped file | Set to Information for production to reduce log volume. |
Git:LongRunningTimeoutSeconds | 300 | Timeout for clone, fetch, and other long Git operations. |
On-disk layout
| Path | Contents |
|---|---|
{StoragePath}/slots/{workspace}/{slot}/ | Slot checkout and build output. |
{StoragePath}/deploy-logs/ | Latest command output per slot. |
<install folder>/logs/deploy-worker-*.jsonl | Worker logs, rolled daily, 30 files kept. |
<install folder>/crash.log | Written only when the worker fails to start. |
Back up the central application and database rather than worker checkouts; slots can be redeployed.
Worker identity
Agent:ServerId is the worker's identity on the server. Because hosts are keyed on this value rather than on the worker's IP address, several workers behind one shared address (VPN or NAT) stay separate hosts, each with its own slots, status, and actions. Set it once per worker and keep it stable: reconnecting with the same value updates the existing host instead of creating a duplicate, even if the address changes.
Give every worker a different ServerId. If you omit it, the worker is identified by its IP address and a warning is logged on both sides; two workers sharing one address then collide on one host record and the second is rejected. A worker presenting a ServerId already claimed by another connected worker is also rejected.
When upgrading an existing worker that ran without ServerId, set ServerId to the IP address it previously registered with to keep its host record and slots — or leave it unset. Adding a new explicit value registers a new host; move its slots, then delete the old record.
Git certificate verification
Keep Agent:DisableGitSslVerification false or omit it whenever Git can validate the server certificate. Setting it to true disables verification for worker-managed clone, fetch, pull, push, and branch operations; it does not affect Git commands written in deploy templates or the operating-system certificate store. Disabling verification permits interception of repository content and credentials — use it only for a known internal Git server after accepting that risk. The worker logs a security warning at startup.
Restrict read access to appsettings.Production.json (the install script limits the install folder to Administrators and SYSTEM) and exclude the storage path from interactive user access. Revoke and replace the API key when a host is retired or suspected compromised.
Create a deploy template
A deploy template defines the commands a workspace allows slots to run.
- Open Workspace → Deploy Templates and create a template (requires Edit Workspaces).
- On the Variables tab, declare reusable variables; mark credentials Secret and values every slot must supply Required.
- On the Initial, Startup, and Shutdown tabs, add commands. For each command choose a script type (Bash, PowerShell, Cmd, Node.js, or Python) and a working directory — a repository or Slot root (the repository choice is hidden in single-repository workspaces).
- Mark commands users may skip as Optional step and choose whether each is Enabled by default.
- Choose whether Startup commands run Sequential or Parallel.
- Preview the template and verify paths and redaction before assigning it to a slot.
| Phase | When it runs |
|---|---|
| Initial Commands | On every Deploy and Redeploy, before Startup (for example install and build). Skipped only by watch directories. |
| Startup Commands | On Deploy, Redeploy, and Start. Sequential or parallel. |
| Shutdown Commands | Only on Stop. Redeploy stops running processes without them, and deleting a slot does not run them. |
Commands are mandatory unless Optional step is enabled. When deploying, each optional command appears as a checkbox initialized from Enabled by default; the selection applies to Initial, Startup, and Shutdown for that deployment. Redeploy presents the template defaults again.
Commands run non-interactively under the worker service account with no command timeout. Use absolute tool paths when the service account's PATH is uncertain, exit non-zero on failure, and keep commands safe to retry. A template cannot be deleted while slots use it; Clone copies a template after confirmation.
Variables and built-in tokens
Variables and built-in tokens are substituted into command text before the command runs, using {Name} syntax.
| Token | Value |
|---|---|
{WorkspaceId} | Workspace identifier. |
{SlotName} | Slot name. |
{WorkingDirectory} | Selected repository directory or slot root. |
{SlotRoot} | Root directory containing all repositories for the slot. |
{RepositoryFolder} | Selected repository folder; empty for slot-root commands. |
{StoragePath} | Worker storage path. |
{GitBranch} | Deployed branch. |
{StarterBranch} | Base branch when supplied by the deployment source. |
A template variable with the same name as a built-in token overrides it. Tokens can reference other tokens up to five levels deep; an unresolved token stays as literal text and a warning is logged. Preview does not fill in built-in tokens. Values are quoted for the selected script type.
Variables are not exported as process environment variables — they reach commands only through token substitution. Secret values are encrypted at rest and redacted from status and error output, but the command receives the clear value in its text. Do not echo secrets, and do not let untrusted users edit deploy commands.
Watch directories
Watch directories skip a command when its declared input directories have not changed since the same command last succeeded on that slot.
Paths are relative to the command's working directory and respect repository ignore rules. Leave the setting empty for commands that must always run. Do not use it for database migrations, service registration, security checks, or other required side effects.
Configure and operate a slot
A slot binds a host, workspace, template, and slot-specific values.
- On the host card, select New Slot, choose the workspace, and select a template.
- Set all required variable overrides (use Reset to return to the template default).
- Set the URL shown to users. It is informational and does not configure DNS, TLS, a reverse proxy, or a firewall.
- Deploy a session branch or a compatible set of ticket branches. The deploy dialog asks for Branch, Starter Branch, and Merge with Starter.
- Review command output (Show details) and verify the URL before handing the slot to QA.
| Slot state | Meaning |
|---|---|
| Available | Not running. Start and Deploy are available. |
| Deploying | Commands are running; progress shows the current command. |
| Running | Startup completed. Stop and Redeploy are available. |
| Stopping | Shutdown commands are running. |
| Error | A command failed; review output and redeploy. |
Available actions are Deploy / Redeploy, Start (Available only), Stop (Running only), Edit, and Delete. Slot overrides cover only the template, variable values, and URL; commands are edited on the template.
For multi-repository workspaces, every repository needs an explicit branch. When Merge with Starter is selected and the starting branch cannot be merged, the deployment continues without the merge and the user who started it receives an inbox notification.
Batch deploy
Batch deploy merges several ticket branches into one slot so QA can test them together.
- Select two or more tickets in QA Approval from the same workspace.
- Merge with Starter is mandatory and all tickets must share the same starting branch.
- A ticket whose branch fails to merge is skipped and unlinked from the slot; progress reports Merged, Skipped, and Failed per ticket and repository.
- Each ticket needs a branch in every required repository.
Offline hosts and deletion
A host is shown Offline with its last-seen time after about a minute without contact or when its connection drops. Its slots and New Slot are hidden, and it is removed from ticket slot pickers; processes already started on the worker keep running.
- Delete slot removes the slot folder without running Shutdown commands. When the host is offline, cleanup is best-effort.
- Delete host is available only while the host is offline; its slot records are removed and nothing is cleaned on the worker machine.
Security and permissions
Deployment access combines role permissions, host credentials, and network restrictions.
| Permission | Capability |
|---|---|
| View Hosts | View host and slot state. |
| Manage Hosts | Approve and manage hosts and slots and run deployment actions. |
| Manage Host API Keys | Create, rotate, revoke, and delete worker credentials. |
| Edit Workspaces | Create and edit deploy templates. |
Keep API-key management separate from routine slot operation. Review key expiry and authentication-failure diagnostics under Hosts → API Keys, remove obsolete hosts, and patch worker hosts and installed runtimes regularly.
Deploy templates are privileged code execution. Restrict template editing to trusted operators, review changes, use a non-administrator service account, isolate workers from sensitive networks, and scope repository credentials to only the repositories and operations required.
Upgrade and recovery
The worker and server must run compatible releases.
- Stop active slots or schedule an interruption.
- Back up the worker
appsettings.Production.jsonand any external state created outside the worker storage path. - Stop the Windows service, replace the installed worker files, and keep the
Agentconfiguration. - Start the service and confirm the host is online before redeploying slots.
Older worker configurations that contained local workspace or slot definitions are no longer used. Recreate those templates and slots in the UI, then remove the obsolete local configuration.
Troubleshooting
Use the Hosts page, slot command output, Windows Service Control Manager, and worker logs together.
| Symptom | Resolution |
|---|---|
| Host remains offline | Verify the service is running, Agent:MainServerUrl and TLS trust are correct, WebSocket upgrades pass the proxy, and the key is active and of Deploy Worker type. Check <install folder>/logs. |
| Host flaps between online and offline | Restore Agent:HeartbeatIntervalSeconds to 30 and check network stability to the server. |
| Registration is rejected | Enable the host if approval is required, check IP Restrictions → Deploy Workers, check for a duplicate ServerId, and confirm the license has deploy-host capacity. |
| Worker is rate-limited | Open Hosts → API Keys, review the key's usage and latest rejection reason, and fix the cause of repeated reconnects or failures. |
| Worker does not start | Read crash.log in the install folder. |
| Repository checkout fails | Verify the workspace repository URL, Git credential, branch, DNS/TLS access, and disk space. |
| Required variable error | Supply a non-empty template default or slot override, then retry. Stop remains available for cleanup. |
| Runtime is not found | Install the runtime for the service account or use its absolute executable path. |
| Command works interactively but fails as a service | Compare service-account permissions, PATH, working directory, and network/proxy access. |
| Slot fails on initial commands | Select Show details to review the full output, then run the commands manually on the host to reproduce. |
| Previous processes still hold ports after Redeploy | Redeploy does not run Shutdown commands; make Startup commands tolerate or stop a previous instance, or Stop before redeploying. |
| Slot details report that the log is unavailable | Confirm the host is online and whether a newer deployment replaced the log. |
| Batch deployment reports skipped tickets | Resolve each reported merge failure; each ticket needs a mergeable branch in every required repository. |
| URL is unreachable after success | Configure DNS, TLS, reverse proxy, application binding, and firewall rules separately; the slot URL does not create them. |
| Disk usage grows | Delete obsolete slots through the UI and monitor the storage volume. Do not manually delete an active slot folder. |
| Secret appears in output | Rotate it immediately and change the command so it does not print the value. |