Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 30, 2025

Description

Adds Aspire.Hosting.Certbot hosting integration for ACME-based certificate management via Certbot container.

New package: Aspire.Hosting.Certbot

  • CertbotResource - Container resource for SSL/TLS certificate provisioning using ACME protocol
  • AddCertbot() - Extension method to add Certbot with domain/email parameters
  • WithServerCertificates<T>() - Mount certificates volume in other containers
  • CertificatePath - Property exposing the path to the SSL/TLS certificate (fullchain.pem)
  • PrivateKeyPath - Property exposing the path to the private key (privkey.pem)
  • Runs standalone ACME challenge server on port 80
  • Shared volume at /etc/letsencrypt with permission fixes for non-root containers
  • Pinned to certbot/certbot:v5.1.0
  • Works with any ACME-compatible certificate authority (Let's Encrypt, ZeroSSL, etc.)

Usage:

var domain = builder.AddParameter("domain");
var email = builder.AddParameter("email");

var certbot = builder.AddCertbot("certbot", domain, email);

// Access certificate paths
var certificatePath = certbot.Resource.CertificatePath;   // /etc/letsencrypt/live/{domain}/fullchain.pem
var privateKeyPath = certbot.Resource.PrivateKeyPath;     // /etc/letsencrypt/live/{domain}/privkey.pem

var yarp = builder.AddContainer("yarp", "myimage")
                  .WithServerCertificates(certbot);

Checklist

  • Is this feature complete?
    • Yes. Ready to ship.
    • No. Follow-up changes expected.
  • Are you including unit tests for the changes and scenario tests if relevant?
    • Yes
    • No
  • Did you add public API?
    • Yes
      • If yes, did you have an API Review for it?
        • Yes
        • No
      • Did you add <remarks /> and <code /> elements on your triple slash comments?
        • Yes
        • No
    • No
  • Does the change make any security assumptions or guarantees?
    • Yes
      • If yes, have you done a threat model and had a security review?
        • Yes
        • No
    • No
  • Does the change require an update in our Aspire docs?
Original prompt

Add support for a lets encypt integration in Aspire.Hosting.LetsEncrypt. It's going to have cert bot container, see below for a useful configuration. Make sure it follows the pattern of other integrations:

e.g.:

// Let's Encrypt parameters (required when EnableHttps=true)
// Set via: Parameters__domain and Parameters__letsencrypt_email
var domain = builder.AddParameter("domain");
var letsEncryptEmail = builder.AddParameter("letsencrypt-email");

var certbot = builder.AddContainer("certbot", "certbot/certbot")
// Shared volume for certificates - both certbot and YARP mount this
.WithVolume("letsencrypt", "/etc/letsencrypt")
// Port 80 must be published to host for Let's Encrypt to reach the ACME challenge
.WithHttpEndpoint(port: 80, targetPort: 80)
.WithExternalHttpEndpoints()
.WithArgs(context =>
{
context.Args.Add("certonly");
context.Args.Add("--standalone");
context.Args.Add("--non-interactive");
context.Args.Add("--agree-tos");
context.Args.Add("-v");
context.Args.Add("--keep-until-expiring");
// Fix permissions so non-root containers (like YARP) can read the certs
context.Args.Add("--deploy-hook");
context.Args.Add("chmod -R 755 /etc/letsencrypt/live && chmod -R 755 /etc/letsencrypt/archive");
context.Args.Add("--email");
context.Args.Add(letsEncryptEmail.Resource);
context.Args.Add("-d");
context.Args.Add(domain.Resource);
});


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI changed the title [WIP] Add support for Let's Encrypt integration in Aspire.Hosting Add Aspire.Hosting.LetsEncrypt integration for Certbot container support Nov 30, 2025
Copilot AI requested a review from davidfowl November 30, 2025 01:19
Copilot finished work on behalf of davidfowl November 30, 2025 01:19
@davidfowl
Copy link
Member

cc @danegsta

@davidfowl
Copy link
Member

@copilot - Lets expose the Certificate and Private Key as propreties on CertbotResource

Copy link
Contributor Author

Copilot AI commented Nov 30, 2025

@copilot - Lets expose the Certificate and Private Key as propreties on CertbotResource

Added CertificatePath and PrivateKeyPath properties to CertbotResource in commit 3d6ccad. Both return ReferenceExpression that resolves to the Let's Encrypt certificate paths (/etc/letsencrypt/live/{domain}/fullchain.pem and privkey.pem).

Copilot finished work on behalf of davidfowl November 30, 2025 04:21
@github-actions
Copy link
Contributor

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 13248

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 13248"

1 similar comment
@github-actions
Copy link
Contributor

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 13248

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 13248"

@mitchdenny
Copy link
Member

Wonder whether we should make this Aspire.Hosting.Certbot instead. Rather than being LetsEncrypt brand specific

@danegsta
Copy link
Member

danegsta commented Dec 2, 2025

Wonder whether we should make this Aspire.Hosting.Certbot instead. Rather than being LetsEncrypt brand specific

Yeah, it'd be nice to have something that'll work with any ACME compatible certificate source.

/// </code>
/// </example>
/// </remarks>
public static IResourceBuilder<T> WithCertbotCertificates<T>(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we're going to have situations where users have multiple certificates (potentially even multiple Certbot certificates) for a resource for different purposes. There might be a server auth (HTTPS) certificate from Let's Encrypt, but also one or more client auth certificates from something like a Vault server on their network.

It's one of the reasons I named the new HTTPS APIs WithServerAuthenticationCertificate to differentiate from future client certificate usage. I think we'll need a similar model for publish time where it's not enough to just have a certificate, we need to consider what it's used for as well.

I'd love to see this integrate with those new APIs so we could do something like:

var certbot = builder.AddCertbot("mydomaincert", "mydomain", "email")
    .RunAsDevelopmentCertificate();

builder.AddYarp("gateway")
    .WithServerAuthenticationCertificate(certbot);

and have everything work at both run and publish.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the future we'd be able to have builder.AddKeyVaultCertificate("mycert") with the same conventions.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does let’s encrypt support issuing more than just server certificates?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see we should rename the method

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not after February 2026 they don't; but Certbot can be used to retrieve certificates from other providers that support the same protocol.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be a great way to provision client certificates from a Vault server on a private network, for example.

@mitchdenny
Copy link
Member

Wonder whether we should make this Aspire.Hosting.Certbot instead. Rather than being LetsEncrypt brand specific

Yeah, it'd be nice to have something that'll work with any ACME compatible certificate source.

ZeroSSL etc.

@davidfowl
Copy link
Member

Let’s not over engineer the certbot integration. We need concrete implementations to flee out the abstractions. There’s no harm in modeling the concrete container and initially before understanding the abstraction.

See also keycloack and oauth

@davidfowl
Copy link
Member

@copilot let’s make this Aspire.Hosting.Certbot

@mitchdenny
Copy link
Member

Agree, but I think the right package name is Aspire.Hosting.Certbot because its not actually from LetsEncrypt. But we can make LetsEncrypt the default since that is what everyone normally thinks about.

…ertbotCertificates to WithServerCertificates

Co-authored-by: davidfowl <[email protected]>
Copy link
Contributor Author

Copilot AI commented Dec 2, 2025

@copilot let’s make this Aspire.Hosting.Certbot

Renamed to Aspire.Hosting.Certbot in commit 87bb3cd. Also renamed WithCertbotCertificates to WithServerCertificates and updated all documentation to be ACME-agnostic rather than Let's Encrypt specific.

Copilot AI changed the title Add Aspire.Hosting.LetsEncrypt integration for Certbot container support Add Aspire.Hosting.Certbot integration for Certbot container support Dec 2, 2025
Copilot finished work on behalf of davidfowl December 2, 2025 02:25
@danegsta
Copy link
Member

danegsta commented Dec 2, 2025

I don't think we need to solve all the design problems right away, but we will have to effectively have to duplicate publish and run time certificate config until we do.

I fully expect we'll end up needing something like:

public interface ICertificateResource
{
    ReferenceExpression PemFormatCertificate { get; }
    ReferenceExpression PemFormatKey { get; }
    ReferenceExpression PfxFormatCertificate { get; }
    
}

We'd also need properties to indicate whether a certificate provider can provide the Pfx or Pem format assets (I assume some will only support PFX and others only PEM). But that would be a pattern that we could easily unify with the existing experimental certificate APIs (once we worked out all the other pesky design decisions we'd have to make).

Copy link
Member

@mitchdenny mitchdenny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should get this in.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants