Skip to main content

Command Palette

Search for a command to run...

Development of Docker Server Agent with .NET

Built Using .NET Core for Linux Operating Systems

Updated
8 min read
Development of Docker Server Agent with .NET

OVERVIEW & PURPOSE

The majority of developers find it challenging to utilize Docker on Linux server systems due to a lack of expertise. Deploying applications built with technologies like .NET, Next.js, Python, and Java can be particularly complex. This server agent provides a comprehensive API solution, simplifying the deployment process for developers.

REQUIREMENTS

  1. Software Development Knowledge (.NET).

  2. Docker Basic Knowledge

  3. Linux Server Knowledge

STEP-01: Create a new ASP.NET Core Web API Project

Open up your terminal and run the following code to create your project. Feel free to personalize the project name instead of using “DockerInfoApi”.

dotnet new webapi -n DockerInfoApi
cd DockerInfoApi

STEP-02: Add Docker .NET NuGet Package

  • To communicate between the Docker environment and this project, the Docker.DotNet NuGet Package is required.

  • The Swashbuckle.AspNetCore NuGet Package is necessary for API management and provides an interactive API testing UI.

dotnet add package Docker.DotNet
dotnet add package Swashbuckle.AspNetCore
dotnet add package NuGet.Protocol

STEP-03: Project Setup

Here is a basic Project.csproj file that you can modify to meet your business requirements. The build and publish configurations are also included.

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net9.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>

    <!-- Add these configurations -->
    <OutputType>Exe</OutputType>
    <RuntimeIdentifier>linux-x64</RuntimeIdentifier>
    <SelfContained>true</SelfContained>
    <PublishSingleFile>true</PublishSingleFile>
    <PublishTrimmed>false</PublishTrimmed>
    <IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Docker.DotNet" Version="3.125.15" />
    <!-- Microsoft.AspNetCore.OpenApi is included in .NET 9.0 SDK - you can remove this explicit reference -->
    <PackageReference Include="NuGet.Protocol" Version="6.13.2" />
    <PackageReference Include="Swashbuckle.AspNetCore" Version="8.1.1" />
  </ItemGroup>

</Project>

STEP-04: Update Program.cs & Configure for Docker

Here is a sample file named Program.cs. You can add custom code to meet your business needs.

using Docker.DotNet;

var builder = WebApplication.CreateBuilder(args);

// Configure Docker client
var dockerUri = Environment.OSVersion.Platform == PlatformID.Unix 
    ? "unix:///var/run/docker.sock" 
    : "npipe://./pipe/docker_engine";
builder.Services.AddSingleton<IDockerClient>(new DockerClientConfiguration(new Uri(dockerUri)).CreateClient());

builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();

STEP-05: Create ContainersController.cs (With APIs)

Here is the first API for accessing the Docker environment. The controller provides four APIs listed below:

  1. GET: /containers - Retrieve a list of all containers.

  2. POST: /containers - Create a new container.

  3. POST: /containers/:id/start - Start the specified container.

  4. POST: /containers/:id/stop - Stop the specified container.

  5. DELETE: /containers/:id - Remove the specified container.

using Docker.DotNet;
using Docker.DotNet.Models;
using Microsoft.AspNetCore.Mvc;

namespace DockerInfoApi.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class ContainersController : ControllerBase
    {
        private readonly IDockerClient _dockerClient;

        public ContainersController(IDockerClient dockerClient)
        {
            _dockerClient = dockerClient;
        }

        // List all containers
        [HttpGet]
        public async Task<IActionResult> GetContainers()
        {
            try
            {
                // List all containers
                var contListParams = new ContainersListParameters
                {
                    All = true
                };

                // Get the list of containers
                var containers = await _dockerClient.Containers.ListContainersAsync(contListParams);

                return Ok(containers);
            }
            catch (DockerApiException ex)
            {
                // Handle Docker API exceptions
                var message = $"Error retrieving containers: {ex.Message}";
                return StatusCode((int)ex.StatusCode, message);
            }
            catch (Exception ex)
            {
                // Handle other exceptions
                var message = $"Error retrieving containers: {ex.Message}";
                return BadRequest(message);
            }
        }

        // Create a new container
        //[HttpPost]
        // Coming Soon...

        // Start a container
        [HttpPost("{id}/start")]
        public async Task<IActionResult> StartContainer(string id)
        {
            try
            {
                // Start the container
                var contStartParams = new ContainerStartParameters { };
                var success = await _dockerClient.Containers.StartContainerAsync(id, contStartParams);

                return Ok($"Container {id} started successfully.");
            }
            catch (DockerContainerNotFoundException ex)
            {
                // Handle container not found exception
                var message = $"Container not found: {ex.Message}";
                return NotFound(message);
            }
            catch (Exception ex)
            {
                // Handle other exceptions
                var message = $"Error starting container: {ex.Message}";
                return BadRequest(message);
            }
        }

        // Stop a container
        [HttpPost("{id}/stop")]
        public async Task<IActionResult> StopContainer(string id)
        {
            try
            {
                // Stop the container
                var stopParams = new ContainerStopParameters
                {
                    WaitBeforeKillSeconds = 10
                };
                await _dockerClient.Containers.StopContainerAsync(id, stopParams);

                return Ok($"Container {id} stopped successfully.");
            }
            catch (DockerContainerNotFoundException ex)
            {
                // Handle container not found exception
                var message = $"Container not found: {ex.Message}";
                return NotFound(message);
            }
            catch (Exception ex)
            {
                // Handle other exceptions
                var message = $"Error stopping container: {ex.Message}";
                return BadRequest(message);
            }
        }

        // Remove a container
        [HttpDelete("{id}")]
        public async Task<IActionResult> RemoveContainer(string id)
        {
            try
            {
                // Remove the container
                var removeParams = new ContainerRemoveParameters
                {
                    Force = true,
                    RemoveVolumes = true
                };
                await _dockerClient.Containers.RemoveContainerAsync(id, removeParams);

                return Ok($"Container {id} removed successfully.");
            }
            catch (DockerContainerNotFoundException ex)
            {
                // Handle container not found exception
                var message = $"Container not found: {ex.Message}";
                return NotFound(message);
            }
            catch (Exception ex)
            {
                // Handle other exceptions
                var message = $"Error removing container: {ex.Message}";
                return BadRequest(message);
            }
        }
    }
}

