'Docker secret not mounting to default location

I'm using docker-compose to produce a docker image which requires access to a secure Azure Artifacts directory via Paket. As I'm sure at least some people are aware, Paket does not have default compatibility with the Azure Artifacts Credential Provider. To gain the access I need, I'm trying to mount the access token produced by the credential provider as a secret, then consume it using cat within a paket config command. cat then returns an error message stating that the file is not found at the default secret location.

I'm running this code within an Azure Pipeline on the Microsoft-provided ubuntu-latest agent.

Here's the relevant code snippets (It's possible I'm going into too much detail...):

docker-compose.ci.build.yml:

version: '3.6'

services:
  ci_build:
    build:
      context: .
      dockerfile: Dockerfile
    image: <IMAGE IDENTITY>
    secrets:
      - azure_credential

secrets:
  azure_credential:
    file: ./credential.txt

dockerfile:

FROM mcr.microsoft.com/dotnet/sdk:6.0.102-bullseye-slim-amd64 AS build
<LABEL maintainer="<Engineering lead>"

WORKDIR /src
<Various COPY instructions>
RUN dotnet tool restore
RUN dotnet paket restore
RUN --mount=type=secret,id=azure_credential dotnet paket config add-token "<ARTIFACT_FEED_URL>" "$(cat /run/secrets/azure_credential)"

Azure pipeline definition YAML:

jobs:
  - job: BuildPublish
    displayName: Build & Publish
    steps:
      - task: PowerShell@2
        displayName: pwsh build.ps1
        inputs:
          filePath: ${{ parameters.workingDirectory }}/.azure-pipelines/build.ps1
          pwsh: true
          workingDirectory: ${{ parameters.workingDirectory }}
        env:
          SYSTEM_ACCESSTOKEN: $(System.AccessToken)

The relevant lines of the powershell script initiating docker-compose:

$projectRoot = Split-Path -Path $PSScriptRoot -Parent
Push-Location -Path $projectRoot
try {
    ...
    Out-File -FilePath ./credential.txt -InputObject $Env:SYSTEM_ACCESSTOKEN
    ...
    & docker-compose -f ./docker-compose.ci.build.yml build
    ...
}
finally {
    ...
    Pop-Location
}

The error message: 0.276 cat: /run/secrets/azure_credential: No such file or directory

If there's other relevant code, let me know.

I tried to verify that the environment variable I'm housing the secret in on the agent even existed and that the value was being saved to the ./credential.txt file for mounting in the image. I verified that the text file was being properly created. I've tried fiddling with the syntax for all the relevant commands--fun fact, Docker docs have two different versions of the mounting syntax, but the other version just crashed. I tried using Windows default pathing in case my source image was a Windows one, but it doesn't appear to be.

Essentially, here's where I've left it: I know that the file ./credential.txt exists and contains some value. I know my mounting syntax is correct, or Docker would crash. The issue appears to be something to do with the default mounting path and/or how docker-compose embeds its secrets.



Solution 1:[1]

I figured it out. For reasons I do not understand, the path to the mounted secret has to be defined as an environment variable in the docker-compose YAML. So, like this:

version: '3.6'

services:
  ci_build:
    build:
      context: .
      dockerfile: Dockerfile
    image: <IMAGE IDENTITY>
    secrets:
      - azure_credential
    environment:
      AZURE_CREDENTIAL_FILE: /run/secrets/azure_credential

secrets:
  azure_credential:
    file: credential.txt

This solved the issue. If anyone knows why this solved the issue, I'd love to hear.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Shonee Freed-Doerr