Yeah, those are similar but narrower scope tools. They do one thing, sit behind a firewall, listen on port 25 and forward SMTP submissions to sendgrid/mailgun's endpoint using an API key.
Posthorn adds an HTTP form endpoint (which is safe to expose to the internet), a JSON API with Bearer auth and idempotency, and a provider abstraction so you can use a broad range of providers via config.
If you just need to forward SMTP requests behind a firewall to a single provider, those are far simpler solutions and Posthorn is overkill. The moment you need anything outside of that, I couldn't find a solution that worked and that's the gap I built Posthorn to fill.
Happy to take any feedback on my approach, either here or in GitHub issues.
No, Posthorn is outbound only. DMARC aggregate reports come back as inbound mail to whatever address you put in your rua tag and Posthorn has no inbox or IMAP to receive them.
Parsedmarc is still the right tool if you want to self host reporting, otherwise you should look into solving this with your provider. Explicitly trying to avoid dealing with all the operational costs of running a mail server, just trying to enable email capabilities in apps that need it so it's beyond the scope of what I built here.
If I'm understanding it right, protonmail-bridge exposes an IMAP and SMTP interface to your local mail client so that if you want to use something like Outlook or Apple Mail to talk to ProtonMail you can.
Similar idea in that it receives SMTP and transforms it to a provider specific API but it's unique for the ProtonMail use case of bridging to your personal mail client and it handles both sending (SMTP) and receiving (IMAP).
Posthorn is server side and outbound only. It runs in your stack and enables apps to send email that otherwise can't. It fronts multiple transactional providers via config and doesn't touch inbound at all.
Nice. Sounds like a neat way to get the best of all worlds. Self hosted email without exposing your IP, leverage a third party with an existing trusted send reputation but still maintain full ownership of the stack.
How much effort has it been to keep it running? Glad that it works for you!
Fair. I was trying to convey self hosted benefits without the downside of hosting your own MTA. I was also really in my head on the niche and assumed everyone else would get it from the snappy title. Not my intent to mislead.
My current plans are for Posthorn to stay focused on email. There's enough work here that I think it justifies a dedicated tool.
I have some v2 roadmap ideas for things like multiple outputs per endpoint so that a contact form submission can fire both an email and a webhook in the same call to support things like form -> email + slack or script triggers an email + pager duty alert.
That's complimentary to the email though, not something I had planned to build out as a stand alone use case. I'd be interested in hearing how that would be useful for you though!
We've chosen Apprise just for the big number of services supported, actually at the moment we only use email and telegram as notification output channels.
Apprise does not accept SMTP protocol as input, so you're bound exclusively to API, binary exec or third party integrations.
I think Posthorn could fill a gap if it will integrate the possibility to send a webhook (alongside/instead of email).
Awesome. This is helpful, thanks. You're doing my market research for me!
Seems like most setups only really need 2-3 channels, rather than the ~140 supported by Apprise. Definitely worth me looking into when I start to work towards a v2 release and supporting webhooks in general.
The part I'm not sure about yet is how I'm going to implement it. My current approach is to custom write a transport layer for each provider, so a generic webhook would be the first non-bespoke transport. I don't want to lock myself into the path of writing a bespoke solution for every email provider and every channel (that's basically reimplementing Apprise in Go with better email support). I'm hoping I can get a generic webhook that would be good enough for most use cases.
I'll also need to think about if I want to support an email + webhook use case or pick one per request. If I built that and you deployed it for email + telegram, would that be good enough for your use case? You could also just deploy it alongside Apprise if you have an email need that we handle better (and I think we definitely do, especially once I ship html email in 1.x).
If you do end up using Posthorn, please let me know how it goes and feel free to open up any issues you see on GitHub.
Fair. Don't disagree with anything you're saying here.
I should probably tighten up that line. What I really meant to say is that the average self-hoster who just wants to enable a few services to send email doesn't want to run a mail server. Different audiences, different (and both correct) answers.
I set out to solve some pretty specific problems of my own but I'm genuinely curious how others have tackled these things. Posthorn and Postal don't compete in my head. Postal makes you into your own provider, which is something I personally deeply want to avoid. Posthorn assumes you've already picked a provider (which might be Postal, actually, it would work just fine pointed at a self-hosted Postal instance).
> the average self-hoster who just wants to enable a few services to send email doesn't want to run a mail server
Maybe I'm confused, maybe the label "self-hoster" is broader than the definition in my mind, but that's exactly what self-hosters want to do, that's why we call ourselves self-hosters, we want to host the stuff we use ourselves :)
If I just wanted to "enable a few services" I'd use AWS or whatever the modern alternatives are.
I think you are confused. I self-host a ton of stuff. One thing I have zero interest in is hosting mail and dealing with all of the configuration and possible timebombs waiting before I can even do the single thing I want the service to do. Instead I pay like $5/month for essentially unlimited emails from any domain I control.
That said, none of it has to do with my own personal email, which has been on Gmail for long enough to drink, so we are probably talking about two different situations.
I think the label "self-hoster" might be overly broad in these sort of discussions. Some people considering firing up a VPS and running something like Posthorn "self-hosting" email, just like a bunch of "modern" AI tooling says "local-first" because the CLI runs locally, although all LLM models are remotely called.
Seems to me like there a broad spectrum of "self-hosters", ranging from "I run everything on my hardware in my home" to "I deploy FOSS SaaS software to AWS for us to run", probably neither of these are more/less "self-hosting" than the other.
Damnit, sunk by the T.S. Eliot thing again: “It is impossible to say just what I mean”. I host a bunch of services on a handful of machines locally. The main one of which died two weeks ago and is waiting on a new SSD drive so we can properly test whether the Anible playbook Claude put together for me will spin nine or ten services right back up or whether it’s going to be perfected for the third time I have to build the machine.
> If I just wanted to enable a few services I'd use AWS or whatever
But then you'd be using AWS for those services too.
I think there's a meaningful gap between folks who are willing and able to self host their own applications but have decided that running their own MTA is a separate and much harder commitment. Different line, but still self-hosting in any reasonable read of the term. I've been on both sides of that line at one point, I'm trying to avoid going back. :)
> But then you'd be using AWS for those services too.
Yes, so obviously as a self-hoster, that's a no-go. Hence not wanting "to enable a few services", it'd go directly counter to the initial objectives.
But yeah, I hear and agree that there is a spectrum here, self-hosting some parts while relying on others can be a good balance, especially if you have other requirements to consider, like time or resource investments, it's not a black & white decision you should make without careful considerations.
If the self hosters runs a mail server it can receive their transactional emails to themselves and they don't even need to care about delivery to gmail
1) Posthorn doesn't host email - no inbox, no IMAP so it doesn't replace what it sounds like all-inkl is doing for you. All it does is take the outgoing messages from any of your hosted/local apps and take care of the plumbing of handing them off to a transactional provider (like Resend or Postmark). Those servers are the ones sending the mail, using their IPs and their sending reputation. Any blacklist concern is really tied to your sending domain and not a new risk from Posthorn. Just the same setup you'd do if you were calling something like Resend directly. If you're following their guidelines, you'll be fine.
2) On the VPS side, if your goal is to be able to ssh in, install some stuff and run your own services, something like Hetzner is a well regarded EU centric option with solid technical support baked in. Security is mostly on you and down to what you install and how you configure it. That can be a huge learning curve and a whole other kettle of fish, definitely not without risk.
Nullmailer's a good call for a single-app use case. It's basically what I was doing.
Posthorn ended up the way it did because I had three different things all hitting Resend at the same time: a contact form, a couple of apps that only had SMTP email support and some scripts I wanted to email results from. I didn't want to have to maintain three different things doing functionally the same routing. Putting them in one binary helped me consolidate credentials and logs.
You're not wrong about the split though, I thought about breaking the two out. I'd originally written the http form handler as a caddy module (which I called caddy-formward to be cute) but ultimately I went the other way because the code after the ingress is the same regardless of how you come into the service and I didn't want to rewrite all that logic.
Have you encountered a similar issue with multiple apps where nullmailer hasn't been enough? Curious how you handled it if so.
Posthorn adds an HTTP form endpoint (which is safe to expose to the internet), a JSON API with Bearer auth and idempotency, and a provider abstraction so you can use a broad range of providers via config.
If you just need to forward SMTP requests behind a firewall to a single provider, those are far simpler solutions and Posthorn is overkill. The moment you need anything outside of that, I couldn't find a solution that worked and that's the gap I built Posthorn to fill.
Happy to take any feedback on my approach, either here or in GitHub issues.