TeamCity build agents: installation, agent pools, cloud profiles and licensing

A TeamCity build agent is a Java service that polls the TeamCity server for builds and runs them. You install it from the zip on your server's Agents page or with the jetbrains/teamcity-agent Docker image, set serverUrl and name in buildAgent.properties, then authorize it in the UI. For agents on demand, cloud profiles start EC2 instances or Kubernetes pods when builds queue.

TeamCity agent basics

Agents run in unidirectional mode: the agent opens every connection to the server over HTTP(S), and the server answers with commands. You do not open inbound ports on agent machines. Each agent advertises its environment as parameters (OS, JDKs, Docker, custom properties), and the server matches queued builds against them.

You self-host agents for two reasons. On TeamCity On-Premises there is no other choice; the server runs builds only on agents you provide. On TeamCity Cloud, JetBrains-hosted agents charge build credits per minute, while self-hosted agents charge a flat monthly slot and give you your own hardware, network and caches.

Prerequisites

  • Java 21 to 25 (OpenJDK or Oracle, 64-bit recommended) for TeamCity 2026.2 agents. The agent distributions with a bundled JDK ship Amazon Corretto 21. Builds can use any other JDK you install.
  • On Linux: unzip and curl or wget.
  • Outbound HTTP(S) from the agent to the server URL.
  • An agent license slot. Authorization fails without one (see Licensing).

Install an agent from the zip

In the TeamCity UI, open Agents and choose Install Build Agents. Download the zip. The minimal package fetches plugins on first start; the full package bundles them. Then on the agent host:

sudo useradd -m -s /bin/bash teamcity
sudo -iu teamcity
mkdir buildAgent && cd buildAgent
unzip ~/buildAgentFull.zip
cp conf/buildAgent.dist.properties conf/buildAgent.properties

Edit conf/buildAgent.properties:

serverUrl=https://teamcity.example.com
name=linux-builder-01
workDir=../work
tempDir=../temp
systemDir=../system

# custom parameters, available to builds and requirements
system.gpu=none
env.BUILD_REGION=eu-central

serverUrl needs the protocol. If you leave name empty, TeamCity derives it from the hostname. After the first connection the agent writes an authorizationToken into the same file; keep it if you reinstall the agent, because it ties the machine to its authorized record.

You can set the two required keys from the command line instead of editing the file:

./bin/agent.sh configure --server-url https://teamcity.example.com --name linux-builder-01
./bin/agent.sh start

agent.sh stop waits for the running build to finish, agent.sh stop force stops at once, and on Linux agent.sh stop kill kills the process. For a boot-time service, JetBrains documents a systemd unit that calls agent.sh start and agent.sh stop with RemainAfterExit=yes and SuccessExitStatus=0 143; run it as the teamcity user. On Windows, the agentInstaller.exe from the same page installs a Windows service.

Run an agent in Docker

JetBrains publishes jetbrains/teamcity-agent on Docker Hub. Map the config directory to a volume so the agent keeps its name and authorization token across restarts:

docker run -d --name teamcity-agent-01 \
  -e SERVER_URL="https://teamcity.example.com" \
  -e AGENT_NAME="docker-agent-01" \
  -v /srv/teamcity-agent-01/conf:/data/teamcity_agent/conf \
  -v /srv/teamcity-agent-01/work:/opt/buildagent/work \
  jetbrains/teamcity-agent

Optional variables: AGENT_TOKEN to start with a known authorization token, and OWN_ADDRESS / OWN_PORT (Linux only) for the address the agent binds to. Pin a tag that matches your server version instead of relying on latest.

Builds that call Docker need a daemon. The documented option is a -linux-sudo tag started with --privileged and -e DOCKER_IN_DOCKER=start, which runs Docker inside the agent container. A privileged container can take over the host, so keep these agents on dedicated machines.

Authorize the agent

A new agent appears under Agents, Unauthorized. Open it, choose Authorize, and pick the pool it should join. Until you do, the server sends it no builds. Authorization consumes an agent license. Unauthorizing an agent frees the license, which is how you rotate machines without buying more.

Agents started from a cloud profile skip this step: TeamCity authorizes them on launch while licenses are available, and removes disconnected cloud agents from the authorized list to free their slots.

Agent pools

Every agent belongs to one pool, and a project can use several pools. Builds of a project only run on agents in pools assigned to it; a project with no pools cannot run builds that need an agent. New agents land in the Default pool unless you choose another.

Typical layout:

  • general-linux: shared by most projects.
  • gpu: assigned only to ML projects.
  • deploy-prod: assigned only to the deployment project, on a network that can reach production.

Custom pools (not Default) can carry a maximum agent count. Once a pool is full, TeamCity refuses new agents for it and its cloud agents stop launching, which caps how many licenses one team's cloud profile can take.

Agent requirements

Pools decide which projects may use an agent. Requirements decide which agents can run a specific build configuration. A requirement compares an agent parameter with an operator such as exists, equals, contains, startsWith or matches. In Kotlin DSL:

object Build : BuildType({
    name = "Build"
    requirements {
        equals("teamcity.agent.jvm.os.name", "Linux")
        equals("system.gpu", "a10")
        exists("docker.server.version")
    }
})

Requirements combine with AND only. TeamCity also adds implicit requirements: a step that references %some.param% needs an agent that defines it, and a step running in a container needs Docker. If no agent qualifies, the build waits with "There are no idle compatible agents which can run this build". The build configuration's Agent Requirements tab lists compatible and incompatible agents with the reason for each.

