Self-hosted email tools usually fall into two buckets.

Some tools catch email for testing. That is where Inbucket fits.

Others help you actually manage newsletters, transactional messages, campaigns, contacts, templates, automations, and analytics. That is where Notifuse fits.

Notifuse is a modern, self-hosted emailing platform that allows you to send newsletters and transactional emails at a fraction of the cost.

The important distinction: Notifuse is not just an SMTP server. It is the email product layer you put above providers like Amazon SES, Mailgun, Postmark, Mailjet, SparkPost, SendGrid, or a generic SMTP service.

What is Notifuse?

Notifuse is a self-hosted email platform built with Go, React, and PostgreSQL.

It provides:

  • Newsletter and broadcast campaigns.
  • Transactional email templates.
  • Contact and list management.
  • Segmentation.
  • Visual MJML email builder.
  • Liquid templating.
  • Email automations.
  • A/B testing.
  • Delivery-provider integrations.
  • Webhooks.
  • Message history.
  • Open and click tracking.
  • Built-in cookieless web analytics.
  • Optional SMTP bridge.
  • Notification center widget.

If Inbucket answers “did my app send this email?”, Notifuse answers “how do I manage all the emails my product sends?”

How Notifuse Fits A Homelab

For a homelab or small product stack, Notifuse can become the control plane for product email.

Examples:

  • Send newsletters to subscribers.
  • Manage product announcement campaigns.
  • Build transactional templates for signups, invites, receipts, and notifications.
  • Segment contacts by fields or behavior.
  • Track campaign links and web conversions.
  • Build automation journeys.
  • Use a real provider only for final delivery.

It does not eliminate the need for a trustworthy email delivery provider. For production, you still want SES, Postmark, Mailgun, SendGrid, Mailjet, SparkPost, or a properly configured SMTP provider.

For testing, you can pair Notifuse with Inbucket:

Notifuse -> test SMTP -> Inbucket -> inspect captured email

That gives you a safe way to review templates before connecting real outbound mail.

Tech Overview

The backend is Go, with a clean architecture layout:

  • cmd/api for the application entrypoint.
  • config for environment and setup configuration.
  • internal/domain for business models.
  • internal/service for workflows.
  • internal/repository for PostgreSQL access.
  • internal/http for handlers and middleware.
  • internal/migrations for database migrations.

The admin console is a React and TypeScript app under console/, built with Vite, Ant Design, TanStack Router, TanStack Query, TipTap, Monaco, MJML tooling, ECharts, and Lingui.

There are also separate frontend packages for:

  • notification_center/
  • web_analytics_sdk/

PostgreSQL is the required database. The upstream Compose file uses PostgreSQL 17.

Self-Hosting Notifuse with Docker

The documented Compose path is straightforward on a clean Docker host:

git clone https://github.com/Notifuse/notifuse.git
cd notifuse
docker compose up -d

That Compose file builds the app locally and publishes:

8081 -> 8080  web app
587  -> 587   optional SMTP bridge
5433 -> 5432  PostgreSQL

On my server, I did not run that Compose file as-is.

Reason:

  • This homelab already has many running containers.
  • Port 587 is a mail-submission port and should not be casually claimed.
  • PostgreSQL did not need to be published to the host for a smoke test.
  • This Docker daemon previously failed when creating new user-defined networks because its address pools were exhausted.

So I used a safer field-test layout.

Safe Field Test Without Touching Existing Containers

This test used:

  • notifuse-safe-postgres for PostgreSQL.
  • notifuse-safe-api for the Notifuse app.
  • Docker’s existing bridge network.
  • Web host port 8326.
  • Optional SMTP bridge host port 2587.
  • No published PostgreSQL port.
  • No user-defined Docker network.

Start PostgreSQL:

docker run -d --name notifuse-safe-postgres \
  --network bridge \
  -e POSTGRES_USER=postgres \
  -e POSTGRES_PASSWORD=notifuse-safe-postgres \
  -e POSTGRES_DB=postgres \
  postgres:17-alpine

Wait until it is ready:

docker exec notifuse-safe-postgres pg_isready -U postgres

Get its bridge IP:

PG_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' notifuse-safe-postgres)

Start Notifuse:

