.netazuredocker

How do I persist logs from a Dockerized .NET Core app in Azure DevOps and save them as artifacts?


I'm running a .NET Core web API inside a Docker container as part of an Azure DevOps pipeline. The app generates logs during execution, and I want to keep those logs after the container stops Ideally, I’d like to save them as build artifacts.

I've tried mounting a volume to store the logs, but after the pipeline finishes, I either don’t see the logs or the folder is empty. I need a way to persist them and access them in Azure DevOps after the build.

In my Dockerfile, I set up a volume like this:

What I tried and expected:

In my Dockerfile, I added a volume:

VOLUME /app/logs

Then in my pipeline, I tried this:

- script: |
    docker build -t myapp .
    docker run --rm -v $(System.DefaultWorkingDirectory)/logs:/app/logs myapp

The app writes logs to /app/logs/app.log. I expected the logs to appear in $(System.DefaultWorkingDirectory)/logs, but the folder is either missing or empty after the container runs. What am I doing wrong?


Solution

  • You're nearly there! This is a common Docker issue in Azure DevOps. Here's how to keep your logs after the container stops.
    Make sure the log folder exists before running the container.

    Docker will not create the host directory if it doesn't already exist. So first, create it in your pipeline.
    if you are using bash or cmd

    
    - script: mkdir -p $(System.DefaultWorkingDirectory)/logs
    

    If you are using powershell

    - powershell: New-Item -ItemType Directory -Path $(System.DefaultWorkingDirectory)\logs" -Force
    

    Mount the volume correctly in your docker run
    You are already using a VOLUME directive in the Dockerfile, which is fine.

    - script: |
    docker build -t myapp .
    docker run --rm -v $(System.DefaultWorkingDirectory)/logs:/app/logs myapp
    

    Flush the logs before the app exits
    Sometimes the logs aren’t fully written to disk when the container shuts down. it's a good idea to explicitly flush the logs.

    AppDomain.CurrentDomain.ProcessExit += (s, e) => Log.CloseAndFlush();

    Publish the logs as an artifact in Azure DevOps
    This is how you make the logs accessible after the build completes

    - task: PublishBuildArtifacts@1
    inputs:
    PathtoPublish: '$(System.DefaultWorkingDirectory)/logs'
    ArtifactName: 'AppLogs'
    publishLocation: 'Container'
    

    You’ll be able to download the logs from the pipeline summary after the job finishes