STEP-06: Build and Publish the Project

Run the Project

dotnet run .

# A http://loclhost:5000 link will be generated after successful installation
# Browse URL: http://loclhost:5000/containers

After a successful run of the project, publish the project

dotnet publish -c Release

STEP-07: Prepare your Docker Environment to Test the APIs

Please check if your Docker is running on the OS.

# This command works on Windows, Linux, and macOS.
docker info > /dev/null 2>&1 && echo "Docker is running" || echo "Docker is not running"

Note: If Docker is not running, then install and run it. Docker Install

Creating a test container:

docker pull ubuntu
docker run -it ubuntu /bin/bash

# Test
# It returns the list of containers
docker ps

CONCLUSION:

The development of a Docker Server Agent with .NET simplifies the deployment process for developers who may find using Docker on Linux servers challenging. By following the outlined steps, developers can create a robust API to manage Docker containers efficiently. This guide provides a comprehensive approach, from setting up an ASP.NET Core Web API project to integrating necessary NuGet packages and configuring the Docker environment. By implementing these steps, developers can enhance their deployment capabilities, streamline container management, and leverage the full potential of Docker in their development workflows.

CONTACT:

I’m Kumar Bishojit Paul, the Founder and CEO of BIKIRAN. If you need further assistance, please leave a comment. I’m interested in helping you.


🏢 About Bikiran

Bikiran is a software development and cloud infrastructure company founded in 2012, headquartered in Khulna, Bangladesh. With 15,000+ clients and over a decade of experience, Bikiran builds and operates a suite of products spanning domain services, cloud hosting, app deployment, workflow automation, and developer tools.

SL Topic Product Description
1 Website Bikiran Main platform — Domain, hosting & cloud services
2 Website Edusoft Education management software for institutions
3 Website n8n Clouds Managed n8n workflow automation hosting
4 Website Timestamp Zone Unix timestamp converter & timezone tool
5 Website PDFpi Online PDF processing & manipulation tool
6 Website Blog Technical articles, guides & tutorials
7 Website Support 24/7 customer support portal
8 Website Probackup Automated database backup for SQL, PostgreSQL & MongoDB
9 Service Domain Domain registration, transfer & DNS management
10 Service Hosting Web, app & email hosting on NVMe SSD
11 Service Email & SMS Bulk email & SMS notification service
12 npm Chronopick Date & time picker React component
13 npm Rich Editor WYSIWYG rich text editor for React
14 npm Button Reusable React button component library
15 npm Electron Boilerplate CLI to scaffold Electron.js project templates
16 NuGet Bkash bKash payment gateway integration for .NET
17 NuGet Bikiran Engine Core .NET engine library for Bikiran services
18 Open Source PDFpi PDF processing tool — open source
19 Open Source Bikiran Engine Core .NET engine — open source
20 Open Source Drive CLI CLI tool to manage Google Drive from terminal
21 Docker Pgsql Docker setup for PostgreSQL
22 Docker n8n Docker setup for n8n automation
23 Docker Pgadmin Docker setup for pgAdmin
24 Social Media LinkedIn Bikiran on LinkedIn
25 Social Media Facebook Bikiran on Facebook
26 Social Media YouTube Bikiran on YouTube
27 Social Media FB n8nClouds n8n Clouds on Facebook