- Azure DevOps
When you build a Docker image you often need to use secrets to be able to retrieve some dependencies. To download them, you must pass credentials inside your Dockerfile. But how to do it properly?
In this tutorial you will see how to pass credentials inside your Azure DevOps pipeline into your Dockerfile to build a Docker image successfully.
Let’s imagine you have to build a dotnet project but you have some nugets package stored in the Azure DevOps artifacts section. The Dockerfile to build the project should look something like this:
FROM mcr.microsoft.com/dotnet/aspnet:6.0-focal AS base WORKDIR /app ENV ASPNETCORE_URLS=http://+:5100 # Creates a non-root user with an explicit UID and adds permission to access the /app folder # For more info, please refer to https://aka.ms/vscode-docker-dotnet-configure-containers RUN adduser -u 5678 --disabled-password --gecos "" appuser && chown -R appuser /app USER appuser FROM mcr.microsoft.com/dotnet/sdk:6.0-focal AS build COPY ["src/DemoProject/DemoProject.csproj", "src/DemoProject/"] ## Restore section RUN dotnet restore "src/DemoProject/DemoProject.csproj" COPY ./src ./src WORKDIR "/src/DemoProject" RUN dotnet publish "DemoProject.csproj" -c Release --no-restore -o /app/publish FROM base AS final WORKDIR /app COPY --from=build /app/publish . EXPOSE 5100 ENTRYPOINT ["dotnet", "DemoProject.dll"]
When Docker will start to run the
restore command it will failed, because to access the nugets packages inside Azure DevOps artifacts from the Dockerfile, you must add a new nuget source. But to add a new nuget source you need to provide a Personal Access Token (PAT) to authenticate.
To pass a secret properly you need to use Docker BuildKit. It’s really easy, you
mount the secret with an identifier:
id and a destination:
dst, both can be the same.
So in our use case we mount the
AZURE_DEVOPS_PAT that will contain the Personal Access Token for Azure DevOps:
Then we can add a new nuget source with the
AZURE_DEVOPS_PAT as password:
dotnet nuget add source --username USERNAME --password `cat /AZURE_DEVOPS_PAT` --store-password-in-clear-text --name common_nugets "https://pkgs.dev.azure.com/<YOUR-ORGANISATION-NUGET-FEED>/index.json"
So the restore command will be:
RUN --mount=type=secret,id=AZURE_DEVOPS_PAT,dst=/AZURE_DEVOPS_PAT \ dotnet nuget add source --username USERNAME --password `cat /AZURE_DEVOPS_PAT` --store-password-in-clear-text --name common_nugets "https://pkgs.dev.azure.com/<YOUR-ORGANISATION-NUGET-FEED>/index.json" && \ dotnet restore "src/Project/Project.csproj"
Now, you have the Dockerfile correctly configured, let’s see how to build the image inside Azure DevOps.
To build the image you can use the
Bash@3 task and run this command:
- task: Bash@3 displayName: Docker build image inputs: targetType: inline script: | docker build \ --secret id=AZURE_DEVOPS_PAT \ -t $<YOUR_ACR_LOGIN_URL>/<YOUR_DOCKER_IMAGE>:<YOUR_DOCKER_TAG> . env: AZURE_DEVOPS_PAT: <VALUE_FROM_YOUR_AZURE_DEVOPS_SECRETS> DOCKER_BUILDKIT: 1
Multiple things are important to note above:
You need to define an env variable
AZURE_DEVOPS_PAT and assign the correct value to it. Make sure to store the PAT in a secure variable inside a variables group of Azure DevOps. If you are not familiar with variables groups you can look at my previous tutorial about it.
You define the secret id with the same environment variable
AZURE_DEVOPS_PAT like this:
To be able to mount secrets in Docker with Docker BuildKit you must set the
DOCKER_BUILDKIT env variable to
1 to activate it.
Now you know how to properly pass your secrets into your Dockerfile using Azure DevOps. Of course you can pass as many secrets as you need.