Course contentsShow
← C#
Lesson 1841 of 1,90817. Deployment and Cloud ArchitectureFree lesson

Volume Mounting for Persistent Logging and Caching

Map container-local directories to persistent storage for stateful .NET container scenarios.

In this lesson, you will learn how to decouple your .NET application’s ephemeral container storage from host-level persistent storage to ensure your logs and cache data survive container restarts.

The Problem: Ephemeral Filesystems

By default, files created inside a Docker container (like local log files or Microsoft.Extensions.Caching.File caches) reside in the container's writable layer. When the container stops or is replaced during a deployment, that layer is discarded. For stateful needs, we must "mount" a directory from the host machine into the container’s filesystem.

Implementing Volume Mounting

In a .NET production scenario, you typically define these mounts in your docker-compose.yml or your orchestrator deployment manifest. By mapping a host path to your application's data directory, the .NET runtime performs file I/O against the host’s persistent disk, making the data immune to the container's lifecycle.

For example, to persist a local caching directory:

services:
  api:
    image: my-dotnet-app
    volumes:
      - /var/lib/dotnet/logs:/app/logs
      - /mnt/fast-ssd/cache:/app/cache

Within your C# application, you simply treat these as standard paths:

// The application writes to /app/logs regardless of the mount
var logPath = Path.Combine(Directory.GetCurrentDirectory(), "logs", "app.log");
File.AppendAllText(logPath, $"Event occurred at {DateTime.UtcNow}");

Strategic Considerations

When mounting volumes, consider the following for high-performance .NET workloads:

  1. I/O Throughput: If your application is heavily reliant on disk-based caching (e.g., local disk provider for IDistributedCache), ensure the host path maps to high-IOPS storage, such as an SSD, rather than a network-attached drive with high latency.
  2. Permissions: Because you are mapping host directories into the container, ensure the Non-Root user defined in your Dockerfile has the appropriate read/write permissions on the host directory. A common pitfall is the container process attempting to write to a host folder owned by root.
  3. Path Synchronization: Use IHostEnvironment.ContentRootPath or similar abstractions in .NET to dynamically locate these mounted volumes, keeping your code agnostic of the specific deployment environment.

Key Takeaway: Volume mounting bridges the gap between containerized execution and persistent state by mapping external host storage into the container’s path structure, ensuring your logs and cache persist across container lifecycles.