Cloud profiles for on-demand agents

A cloud profile tells TeamCity how to start agent machines when builds queue and when to stop them. Amazon EC2, Kubernetes and VMware vSphere integrations ship with the server; Azure and Google Cloud come as plugins. Create a profile under Project Settings, Cloud Profiles.

Amazon EC2

Bake an AMI with Java and the agent installed and set to start on boot. Remove name from buildAgent.properties (TeamCity assigns unique names). You can also drop serverUrl and authorizationToken: cloud agents receive both at launch. In the profile, give TeamCity an IAM identity with ec2:RunInstances, ec2:StartInstances, ec2:StopInstances, ec2:TerminateInstances, ec2:Describe* and tag permissions. Then add images (AMI or launch template), each with an instance limit and a target pool.

Termination settings control cost. An idle timeout stops agents with no work, and the after first build finished condition gives you one build per instance. TeamCity terminates an agent only after its current build finishes. Spot instances cut cost, but AWS can reclaim them; TeamCity then fails the build and puts it back in the queue, so JetBrains advises against spot for production-critical builds.

Kubernetes

The Kubernetes profile needs the API server URL, CA certificate, a namespace and credentials (for example a service account token). The account needs get, create, list and delete on pods. For each image you pick one of three pod specifications: a single container from an image such as jetbrains/teamcity-agent, an existing Deployment as a template, or a custom pod YAML where you set CPU and memory requests. Builds that need Docker inside these pods require privileged containers or a remote builder.

Licensing: On-Premises vs TeamCity Cloud

TeamCity On-PremisesTeamCity Cloud
Included agents3 agents in Professional (free) and in EnterpriseFree trial covers up to 3 concurrent self-hosted builds
Adding capacityBuy agent licenses; each one adds one authorized agentBuy self-hosted slots at a flat 20,000 build credits per month each
What countsAuthorized agents, local or cloud, of any kindConcurrent builds on self-hosted agents
Build minutesNot meteredNot counted on self-hosted agents

On-Premises licenses form a shared pool that any authorized agent draws from. Professional also limits you to 100 build configurations, plus 10 for each agent license you buy. If you exceed your licensed agents, TeamCity shows a warning and stops new builds from starting. Cloud profiles draw from the same license count, so a profile with an instance limit of 20 needs 20 free licenses to reach full size.

On TeamCity Cloud you register self-hosted agents against your instance URL the same way as on-premises. You can connect as many as you like; the number of slots you buy caps how many builds run on them at once.

Beyond licenses you pay for the machines, the AMIs or images you maintain, and the time spent on agent upgrades (the server pushes agent updates, which restart agents between builds).

Security hardening

  • Run agents under a dedicated non-root user and use HTTPS for serverUrl.
  • Treat authorizationToken as a credential: it identifies an authorized agent.
  • Use pools to keep untrusted builds, such as pull requests from external contributors, off agents that hold deploy credentials or reach production networks.
  • Prefer one-build cloud agents for pull-request builds, so nothing a build leaves on disk reaches the next one.
  • Avoid privileged Docker-in-Docker agents on shared hosts.

Troubleshooting

Agent never shows up in the UI

Check logs/teamcity-agent.log. Most failures come from a wrong serverUrl (missing protocol, internal hostname), a proxy, or an untrusted TLS certificate. Proxy settings go in buildAgent.properties as teamcity.https.proxyHost and teamcity.https.proxyPort.

Agent stays unauthorized after a reinstall

The new install generated a new token. Authorize the new entry and remove the old one, or restore the previous authorizationToken.

Builds wait with no compatible agents

Open the build configuration's Agent Requirements tab. In most cases the agent sits in a pool the project cannot use, or a parameter is missing.

Cloud agents do not start

The profile hit its instance limit, you ran out of agent licenses, or the IAM identity lacks a permission. The cloud profile page shows the last error per image.

Agent fails to start after a server upgrade

Newer agents need a newer Java. Upgrade to Java 21 or later, or use an agent package with a bundled JDK.

FAQ

How many build agents are free in TeamCity?

TeamCity On-Premises Professional includes 3 agents at no cost. Enterprise also includes 3 and you buy more as agent licenses.

Do cloud agents count against TeamCity agent licenses?

Yes. Licenses limit authorized agents regardless of origin, so EC2 and Kubernetes agents count while they stay connected.

Can I use self-hosted agents with TeamCity Cloud?

Yes. You pay a flat monthly slot per concurrent self-hosted build and no build credits for the build time.

Can one TeamCity agent run several builds at once?

No. An agent runs one build at a time. Run several agents (separate directories or containers) on a large host for parallelism.

Related guides: Jenkins agents on demand, Azure DevOps self-hosted agents and self-hosted GitHub Actions runners.

TeamCity agents with cirunner.dev

cirunner.dev provisions a fresh VM per job, registers it with your CI using a token you provide, scales with the queue and destroys the machine after the job. You choose CPU, RAM, x86_64 or arm64, region, base image and an optional GPU, and pay per compute minute.

The service is in early access, launching with GitHub Actions and GitLab CI. TeamCity is on the roadmap; vote for it on the early-access form.

Skip the runner fleet

cirunner.dev boots a fresh VM for every TeamCity job, registers it, and destroys it when the job ends. TeamCity is on our roadmap. Vote for it on the early-access form.

Join early access