Skip to main content
net10.0net8.0net9.0

An Aspire hosting integration for Posta.

Published
Sep 12, 2026
1mo ago
Total Downloads
1.2K
1,208

Install

dotnet add package CommunityToolkit.Aspire.Hosting.Posta --version 13.5.1-beta.752
ProductVersions
.NET
net10.0net8.0net9.0

README

Posta hosting integration

Use this integration to model, configure, and orchestrate the Posta self-hosted email delivery platform in an Aspire AppHost.

Getting started

Install the package in your AppHost project:

aspire add CommunityToolkit.Aspire.Hosting.Posta

Basic usage

var builder = DistributedApplication.CreateBuilder(args);

var postgresPassword = builder.AddParameter("postgres-password", secret: true);
var postgres = builder.AddPostgres("postgres", password: postgresPassword);
var database = postgres.AddDatabase("posta-db", "posta");
var redis = builder.AddRedis("redis");

var posta = builder.AddPosta("posta", database, redis);

builder.AddProject<Projects.Api>("api")
    .WithReference(posta)
    .WaitFor(posta);

builder.Build().Run();

To persist filesystem-backed attachments across container restarts, add a named volume or a host bind mount:

var posta = builder.AddPosta("posta", database, redis)
    .WithDataVolume();

// Alternatively:
// .WithDataBindMount("./data/posta");

Posta stores data in PostgreSQL, uses Redis for queueing, and runs the embedded worker in the main container by default. AddPosta requires PostgreSQL database and Redis resources so the container starts with the dependencies it needs.

Configuration

Use the PostaOptions callback when values are known in the AppHost and can be represented as typed literal values. Secret values inside PostaOptions, such as OAuth client secrets, S3 keys, SMTP passwords, encryption keys, inbound webhook secrets, POSTA_DB_URL, and Redis passwords, should still be passed as Aspire parameters.

var encryptionKey = builder.AddParameter("posta-encryption-key", secret: true);
var smtpPassword = builder.AddParameter("posta-smtp-password", secret: true);

var posta = builder.AddPosta("posta", database, redis, options =>
{
    options.Environment = "production";
    options.WebUrl = "https://mail.example.com";
    options.ApiUrl = "https://mail.example.com";
    options.CorsOrigins = "https://app.example.com";
    options.MetricsEnabled = true;
    options.EncryptionKey = encryptionKey;

    options.SystemSmtpHost = "smtp.example.com";
    options.SystemSmtpPort = 587;
    options.SystemSmtpPassword = smtpPassword;
    options.SystemSmtpFrom = "[email protected]";
    options.SystemSmtpEncryption = "starttls";
});

For production deployments, configure EncryptionKey. Posta uses it for AES-256-GCM encryption of stored SMTP passwords; without it, those passwords are only base64-encoded. Keep this value stable across container restarts and upgrades.

For values coming from configuration, environment variables, user secrets, or publish-time parameters, use the grouped parameter-based methods. These methods accept options objects whose properties are IResourceBuilder<ParameterResource>?, so they work with AddParameter and AddParameterFromConfiguration.

var smtpHost = builder.AddParameterFromConfiguration("posta-smtp-host", "Posta:Smtp:Host");
var smtpPort = builder.AddParameterFromConfiguration("posta-smtp-port", "Posta:Smtp:Port");
var smtpUsername = builder.AddParameterFromConfiguration("posta-smtp-username", "Posta:Smtp:Username");
var smtpPassword = builder.AddParameterFromConfiguration("posta-smtp-password", "Posta:Smtp:Password", secret: true);
var smtpFrom = builder.AddParameterFromConfiguration("posta-smtp-from", "Posta:Smtp:From");
var smtpEncryption = builder.AddParameterFromConfiguration("posta-smtp-encryption", "Posta:Smtp:Encryption");

var googleClientId = builder.AddParameterFromConfiguration("posta-google-client-id", "Posta:GoogleOAuth:ClientId");
var googleClientSecret = builder.AddParameterFromConfiguration("posta-google-client-secret", "Posta:GoogleOAuth:ClientSecret", secret: true);
var googleCallbackUrl = builder.AddParameterFromConfiguration("posta-google-callback-url", "Posta:GoogleOAuth:CallbackUrl");

var s3Endpoint = builder.AddParameterFromConfiguration("posta-s3-endpoint", "Posta:S3:Endpoint");
var s3Region = builder.AddParameterFromConfiguration("posta-s3-region", "Posta:S3:Region");
var s3Bucket = builder.AddParameterFromConfiguration("posta-s3-bucket", "Posta:S3:Bucket");
var s3AccessKey = builder.AddParameterFromConfiguration("posta-s3-access-key", "Posta:S3:AccessKey", secret: true);
var s3SecretKey = builder.AddParameterFromConfiguration("posta-s3-secret-key", "Posta:S3:SecretKey", secret: true);

var posta = builder.AddPosta("posta", database, redis)
    .WithSystemSmtp(options =>
    {
        options.Host = smtpHost;
        options.Port = smtpPort;
        options.Username = smtpUsername;
        options.Password = smtpPassword;
        options.From = smtpFrom;
        options.Encryption = smtpEncryption;
    })
    .WithGoogleOAuth(options =>
    {
        options.ClientId = googleClientId;
        options.ClientSecret = googleClientSecret;
        options.CallbackUrl = googleCallbackUrl;
    })
    .WithS3BlobStorage(options =>
    {
        options.Endpoint = s3Endpoint;
        options.Region = s3Region;
        options.Bucket = s3Bucket;
        options.AccessKey = s3AccessKey;
        options.SecretKey = s3SecretKey;
    });

You can also configure inbound SMTP and email verification through parameter-based options:

