Build agents
Install the OpsNexus agent on Linux, macOS, Windows or Docker, give it executors and labels to run pipelines, and keep it healthy.
On this page
The OpsNexus agent is a small Python program you install on your own machines. It does two jobs:
- Monitoring: every 15 seconds it reports CPU, memory, disk, network, uptime and running jobs to OpsNexus.
- Building: when it has executors, it takes OpsNexus pipeline builds from the queue, checks out the code with Git, runs each step and streams the console output back. This is the same role as a Jenkins agent.
The agent only makes outbound HTTPS (or HTTP) calls to OpsNexus. OpsNexus never connects to the agent. Builds always run on your agents, never on the OpsNexus server.
Agents are managed under Build & deploy → Build agents, which has two tabs: All agents and Download & install.
Requirements
| Item | Needed |
|---|---|
| Python | 3.9 or newer. The installers create a virtual environment with psutil. |
| Git | Needed to check out code for builds. |
| Build tools | Whatever your steps use: Node, JDK, .NET, Docker and so on. |
| Docker | Needed only for plugins that run in a container image, and for the Docker install option. |
| Network | The agent must reach the OpsNexus address. Test it with curl http://<address>/api/health/live. |
Registration tokens
An agent registers with a registration token.
- A token works once. After an agent registers with it, it cannot be used again.
- A token from the install page expires after 24 hours. Through the API (
POST /api/agents/tokens) you can setexpires_in_hoursfrom 1 to 168. - The token is shown once. Copy it when you create it.
- The token sets the agent's Pool (default
default). The pool groups agents, for examplelinux-buildorwindows-desktop. - The token decides whether the agent builds for This project only, or for All projects (shared). A shared agent belongs to the organization. Creating a shared token needs modify on Build agents in your organization role, and an organization admin can turn sharing off.
When the agent registers, it gets its own ID and secret. The secret is saved in the agent's config file and stored hashed in OpsNexus.
Install an agent
- Open Build agents → Download & install.
- Under 1. Create a registration token, choose who the agent builds for, set the Pool, and select Create token.
- Under 2. Run OpsNexus pipelines on it? (optional), set Executors (0 = monitoring only) and Labels.
- Under 3. Install, choose Linux, Windows, macOS or Docker, check the OpsNexus address the agent connects to, and copy the command.
- Run the command on the machine. The agent appears under All agents within a few seconds.
Linux
Run as root. The installer creates the onx-agent system user and the onx-agent systemd service.
curl -fsSL https://opsnexus.example.com/api/agents/download/linux -o install.sh
sudo bash install.sh --token onx_reg_xxxxxxxx --url https://opsnexus.example.com --executors 2 --labels linux,docker,node| Option | Meaning |
|---|---|
--token |
The registration token. Required. |
--url |
The OpsNexus address. The page fills it in. |
--name |
Agent name. Defaults to the host name. |
--executors |
Builds at the same time. Default 0 (monitoring only). |
--labels |
Comma-separated labels, for example linux,docker. |
--insecure |
Skip TLS certificate checks. For test servers only. |
Workspaces are in /var/lib/opsnexus-agent/work.
macOS
Run as an administrator. The installer creates the launchd service com.opsnexus.agent. It needs python3 (install it with xcode-select --install or Homebrew).
curl -fsSL https://opsnexus.example.com/api/agents/download/macos -o install.sh
sudo bash install.sh --token onx_reg_xxxxxxxx --url https://opsnexus.example.com --executors 2 --labels macos,xcodeThe options are the same as on Linux.
Windows
Run PowerShell as Administrator. The installer creates the scheduled task OpsNexus Agent, which runs as SYSTEM, starts at boot and restarts on failure.
Invoke-WebRequest https://opsnexus.example.com/api/agents/download/windows -OutFile install.ps1
powershell -ExecutionPolicy Bypass -File install.ps1 -Token onx_reg_xxxxxxxx -Server https://opsnexus.example.com -Executors 2 -Labels windows,dotnetParameters: -Token (required), -Server, -Name, -Executors, -Labels and -Insecure. Builds need Git for Windows.
Docker
The Docker option builds the agent image from your OpsNexus server and runs it as a container. The image includes Git, bash, Python and the Docker CLI.
# 1. Build the agent image (once per machine; again after OpsNexus updates the agent)
curl -fsSL https://opsnexus.example.com/api/agents/download/docker.tar.gz -o opsnexus-agent.tar.gz
mkdir -p opsnexus-agent && tar -xzf opsnexus-agent.tar.gz -C opsnexus-agent
docker build -t opsnexus-agent opsnexus-agent
# 2. Start the agent
docker rm -f docker-agent-01 2>/dev/null || true
docker run -d \
--name docker-agent-01 \
--hostname docker-agent-01 \
--restart unless-stopped \
-e ONX_URL=https://opsnexus.example.com \
-e ONX_REGISTRATION_TOKEN=onx_reg_xxxxxxxx \
-e ONX_AGENT_NAME=docker-agent-01 \
-e ONX_EXECUTORS=2 \
-e ONX_LABELS=linux,docker \
-v /var/run/docker.sock:/var/run/docker.sock \
--group-add "$(stat -c %g /var/run/docker.sock 2>/dev/null || echo 0)" \
-v docker-agent-01-data:/data \
opsnexus-agent- The registration is kept in the
<name>-datavolume, so the container keeps its identity when it restarts. - Builds can use Docker mounts the host's Docker socket and adds the label
docker. Builds can then rundocker build,docker runanddocker compose. Use a machine dedicated to builds for this. - The page also has a Windows PowerShell variant of the commands.
- Logs:
docker logs -f docker-agent-01.
Container settings:
| Variable | Meaning |
|---|---|
ONX_URL |
The OpsNexus address. It always overrides the saved address. |
ONX_REGISTRATION_TOKEN |
Token used to register when there is no saved registration, or when the token is different from the one used before. |
ONX_AGENT_NAME |
Agent name. |
ONX_EXECUTORS |
Executors. The container default is 2. |
ONX_LABELS |
Comma-separated labels. |
ONX_WORK_DIR |
Workspace folder. The image uses /data/work. |
ONX_AGENT_CONFIG |
Config file path. The image uses /data/agent.json. |
Next to OpsNexus with docker compose
The OpsNexus compose file has a runner service that uses the same image. On the OpsNexus server:
# in .env next to docker-compose.yml
RUNNER_TOKEN=onx_reg_xxxxxxxx
RUNNER_EXECUTORS=2
RUNNER_LABELS=linuxdocker compose --profile runner up -d runnerRUNNER_NAME sets the agent name (default docker-runner). Without RUNNER_LABELS, the service uses linux,docker-runner.
The OpsNexus address (AGENT_URL)
The agent connects to the address in its install command. That address must work from the agent machine. http://localhost:8080 and http://host.docker.internal:8080 only work on the OpsNexus server itself.
- The install page uses
AGENT_URLfrom the server's.env. IfAGENT_URLis empty, it usesPUBLIC_URL. - If that address is local-only, the page warns you and suggests the address in your browser instead.
- You can edit OpsNexus address the agent connects to on the page for a one-off install.
- To set it for everyone, set
AGENT_URLto an address every agent can reach (for examplehttp://192.168.1.10:8080orhttps://opsnexus.example.com) and restart theapiservice. KeepPUBLIC_URLas it is if SSO is set up, because SSO providers need that exact URL. - Open the web port (
WEB_PORT, default 8080) in the server's firewall.
# .env on the OpsNexus server
PUBLIC_URL=http://localhost:8080
AGENT_URL=http://192.168.1.10:8080If OpsNexus moves to a new address, agents do not need to register again:
- Container: recreate it with the new
-e ONX_URL=.... - Installed service: run
python onx_agent.py set-url https://new-addresswith the agent's Python, then restart the service.
Executors and labels
Executors is the number of builds an agent runs at the same time. 0 means monitoring only. The maximum is 32. A build that waits for an approval keeps its executor busy.
Labels let pipelines choose agents:
agent:
labels: [linux, docker]- An agent matches when it has every label the pipeline asks for. Matching ignores case.
- Each agent also matches its operating system (
linux,windows,macos), its name and its pool, without adding them. - Labels use letters, digits,
.,_and-, up to 40 characters. An agent can have up to 30 labels. - A pipeline can also ask for a pool. The pool must match exactly.
- A project's agent only builds that project's pipelines. A shared agent builds any project's pipelines.
Executors and labels come from the agent's config file by default. To set them in OpsNexus instead:
- Open Build agents → All agents and select the agent.
- Turn on Run pipeline builds on this agent.
- Set Executors and Labels and select Save.
The agent applies the change on its next heartbeat (within 15 seconds). Use the agent's config file goes back to the values in the config file.
Config file
| OS | Service | Config file | Logs |
|---|---|---|---|
| Linux | systemd onx-agent (user onx-agent) |
/etc/opsnexus/agent.json |
journalctl -u onx-agent |
| macOS | launchd com.opsnexus.agent |
/Library/Application Support/OpsNexus/agent.json |
/Library/Logs/OpsNexus/agent.log |
| Windows | Scheduled task OpsNexus Agent (SYSTEM) | C:\ProgramData\OpsNexus\agent.json |
Task Scheduler history |
Keys you can edit:
{
"executors": 2,
"labels": ["linux", "docker"],
"work_dir": "/var/lib/opsnexus-agent/work",
"job_process_names": ["Runner.Worker"],
"verify_tls": true
}job_process_names: processes that mean another CI tool is running a build on this machine, for exampleRunner.Worker(Azure DevOps or GitHub runner) orgitlab-runner-helper. The agent shows as busy while one runs.ONX_EXECUTORS,ONX_LABELSandONX_WORK_DIRoverride the file.
Restart the service after editing the file.
Agent status and actions
The All agents list shows each agent's OS, IP, status, pipelines role (executors and labels, or Monitoring only), running jobs and last heartbeat. Shared or Project shows who the agent builds for. Select an agent to see CPU, memory, disk, uptime, a CPU chart for the last hour, build statistics and actions.
| Status | Meaning |
|---|---|
| idle / busy / online | Reporting. Busy means it is running jobs. |
| disconnected | No heartbeat for 2 minutes (AGENT_OFFLINE_SECONDS, default 120). OpsNexus sends the agent.disconnected event. |
| offline | No heartbeat for more than an hour after that. |
| maintenance | Maintenance mode is on. |
| disabled | The agent is disabled. |
Actions (need modify on Build agents; for a shared agent, at organization level):
| Action | Effect |
|---|---|
| Restart | The agent restarts on its next heartbeat, after its running builds finish. |
| Upgrade | The agent downloads the newest onx_agent.py from your OpsNexus server and restarts, after its running builds finish. |
| Maintenance / End maintenance | In maintenance the agent keeps reporting but takes no new builds. |
| Disable / Enable | A disabled agent takes no builds. |
| Unregister | Deletes the agent. Its secret stops working immediately. Needs full access. |
Upgrade an agent
- Installed service: select the agent and Upgrade, or run the installer again.
- Docker: build the image again (step 1 of the Docker command) and recreate the container. Running the Docker command again with a new token re-registers it cleanly.
Uninstall an agent
- Remove the service from the machine:
# Linux
sudo systemctl disable --now onx-agent && sudo rm -rf /opt/opsnexus-agent /etc/opsnexus /etc/systemd/system/onx-agent.service
# macOS
sudo launchctl bootout system /Library/LaunchDaemons/com.opsnexus.agent.plist && sudo rm -rf "/Library/Application Support/OpsNexus" /Library/LaunchDaemons/com.opsnexus.agent.plist# Windows
Unregister-ScheduledTask -TaskName "OpsNexus Agent" -Confirm:$false; Remove-Item -Recurse "$env:ProgramFiles\OpsNexus", "$env:ProgramData\OpsNexus"For a container: docker rm -f <name>.
- In OpsNexus, select the agent and Unregister so its secret stops working.
Run the agent by hand
python onx_agent.py register --url https://opsnexus.example.com --token onx_reg_xxxxxxxx --name build-01 --executors 2 --labels linux
python onx_agent.py runCommands: register, run, start (containers: register from ONX_* variables if needed, then run), set-url <url> and version. Set ONX_AGENT_CONFIG=/path/agent.json to use another config file.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
Builds stay Queued with No build agent is set up to run pipelines yet |
No agent has executors. | Give an agent executors, or install one with --executors. |
No build agent with label X |
No agent has every requested label. | Add the label to an agent, or change the pipeline's agent: labels. |
Every agent with label X is offline |
The matching agents are not reporting. | Check the service and the network. |
Log says rejected this agent ... unregistered |
The agent was unregistered, or its config belongs to another OpsNexus database. | Create a new token. Container: run the install command again with it (it re-registers, even with the same volume). Service: run register again and restart. |
Registration failed: An agent named X already exists |
The old registration still exists. | Unregister it under Build agents, or pick another name. |
Registration failed: can't reach OpsNexus at ... |
Wrong address or a firewall. | See "The OpsNexus address (AGENT_URL)" above. |
This registration token is invalid, used or expired |
Tokens work once and expire. | Create a new token. If the agent already has a saved registration, it keeps using it. |
WARNING: ... only works on the OpsNexus machine itself |
The address is localhost or host.docker.internal. |
Use the server's network address. |
git is not installed on this agent |
Git is missing. | Install Git and restart the agent. |
Checkout fails with Repository not found or authentication errors |
The pipeline has no credential, or the credential cannot see the repository. | Check the credential on the pipeline's source settings and use Verify connection. |
Build fails with The build agent X stopped responding |
The agent sent nothing for 3 minutes during the build. | Check the machine and the agent's logs. |
A plugin step says install Docker on this agent |
The plugin runs in a container image. | Install Docker on the agent, or run the job on an agent with the docker label. |
For more, see Troubleshooting.