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.
- Azure Hosted Agent
- 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.
- We are using Linux Ubuntu System to create the Agent Docker Image
- 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