var inboundEnabled = builder.AddParameterFromConfiguration("posta-inbound-enabled", "Posta:Inbound:Enabled");
var inboundWebhookSecret = builder.AddParameterFromConfiguration("posta-inbound-webhook-secret", "Posta:Inbound:WebhookSecret", secret: true);

var emailVerificationRequired = builder.AddParameterFromConfiguration("posta-email-verification-required", "Posta:EmailVerification:Required");

builder.AddPosta("posta", database, redis)
    .WithInboundSmtp(options =>
    {
        options.Enabled = inboundEnabled;
        options.WebhookSecret = inboundWebhookSecret;
    }, port: 2525)
    .WithEmailVerification(options =>
    {
        options.Required = emailVerificationRequired;
});

WithInboundSmtp exposes a TCP endpoint named smtp. Its host port is optional and its container target port defaults to 2525. If options.Port is supplied as a parameter, pass the same numeric value as targetPort so the endpoint and POSTA_INBOUND_SMTP_PORT remain aligned.

These SMTP features have different purposes:

  • WithSystemSmtp configures an external SMTP server used by Posta to send platform notifications. It does not expose a listener.
  • WithInboundSmtp exposes the smtp endpoint, default target port 2525, for receiving email addressed to domains managed by Posta.
  • WithSmtpRelay exposes the authenticated smtp-relay endpoint, default target port 2526, for applications that submit outgoing email over SMTP instead of the HTTP API.
var relayEnabled = builder.AddParameter("posta-relay-enabled", "true");

builder.AddPosta("posta", database, redis)
    .WithSmtpRelay(options => options.Enabled = relayEnabled);

When inbound STARTTLS is enabled, mount the certificate and private key into the container and configure their container paths. For example:

builder.AddPosta("posta", database, redis)
    .WithInboundSmtp(options =>
    {
        options.Enabled = inboundEnabled;
        options.TlsMode = builder.AddParameter("posta-inbound-tls-mode", "starttls");
        options.TlsCertFile = builder.AddParameter("posta-inbound-tls-cert", "/etc/posta/tls/fullchain.pem");
        options.TlsKeyFile = builder.AddParameter("posta-inbound-tls-key", "/etc/posta/tls/privkey.pem");
    })
    .WithBindMount("./certs", "/etc/posta/tls", isReadOnly: true);

API overview

Method Purpose
AddPosta(name, database, redis) Adds Posta and configures PostgreSQL and Redis references.
AddPosta(name, database, redis, PostaOptions) Adds Posta with typed environment configuration.
AddPosta(name, database, redis, Action<PostaOptions>) Adds Posta with callback-based typed environment configuration.
WithReference(PostgresDatabaseResource) Configures the PostgreSQL database environment variables and waits for the database.
WithReference(RedisResource, redisPassword) Configures Redis address/password environment variables and waits for Redis.
WithDataVolume(name, isReadOnly) Adds a named volume at /data for filesystem-backed attachments.
WithDataBindMount(source, isReadOnly) Adds a host bind mount at /data for filesystem-backed attachments.
WithSystemSmtp(PostaSystemSmtpOptions) Configures parameter-based system SMTP settings.
WithSystemSmtp(Action<PostaSystemSmtpOptions>) Configures parameter-based system SMTP settings with a callback.
WithInboundSmtp(PostaInboundSmtpOptions, port, targetPort) Configures inbound SMTP and exposes the smtp TCP endpoint.
WithInboundSmtp(Action<PostaInboundSmtpOptions>, port, targetPort) Configures inbound SMTP with a callback and exposes the smtp TCP endpoint.
WithSmtpRelay(PostaSmtpRelayOptions, port, targetPort) Configures authenticated SMTP submission and exposes the smtp-relay TCP endpoint.
WithSmtpRelay(Action<PostaSmtpRelayOptions>, port, targetPort) Configures authenticated SMTP submission with a callback.
WithS3BlobStorage(PostaS3BlobStorageOptions) Configures parameter-based S3-compatible attachment storage and sets the blob provider to s3.
WithS3BlobStorage(Action<PostaS3BlobStorageOptions>) Configures parameter-based S3-compatible attachment storage with a callback and sets the blob provider to s3.
WithGoogleOAuth(PostaGoogleOAuthOptions) Configures parameter-based Google OAuth login settings.
WithGoogleOAuth(Action<PostaGoogleOAuthOptions>) Configures parameter-based Google OAuth login settings with a callback.
WithEmailVerification(PostaEmailVerificationOptions) Configures parameter-based email verification settings.
WithEmailVerification(Action<PostaEmailVerificationOptions>) Configures parameter-based email verification settings with a callback.

Use PostaOptions.DatabaseUrl, PostaOptions.RedisAddress, and PostaOptions.RedisPassword only when you need to override the generated PostgreSQL or Redis environment values.

Connection Properties

The Posta resource exposes the following connection properties:

Name Format
Host Posta HTTP API host
Port Posta HTTP API port
Uri http://{host}:{port}

These properties become environment variables named [RESOURCE]__HOST, [RESOURCE]__PORT, and [RESOURCE]__URI when referenced by another resource. The connection string uses Endpoint=http://{host}:{port}.

Additional documentation

Feedback & contributing

https://github.com/CommunityToolkit/Aspire

Changes from Previous Version

No structural changes between v13.5.1-beta.751 and v13.5.1-beta.752.

Adoption Assessment

A verified publisher signal is available. Assess fit from the package's supported frameworks, license and dependency graph rather than popularity alone.

This version is marked prerelease. Validate its API and upgrade path before production use.Compatibility metadata lists 3 target frameworks; confirm the exact target used by your application.

Related Guides & Workflows

Learn how to evaluate, integrate, or audit this package in your .NET project.