Mailpit 安裝與使用
Mailpit 安裝與使用
前言
開發時最麻煩的事情之一,就是測試寄信功能。
填完表單按下送出,然後……什麼都沒發生。是寄出去了嗎?還是掉了?
跑去收信匣看,沒有。垃圾桶?也沒有。然後開始猜:是 SMTP 設定錯了?還是信被黑洞吸走了?
更慘的是,如果你不小心寄真的信出去……恭喜,你就變成那個「我只是在測試系統」的工程師,
然後客戶打電話進來問說:「你們剛剛寄了一封主旨是『test123』的信給我,這是什麼?」

這時候你就需要一個假郵件伺服器。
Mailpit 就是這樣的工具!它可以攔截所有寄出的信,不會真的寄給任何人,
然後用一個乾淨的 Web 介面讓你查看每封信長什麼樣子。
開發測試的好夥伴,絕對不能沒有它!
部署目標
用 Docker 把 Mailpit 架起來,讓開發環境的寄信功能有個安全的落點。
Docker Compose 部署
1. 建立專案目錄
mkdir mailpit
cd mailpit資料夾名稱隨你高興,反正最後找得到就好。
2. 建立 docker-compose.yml
services:
mailpit:
image: axllent/mailpit
container_name: mailpit
restart: unless-stopped
volumes:
- ./volumes/data:/data
ports:
- 8025:8025 # Web UI & API server
- 1025:1025 # SMTP server
environment:
MP_MAX_MESSAGES: 5000
MP_DATABASE: /data/mailpit.db
MP_UI_AUTH_FILE: /data/password-file
MP_SMTP_AUTH_ACCEPT_ANY: 1
MP_SMTP_AUTH_ALLOW_INSECURE: 1
networks:
- docker-network
# 如果有後端要連線就要掛在同個虛擬網路下才能連到
networks:
docker-network:
name: docker-network # 網路名稱(可被其他 compose 檔案參考)
driver: bridge # 橋接模式:容器間可通訊,但與宿主機隔離
driver_opts:
com.docker.network.driver.mtu: "1450" # 設定 MTU 為 1450 解決網路連線問題
external: true # 使用已存在的橋接網路幾個環境變數說明一下:
| 變數 | 說明 |
|---|---|
MP_MAX_MESSAGES | 最多保留幾封信,超過就自動刪舊的 |
MP_DATABASE | 信件資料庫路徑 |
MP_UI_AUTH_FILE | Web 介面的帳號密碼檔案路徑 |
MP_SMTP_AUTH_ACCEPT_ANY | 接受任何 SMTP 帳密(開發用,不驗證帳號密碼正確性) |
MP_SMTP_AUTH_ALLOW_INSECURE | 允許不加密的 SMTP 連線 |
3. 建立資料目錄與密碼檔
mkdir -p volumes/data建立 Web 介面的登入帳號密碼檔:
echo "admin:1234" > volumes/data/password-file帳號密碼格式為
帳號:密碼,每行一組。
這是開發用途,密碼設簡單點自己看得懂就好!
4. 啟動服務
docker-compose up -d
-d就是「我要在背景偷偷執行,不要吵我」的意思
初始設定與測試
1. 檢查服務狀態
# 查看容器狀態
docker-compose ps
# 查看日誌
docker-compose logs mailpit看到 mailpit running 就代表成功了!
2. 存取 Web 管理介面
開啟瀏覽器前往:http://你的伺服器IP:8025
- 帳號:
admin - 密碼:
1234
登入後就能看到 Mailpit 的收件匣介面。現在把你的應用程式 SMTP 指向這台伺服器的 1025 port,
所有寄出的信就會被攔截到這裡,不會真的送出去了!
C# 實作
伺服器架好了,接下來讓 C# 應用程式把信寄進去。
1. 安裝 NuGet 套件
dotnet add package MailKit
MailKit是 .NET 的 SMTP 寄信套件,並非專屬 Mailpit 使用。
只要是走 SMTP 協定的郵件伺服器(Gmail、Outlook、自架 SMTP 等)都能用它來寄信。MailKit包含了MimeKit,裝一個就夠。
2. 設定 appsettings.json
{
"Email": {
"Host": "localhost",
"Port": 1025,
"UserName": "test",
"Password": "test",
"UseSsl": false,
"FromName": "系統通知",
"FromAddress": "[email protected]"
}
}
MP_SMTP_AUTH_ACCEPT_ANY: 1讓 Mailpit 接受任何帳密,
所以UserName/Password隨便填都可以過。
3. 設定模型
public class EmailConfig
{
public string Host { get; set; } = string.Empty;
public int Port { get; set; } = 1025;
public string UserName { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
public bool UseSsl { get; set; }
public string FromName { get; set; } = string.Empty;
public string FromAddress { get; set; } = string.Empty;
}4. EmailSender 實作
using MailKit.Net.Smtp;
using MimeKit;
using System.Text;
public class EmailSender
{
private readonly EmailConfig _config;
public EmailSender(EmailConfig config)
{
_config = config;
}
public async Task SendAsync(string toName, string toAddress, string subject, string htmlBody)
{
var message = new MimeMessage();
message.From.Add(new MailboxAddress(Encoding.UTF8, _config.FromName, _config.FromAddress));
message.To.Add(new MailboxAddress(Encoding.UTF8, toName, toAddress));
message.Subject = subject;
message.Body = new BodyBuilder
{
HtmlBody = htmlBody,
TextBody = htmlBody
}.ToMessageBody();
using var client = new SmtpClient();
await client.ConnectAsync(_config.Host, _config.Port, _config.UseSsl);
await client.AuthenticateAsync(_config.UserName, _config.Password);
await client.SendAsync(message);
await client.DisconnectAsync(true);
}
}5. 使用範例
Program.cs(讀取 appsettings.json)
var config = builder.Configuration
.GetSection("Email")
.Get<EmailConfig>()!;
builder.Services.AddSingleton(config);
builder.Services.AddScoped<EmailSender>();注入使用
public class SomeService(EmailSender emailSender)
{
public async Task NotifyUser()
{
await emailSender.SendAsync(
toName: "王小明",
toAddress: "[email protected]",
subject: "您好,這是測試信件",
htmlBody: "<h1>Hello!</h1><p>這封信應該只會出現在 Mailpit,不會真的送出去。</p>"
);
}
}寄出後打開 http://你的伺服器IP:8025,信就乖乖躺在那裡等你審閱了!