SECRET_KEY=$(openssl rand -base64 48)

docker run -d --name notifuse-safe-api \
  --network bridge \
  -p 8326:8080 \
  -p 2587:587 \
  -e SERVER_PORT=8080 \
  -e SERVER_HOST=0.0.0.0 \
  -e ENVIRONMENT=production \
  -e DB_HOST="$PG_IP" \
  -e DB_PORT=5432 \
  -e DB_USER=postgres \
  -e DB_PASSWORD=notifuse-safe-postgres \
  -e DB_PREFIX=notifuse \
  -e DB_NAME=notifuse_system \
  -e DB_SSLMODE=disable \
  -e SECRET_KEY="$SECRET_KEY" \
  -e API_ENDPOINT=http://localhost:8326 \
  -e WEBHOOK_ENDPOINT=http://localhost:8326 \
  -e TELEMETRY=false \
  -e CHECK_FOR_UPDATES=false \
  notifuse/notifuse:latest

Then open:

http://localhost:8326/console

From another device on your LAN:

http://SERVER_IP:8326/console

What Worked In The Field Test

The container became healthy:

curl http://localhost:8326/healthz

Response:

{"status":"ok"}

The root path redirected to the console:

/ -> /console

The console served HTML successfully at:

http://localhost:8326/console

Setup status returned:

{
  "is_installed": false,
  "smtp_configured": false,
  "api_endpoint_configured": true,
  "root_email_configured": false,
  "smtp_bridge_configured": false,
  "oidc_configured": false
}

That is the expected first-run state. The app is alive, PostgreSQL is connected, and the setup wizard is waiting for the root email and SMTP configuration.

The logs also confirmed:

  • App version 38.0.
  • PostgreSQL connection succeeded.
  • First-run database version initialized.
  • Setup wizard required.
  • GeoIP database loaded.
  • Server started on 0.0.0.0:8080.

Completing Setup

The setup wizard asks for things such as:

  • Root administrator email.
  • API endpoint.
  • SMTP settings.
  • Telemetry/update preferences.
  • Optional SMTP bridge settings.
  • Optional OIDC settings.

For a local test, you can use:

API endpoint: http://localhost:8326

For production, use your real HTTPS endpoint:

https://mail.yourdomain.com

For outbound SMTP, either connect a real delivery provider or use a test sink like Inbucket while you are learning.

Important Production Notes

Do not reuse the default SECRET_KEY from example files.

Generate one:

openssl rand -base64 48

Keep PostgreSQL private:

Do publish:     Notifuse web/API port behind HTTPS
Do not publish: PostgreSQL directly to the internet

Use a reverse proxy such as Caddy, Traefik, Nginx, or Cloudflare Tunnel for the web console.

Be careful with the SMTP bridge. Publishing port 587 means you are exposing an SMTP listener. Only enable it when you understand the authentication, TLS, and routing model.

Notifuse vs Inbucket

These two tools are complementary.

Tool Use Case
Inbucket Catch and inspect fake/test emails
Notifuse Manage real campaigns, transactional email, templates, contacts, automations, and analytics

During development:

Notifuse -> Inbucket

In production:

Notifuse -> SES/Postmark/Mailgun/SendGrid/Mailjet/SparkPost/SMTP

Things I Did Not Do

For this first pass, I stopped at the safe setup-wizard boundary.

I did not:

  • Complete the setup wizard.
  • Create a root admin account.
  • Configure a real SMTP provider.
  • Send real email.
  • Expose Notifuse publicly.
  • Publish PostgreSQL to the host.
  • Run the upstream Compose file as-is.
  • Create a new Docker network.

That is intentional. It confirms the app runs without risking your current homelab containers or accidentally sending mail.

Conclusion

Notifuse is a serious self-hosted email platform, not a tiny utility.

It brings together campaign sending, transactional email, contacts, automations, templates, provider integrations, and analytics in one Go/React/PostgreSQL application. The safe Docker test worked on this server with high ports and without touching existing containers.

If you want to evaluate it further, the next practical step is to complete the setup wizard using a test SMTP target, ideally Inbucket, before connecting a real delivery provider.

Notifuse is open source under the AGPL-3.0 license.

FAQ