Create Self Hosted Agent Docker Image for Azure DevOps

Recently exploring the Azure DevOps in 360 degree directions. Ended up with creating self hosted agent for Azure DevOps. In this post. we will quickly go through with the method of creating Self Hosted Agent docker for Azure DevOps pipelines.

Just a brief about the types of DevOps Agent in Azure.

  1. Azure Hosted Agent
  2. Self Hosted Agent

So as per the name it is self explanatory yet in a simple manner we can say that –

Azure Hosted Agent, are hosted in Azure which are managed by the Azure. There upgradation, security, networking, disk space, all other operational things will be taken care by Azure. Whereas in Self Hosted Agent, it is a bit different.

Self Hosted Agent, you can host in anywhere. It does not matter from where. Even I was able to run the Self Hosted Agent in my Laptop’s Virtual Box. Contrary to Azure Hosted Agent, you have to take care each and everything of Self Hosted Agent.

Currently, Azure supports the Windows, Linux and MacOS based DevOps agent at the time of writing this post.

You can also run the agents in the container. Welcome in Microservice world indeed. This is a future so I prefer to use the containers.

You might have got the idea from my above contents that in this post we will straight talk about creating docker image for self hosted agent for Azure DevOps.

Create Self Hosted Agent Docker Image

We will directly dive into how we will create this Docker Image. We expect you already know how to create the docker image and by following this post also you will be able to create the Docker Image of the agent.

  1. We are using Linux Ubuntu System to create the Agent Docker Image
  2. We are also using the Ubuntu for Container OS.

Create a directory

In this directory we will keep the Dockerfile and start.sh file which are the requirements.

mkdir azp-agent-linux

Create Dockerfile

Change to the directory and create the Dockerfile inside

cd azp-agent-linux

Now create a file called Dockerfile and paste the given below contents. You will also observe that we are installing some softwares like Ansible, az and aws cli,git and azure bicep.

vi Dockerfile
FROM ubuntu:22.04
ENV TARGETARCH="linux-x64"
ARG DEBIAN_FRONTEND=noninteractive
RUN apt update
RUN apt install -y curl git jq libicu70 software-properties-common;apt-add-repository --yes --update ppa:ansible/ansible \
&& apt -y install ansible zip unzip apt-utils \
&& curl https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip -o awscliv2.zip;unzip awscliv2.zip \
&& ./aws/install -i /usr/local/aws-cli -b /usr/local/bin \
&& curl -sL https://aka.ms/InstallAzureCLIDeb | bash \
&& az bicep install
WORKDIR /azp/
COPY ./start.sh ./
RUN chmod +x ./start.sh
RUN useradd -m -d /home/agent agent
RUN chown -R agent:agent /azp /home/agent
USER agent
ENTRYPOINT [ "./start.sh" ]

Create start.sh file

Create start.sh file in same directory where you have created the Dockerfile. We will copy this to Docker image during the build.

vi start.sh
#!/bin/bash
set -e
if [ -z "${AZP_URL}" ]; then
echo 1>&2 "error: missing AZP_URL environment variable"
exit 1
fiif [ -z "${AZP_TOKEN_FILE}" ]; then
if [ -z "${AZP_TOKEN}" ]; then
echo 1>&2 "error: missing AZP_TOKEN environment variable"
exit 1
fiAZP_TOKEN_FILE="/azp/.token"
echo -n "${AZP_TOKEN}" > "${AZP_TOKEN_FILE}"
fiunset AZP_TOKENif [ -n "${AZP_WORK}" ]; then
mkdir -p "${AZP_WORK}"
ficleanup() {
trap "" EXITif [ -e ./config.sh ]; then
print_header "Cleanup. Removing Azure Pipelines agent..."# If the agent has some running jobs, the configuration removal process will fail.
# So, give it some time to finish the job.
while true; do
  ./config.sh remove --unattended --auth "PAT" --token $(cat "${AZP_TOKEN_FILE}") && break

  echo "Retrying in 30 seconds..."
  sleep 30
done
Copyfi
}print_header() {
lightcyan="\033[1;36m"
nocolor="\033[0m"
echo -e "\n${lightcyan}$1${nocolor}\n"
}Let the agent ignore the token env variablesexport VSO_AGENT_IGNORE="AZP_TOKEN,AZP_TOKEN_FILE"print_header "1. Determining matching Azure Pipelines agent..."AZP_AGENT_PACKAGES=$(curl -LsS 
-u user:$(cat "${AZP_TOKEN_FILE}") 
-H "Accept:application/json;" 
"${AZP_URL}/_apis/distributedtask/packages/agent?platform=${TARGETARCH}&top=1")AZP_AGENT_PACKAGE_LATEST_URL=$(echo "${AZP_AGENT_PACKAGES}" | jq -r ".value[0].downloadUrl")if [ -z "${AZP_AGENT_PACKAGE_LATEST_URL}" -o "${AZP_AGENT_PACKAGE_LATEST_URL}" == "null" ]; then
echo 1>&2 "error: could not determine a matching Azure Pipelines agent"
echo 1>&2 "check that account "${AZP_URL}" is correct and the token is valid for that account"
exit 1
fiprint_header "2. Downloading and extracting Azure Pipelines agent..."curl -LsS "${AZP_AGENT_PACKAGE_LATEST_URL}" | tar -xz & wait $!source ./env.shtrap "cleanup; exit 0" EXIT
trap "cleanup; exit 130" INT
trap "cleanup; exit 143" TERMprint_header "3. Configuring Azure Pipelines agent..."./config.sh --unattended 
--agent "${AZP_AGENT_NAME:-$(hostname)}" 
--url "${AZP_URL}" 
--auth "PAT" 
--token $(cat "${AZP_TOKEN_FILE}") 
--pool "${AZP_POOL:-Default}" 
--work "${AZP_WORK:-_work}" 
--replace 
--acceptTeeEula & wait $!print_header "4. Running Azure Pipelines agent..."chmod +x ./run.shTo be aware of TERM and INT signals call ./run.shRunning it with the --once flag at the end will shut down the agent after the build is executed./run.sh "$@" & wait $!

Build the Docker Image

Now run the docker build command to create the Docker Image.

docker build -t azp-agent-linux .

This will create your Docker Image for Self Hosted Agent.

Run the docker container and make it available as a Self Hosted Agent.

AZP_URL = URL of your Azure DevOps Project

AZP_TOKEN = It is the PAT token of your Project Organization in Azure DevOps

AZP_POOL = Agent Pool Name

AZP_AGENT_NAME = Docker Agent Name

docker run -e AZP_URL="" -e AZP_TOKEN="" -e AZP_POOL="" -e AZP_AGENT_NAME="Docker Agent - Linux" --name "azp-agent-linux" azp-agent-linux:latest

Check the Docker Container Status

You can the running status of container by using this command.

docker ps

My Docker Image Self Hosted Agent for Azure DevOps

If you are interested to use my Docker Image, you can pull it from the Dockerhub.

docker pull sharadchhetri/azp-agent-linux

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.