DEV Community

Cover image for How I Set Up a Self-Hosted Azure DevOps Agent on Ubuntu (And What I Learned the Hard Way)
Vivian Chiamaka Okose
Vivian Chiamaka Okose

Posted on

How I Set Up a Self-Hosted Azure DevOps Agent on Ubuntu (And What I Learned the Hard Way)

When you are just starting out with Azure DevOps, the managed Microsoft-hosted agents seem like the easy choice. Clean environment, no setup, just works.

Then you hit the parallelism limit on a free plan and everything queues.

That is what sent me down the path of setting up my own self-hosted agent. Here is exactly what I built and what tripped me up along the way.

What a Self-Hosted Agent Actually Is

An agent is the thing that executes your pipeline jobs. When Azure DevOps runs a pipeline, it needs a machine to do the work.

Microsoft-hosted agents are temporary VMs that spin up, do the job, and disappear. Convenient but limited.

A self-hosted agent is one you run yourself, on infrastructure you control. It stays running between jobs, keeps its installed software, and has no parallelism limits.

What I Built

  • Ubuntu 22.04 VM on Azure (Standard_D2s_v3)
  • A custom agent pool called SelfHostedPool
  • Azure Pipelines agent v4.271.0 installed as a system service
  • A test pipeline that confirmed everything was working

Step 1: Create a Personal Access Token

In Azure DevOps, click your profile picture at the top right, then go to Personal Access Tokens. Create a new one with:

  • Agent Pools: Read and Manage
  • Build: Read and Execute

Copy it immediately. You will not see it again.

Step 2: Create the Agent Pool

Go to Organization Settings, then Pipelines, then Agent Pools. Click Add Pool.

  • Type: Self-hosted
  • Name: SelfHostedPool
  • Grant access to all pipelines: checked

Step 3: Provision the VM

I created a Standard_D2s_v3 Ubuntu 22.04 VM on Azure via the portal. The key thing is opening port 443 for outbound communication. The agent talks to Azure DevOps over HTTPS.

Step 4: Get the Agent Download URL

This is where I ran into my first real obstacle. The standard download domain was not resolving. The fix was to get the download URL directly from the Azure DevOps API:

curl -s "https://dev.azure.com/YOUR_ORG/_apis/distributedtask/packages/agent/linux-x64?top=1&api-version=3.0" \
  -u :YOUR_PAT | grep "downloadUrl"
Enter fullscreen mode Exit fullscreen mode

This gives you the exact URL for the latest agent version registered for your organization. Use that URL to download.

Step 5: Install and Configure

mkdir -p ~/azagent && cd ~/azagent
curl -fSL "DOWNLOAD_URL_FROM_ABOVE" -o vsts-agent-linux-x64-4.271.0.tar.gz
tar zxvf vsts-agent-linux-x64-4.271.0.tar.gz
./config.sh
Enter fullscreen mode Exit fullscreen mode

When prompted, enter your organization URL, PAT, and pool name. Then start it as a service:

sudo ./svc.sh install
sudo ./svc.sh start
sudo ./svc.sh status
Enter fullscreen mode Exit fullscreen mode

Active and running.

Step 6: Verify in Azure DevOps

Go to Organization Settings, then Agent Pools, then SelfHostedPool. Your agent should appear as Online.

The Test Pipeline

trigger:
  - main

pool:
  name: SelfHostedPool

steps:
  - script: uname -a
    displayName: System Info
  - script: whoami
    displayName: Current User
  - script: df -h
    displayName: Disk Usage
Enter fullscreen mode Exit fullscreen mode

Run it. Watch all three steps execute on your VM. That green checkmark means your pipeline is running on infrastructure you built.

What I Learned

Running as a system service is not optional for real use. If you run the agent interactively with ./run.sh, it dies when your SSH session ends. Install it as a service so it runs permanently.

Port 443 must be open outbound, not inbound. The agent calls Azure DevOps, not the other way around.

The API download method is more reliable than guessing version numbers. Always use it.

This agent pool powered every pipeline in my Azure DevOps series. Projects 2, 3, and 4 all ran on it. Building it first was the right call.


Vivian Chiamaka Okose is a DevOps Engineer documenting her learning journey in public.


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

Top comments (0)