惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
Docker
月光博客
月光博客
B
Blog RSS Feed
C
Check Point Blog
WordPress大学
WordPress大学
T
Tailwind CSS Blog
GbyAI
GbyAI
H
Help Net Security
Y
Y Combinator Blog
I
InfoQ
雷峰网
雷峰网
阮一峰的网络日志
阮一峰的网络日志
小众软件
小众软件
美团技术团队
博客园 - 三生石上(FineUI控件)
MongoDB | Blog
MongoDB | Blog
Jina AI
Jina AI
A
About on SuperTechFans
G
Google Developers Blog
爱范儿
爱范儿
F
Fortinet All Blogs
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
U
Unit 42
人人都是产品经理
人人都是产品经理

Dallas Lu

一些没有意义的事情 博客程序的一次大重构 OpenWRT 使用 udp2raw 对抗 WireGuard 阻断 如何证明你是原创作者 Nginx 泛域名配置的隐患与对策 WISeID S/MIME 证书 V2EX 刑满释放记 使用 Radicale 在 Ubuntu 24.04 中搭建 vCards CardDav 服务 邮件服务的域名成功从 SURBL 黑名单移除 The Domain of Mail successfully removed from SURBL blacklist 网站多语言的设计细节 Website Multilingual Design Details 网站评论系统的目前进展和展望 Current Progress and Outlook of the Website Comment System 在公网使用 iptables 转发端口时保留客户端 IP Retaining Client IP with iptables Port Forwarding on Public Networks 邮件投递平台 Postal 的使用经验 Experience with Using Postal, the Mail Delivery Platform 自建 Postal 完美替代 SendGrid 互联网在崩塌吗,然后呢 Is the Internet collapsing and then what 在 SvelteKit 应用中使用 JSON-LD Using JSON-LD in SvelteKit Applications 网页的打印样式应该怎么写 How to write print styles for web pages “茴字的四种写法”之 IP 与域名 Trivia: Special ways of writing IP and domain names 怎么伪造 Git 提交的时区 How to fake the timezone of a git commit 供大众交流的论坛和其它替代产品还是不好用
Build Your Own SendGrid: Postal SMTP Server
Dallas Lu · 2024-06-28 · via Dallas Lu

Cloudflare’s email routing feature is quite useful. Additionally, I have been using SendGrid for sending emails and have been on the lookout for alternatives. Self-hosted email options include Mail-in-a-box, Docker-mailserver, MailCow, among others. However, sometimes I don’t need an inbox, so I decided to try Postal as a replacement for SendGrid. This article documents the installation and usage of Postal.

Preparation

A Domain Name

Usually, a subdomain is sufficient, such as postal.example.com. This will be used for management and configuration purposes. Once installed, you can bind new domains to send and receive emails.

A VPS

It’s best to have a VPS dedicated to running Postal, allowing traffic on port 25, with both IPv4 and IPv6 public IPs, and set rDNS to resolve to postal.example.com, which is crucial for successful email delivery.

How to Test If Your VPS Allows Traffic on Port 25

Test Connection to Other Servers on Port 25
telnet smtp.google.com 25
Test If External Servers Can Connect to Your VPS on Port 25

Listen on port 25 on your VPS:

nc -l -p 25

Allow inbound traffic on port 25, for example, using UFW:

ufw allow 25/tcp

Connect to your local port 25 from an external server:

telnet <YOUR_VPS_IP> 25

Luckily, the ServerHub Dedicated Hosting I’m using doesn’t have a port 25 restriction. At the same time, the DMIT I’m using doesn’t allow IPv4 outbound traffic on port 25. But it allows inbound traffic on port 25, which should probably be credited to Tao Shu 1.

Install Postal

Postal recommends at least 4GB of RAM and 25GB of storage space. I used a freshly installed Ubuntu 22.04 to run Postal.

apt install git curl jq
git clone https://github.com/postalserver/install /opt/postal/install
sudo ln -s /opt/postal/install/bin/postal /usr/bin/postal

Docker

Postal does not officially support Podman, so we should install Docker:

# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Add the repository to Apt sources:
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update

sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

MariaDB

You can use Docker.

docker run -d \
   --name postal-mariadb \
   -p 127.0.0.1:3306:3306 \
   --restart always \
   -e MARIADB_DATABASE=postal \
   -e MARIADB_ROOT_PASSWORD=postal \
   mariadb

Alternatively, you can run MariaDB without Docker. Ensure that Postal has all privileges on the postal and postal-% databases.

GRANT ALL PRIVILEGES ON `postal`.* TO 'postal'@'%' IDENTIFIED BY 'YOUR_PASSWORD' WITH GRANT OPTION;
GRANT ALL PRIVILEGES ON `postal\-%`.* TO 'postal'@'%' IDENTIFIED BY 'YOUR_PASSWORD' WITH GRANT OPTION;
FLUSH PRIVILEGES;

To log emails, confirm that innodb_log_file_size is ten times the maximum email size. Check the current configuration 2:

SHOW GLOBAL VARIABLES LIKE 'innodb_log_file_size';

Setting Up Postal

Run:

postal bootstrap postal.yourdomain.com

Edit the generated configuration file to set the database password, etc.:

vim /opt/postal/config/postal.yml

ghcr.io

Visit https://github.com/settings/tokens/new to generate a classic token3

export CR_PAT=YOUR_TOKEN
export ghcr_user=YOUR_GITHUB_USERNAME
echo $CR_PAT | docker login ghcr.io -u $ghcr_user -password-stdin

Initialize the Database and More

postal initialize

Create an Admin User

postal make-user

Start Postal

postal start

Caddy

docker run -d \
   --name postal-caddy \
   --restart always \
   --network host \
   -v /opt/postal/config/Caddyfile:/etc/caddy/Caddyfile \
   -v /opt/postal/caddy-data:/data \
   caddy

Configuring DNS Records

Create A and AAAA records for postal.example.com pointing to your server’s IP. Follow https://docs.postalserver.io/getting-started/dns-configuration to configure other DNS records.

In the configuration file, the domains in dns.mx_records should all be CNAMEs to postal.example.com.

Using Postal

Access postal.example.com, create an organization, then create a mail server, add a domain, configure the DNS records for the mail domain as prompted on the page, and verify them.

Go to Messages -> Send Message to send a test email. Visit https://www.mail-tester.com to get a test email address and send a test email to see if you can achieve a perfect score.

In Credentials, you can add SMTP credentials to start sending emails.

It’s recommended to enable privacy mode in the settings to avoid leaking the IP addresses of SMTP clients.

Conclusion

Postal also supports email receiving features similar to Cloudflare’s email routing, allowing forwarding to mailboxes or HTTP endpoints. Recently, my SendGrid account became inaccessible for unknown reasons. After using Postal for a while, I found it can completely replace services like SendGrid and offers more freedom.


  1. 涛叔. 记录开通 25 号端口的经历. Taoshu.in. 2022. ↩

  2. https://mariadb.com/docs/server/storage-engines/innodb/operations/configure-redo-log/

  3. Andrew Hoog. Authorizing GitHub Container Registry. DON’T PANIC. 2023 ↩