CosmicChimps.Aspire.Hosting.Dokploy 13.3.5-preview.1

This is a prerelease version of CosmicChimps.Aspire.Hosting.Dokploy.
dotnet add package CosmicChimps.Aspire.Hosting.Dokploy --version 13.3.5-preview.1
                    
NuGet\Install-Package CosmicChimps.Aspire.Hosting.Dokploy -Version 13.3.5-preview.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="CosmicChimps.Aspire.Hosting.Dokploy" Version="13.3.5-preview.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="CosmicChimps.Aspire.Hosting.Dokploy" Version="13.3.5-preview.1" />
                    
Directory.Packages.props
<PackageReference Include="CosmicChimps.Aspire.Hosting.Dokploy" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add CosmicChimps.Aspire.Hosting.Dokploy --version 13.3.5-preview.1
                    
#r "nuget: CosmicChimps.Aspire.Hosting.Dokploy, 13.3.5-preview.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package CosmicChimps.Aspire.Hosting.Dokploy@13.3.5-preview.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=CosmicChimps.Aspire.Hosting.Dokploy&version=13.3.5-preview.1&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=CosmicChimps.Aspire.Hosting.Dokploy&version=13.3.5-preview.1&prerelease
                    
Install as a Cake Tool

CosmicChimps.Aspire.Hosting.Dokploy

Deploy .NET Aspire applications to Dokploy using Docker Stack format.

Overview

This package extends .NET Aspire to deploy applications to Dokploy, a self-hosted PaaS built on Docker Swarm. It automatically configures your Aspire application for Docker Stack deployment with full control over all Docker Compose service settings.

Key Discovery

Aspire.Hosting.Docker already includes full Docker Stack/Swarm support! This package builds on that foundation to provide seamless Dokploy integration via API. You use the built-in PublishAsDockerComposeService() method to configure all Swarm settings with complete flexibility.

Installation

dotnet add package CosmicChimps.Aspire.Hosting.Dokploy

Usage

Basic Configuration with Swarm Deploy Settings

using Aspire.Hosting.Docker.Resources.ServiceNodes.Swarm;

var builder = DistributedApplication.CreateBuilder(args);

// Configure Docker Compose environment for Stack/Swarm format
builder.AddDockerComposeEnvironment("env")
    .ConfigureComposeFile(composeFile =>
    {
        // Set version for Docker Stack compatibility
        composeFile.Version = "3.8";

        // Change networks from bridge to overlay for Swarm
        foreach (var network in composeFile.Networks.Values)
        {
            if (network.Driver == "bridge" || network.Driver is null)
            {
                network.Driver = "overlay";
            }
        }

        // Clean up all services for Stack compatibility
        foreach (var service in composeFile.Services.Values)
        {
            // Remove depends_on (not supported in Stack format)
            service.DependsOn.Clear();

            // Remove restart if deploy section exists
            if (service.Deploy is not null)
            {
                service.Restart = null;
            }
        }
    });

// Configure Redis with Swarm deploy settings
var cache = builder.AddRedis("cache")
    .PublishAsDockerComposeService((_, service) =>
    {
        service.Deploy = new Deploy
        {
            Replicas = 1,
            RestartPolicy = new RestartPolicy
            {
                Condition = "on-failure",
                Delay = "5s",
                MaxAttempts = 3
            },
            Placement = new Placement
            {
                // Pin to manager node for data persistence
                Constraints = new List<string> { "node.role == manager" }
            }
        };
        // Remove compose-specific restart
        service.Restart = null;
    });

// Configure API service with Swarm deploy settings
var api = builder.AddProject<Projects.ApiService>("api")
    .PublishAsDockerComposeService((_, service) =>
    {
        service.Deploy = new Deploy
        {
            Replicas = 2, // Scale to 2 instances
            RestartPolicy = new RestartPolicy
            {
                Condition = "on-failure",
                Delay = "5s",
                MaxAttempts = 3
            }
        };
        service.Restart = null;
    });

// Configure web with Traefik labels for sticky sessions
builder.AddProject<Projects.Web>("web")
    .WithReference(cache)
    .WithReference(api)
    .PublishAsDockerComposeService((_, service) =>
    {
        service.Deploy = new Deploy
        {
            Replicas = 3,
            RestartPolicy = new RestartPolicy
            {
                Condition = "on-failure",
                Delay = "5s",
                MaxAttempts = 3
            },
            Labels = new LabelSpecs
            {
                { "traefik.http.services.blazor.loadbalancer.sticky.cookie", "true" },
                { "traefik.http.services.blazor.loadbalancer.sticky.cookie.name", "blazor_affinity" }
            }
        };
        service.Restart = null;
    });

builder.Build().Run();

Deploy to Dokploy (Future Feature)

using CosmicChimps.Aspire.Hosting.Dokploy;

// This will be implemented in a future version
builder.PublishToDokploy("myapp", settings =>
{
    settings.DokployUrl = "https://your-dokploy-instance.com";
    settings.ApiToken = builder.Configuration["Dokploy:ApiToken"]!;
    settings.ProjectId = builder.Configuration["Dokploy:ProjectId"]!;
});

Why Use PublishAsDockerComposeService Directly?

By using PublishAsDockerComposeService() directly instead of wrapper methods, you get:

Full Control: Configure any Docker Compose/Stack setting
Flexibility: Add labels, volumes, networks, environment variables, etc.
Composability: Chain multiple configurations together
No Limitations: Not restricted to predefined wrapper methods

Example: Complete Service Configuration

builder.AddProject<Projects.Web>("web")
    .PublishAsDockerComposeService((_, service) =>
    {
        // Deploy settings
        service.Deploy = new Deploy
        {
            Replicas = 3,
            RestartPolicy = new RestartPolicy
            {
                Condition = "on-failure",
                Delay = "10s",
                MaxAttempts = 5
            },
            Placement = new Placement
            {
                Constraints = new List<string> 
                { 
                    "node.role == worker",
                    "node.labels.region == us-east"
                }
            },
            // Add Traefik labels
            Labels = new LabelSpecs
            {
                { "traefik.enable", "true" },
                { "traefik.http.routers.web.rule", "Host(`example.com`)" },
                { "traefik.http.services.web.loadbalancer.sticky.cookie", "true" }
            },
            // Resource limits
            Resources = new Resources
            {
                Limits = new ResourceLimits
                {
                    Cpus = "0.5",
                    Memory = "512M"
                },
                Reservations = new ResourceReservations
                {
                    Cpus = "0.25",
                    Memory = "256M"
                }
            }
        };
        
        // Remove compose-specific settings
        service.Restart = null;
        
        // Add volumes, networks, or other settings as needed
    });

Docker Stack vs Docker Compose

ports vs expose

  • ports: Exposes ports to the host machine (external access)

    ports:
      - "${WEBFRONTEND_PORT}:8080"
    

    Use when you need external access (e.g., web frontend via reverse proxy)

  • expose: Makes ports available only to other services in the same network (internal access)

    expose:
      - "${APISERVICE_PORT}"
    

    Use for internal services that only need to communicate with other services

Stack Format Requirements

Docker Stack has different requirements than Docker Compose:

✅ Supported
  • Pre-built images in a registry
  • Environment variables
  • Named volumes
  • Overlay networks
  • Deploy sections (replicas, restart policy, placement, resources, labels)
  • expose and ports for networking
❌ Not Supported
  • build: sections (images must be pre-built)
  • depends_on: (Swarm has built-in service discovery)
  • container_name: (Swarm manages naming)
  • Top-level restart: (use deploy.restart_policy)
  • Extended depends_on format with conditions

Configuration

Store your Dokploy credentials in appsettings.json:

{
  "Dokploy": {
    "ApiToken": "your-api-token",
    "ProjectId": "your-project-id"
  }
}

Troubleshooting

Error: "services.webfrontend.depends_on.0 must be a string"

Docker Stack doesn't support the extended depends_on format with conditions. Use the ConfigureComposeFile method shown above to remove depends_on entries, or convert them to simple string format.

Error: "Service has a build section"

Stack files don't support build:. Ensure your project images are pre-built and pushed to a registry accessible by your Swarm cluster.

Networks not working between services

Ensure networks use driver: overlay for multi-host Swarm networking. The example above shows how to convert bridge networks to overlay in the ConfigureComposeFile method.

When to use ports vs expose

  • Use ports for services that need external access (e.g., web frontend accessible via Traefik)
  • Use expose for internal services that only communicate with other services (e.g., API, databases)

Examples

See the example/CosmicChimps.Aspire.AppHost/ folder in the repository for a complete working example with Redis, API service, and Blazor web frontend configured for Docker Stack deployment.

License

MIT

Contributing

Contributions welcome! Please open an issue or PR on GitHub.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
13.3.5-preview.1 52 5/25/2026
13.3.1-preview.1 53 5/13/2026
13.2.4-preview.12 68 5/7/2026
13.2.4-preview.11 49 5/5/2026
13.2.4-preview.10 49 5/4/2026
13.2.4-preview.9 45 5/4/2026
13.2.4-preview.8 41 5/4/2026
13.2.4-preview.7 54 5/4/2026
13.2.4-preview.6 57 5/3/2026
13.2.4-preview.5 53 5/3/2026
13.2.4-preview.4 50 5/3/2026
13.2.4-preview.3 58 5/2/2026
13.2.4-preview.2 64 5/1/2026
13.2.4-preview.1 94 4/25/2026
13.2.3-preview.1 85 4/22/2026
13.2.2-preview.2 57 4/20/2026
13.2.2-preview.1 68 4/10/2026
13.2.1-preview.2 63 4/8/2026
13.2.1-preview.1 73 4/6/2026
13.2.0-preview.1 62 3/25/2026
Loading failed