لماذا الانتقال من MailHog إلى Mailpit
MailHog لم يعد مُصانًا منذ أواخر عام 2022. يتراكم فيه تبعيات قديمة، وواجهته تعود إلى السنوات الأولى من Bootstrap، ولم تتطور واجهته البرمجية قط. يعالج Mailpit كل هذه النقاط: يخضع لتطوير نشط (أحدث إصدار في 2024)، ويوفر واجهة تفاعلية في الوقت الفعلي، ويكشف واجهة برمجية REST متوافقة مع MailHog لتجنب كسر النصوص البرمجية الحالية.
لا تتطلب عملية الانتقال أي ترحيل بيانات: لا يحتفظ Mailpit بأي شيء افتراضيًا. كل إعادة تشغيل تبدأ بصندوق بريد فارغ، وهو بالضبط السلوك المطلوب في خط أنابيب الاختبار.
ما يقدمه Mailpit عمليًا
- واجهة حديثة مع البحث في النص الكامل، وعرض HTML/نص، ومعاينة الهاتف المحمول، وفحص الرؤوس
- ملف تنفيذي Go منفرد مُجمَّع بشكل ثابت — لا تبعيات للنظام، يعمل في حاوية بحجم 20 ميغابايت
- استهلاك الذاكرة أقل من 50 ميغابايت في وضع الخمول، مستقر حتى مع آلاف الرسائل في الجلسة
- REST API متوافقة مع MailHog (
/api/v1/messages،/api/v1/search) للنصوص البرمجية الحالية - دعم SMTP المُصادق عليه، وTLS اختياري، والتحكم في الوصول عبر الشبكة
- Webhook قابل للتكوين لإبلاغ نقطة نهاية خارجية عند كل استقبال بريد إلكتروني
المتطلبات الأساسية
يكفي VPS يعمل بـ Debian 12 أو Ubuntu 22.04/24.04 مع Docker وDocker Compose v2 مثبتَين. يُعد Mailpit من أخف الأدوات في الكتالوج: خطط لـ 1 vCPU مشترك و256 ميغابايت من ذاكرة الوصول العشوائي للاستخدام في التطوير أو CI. يُوصى باستخدام نطاق فرعي مخصص (mail.your-domain.com) للوصول إلى الواجهة من المتصفح عبر HTTPS.
المنافذ المستخدمة: 1025 (SMTP) و8025 (واجهة الويب). إذا كان خدمة بريد إلكتروني تعمل بالفعل على المنفذ 1025، ستحتاج إلى تغيير منفذ Mailpit (انظر قسم استكشاف الأخطاء).
نشر Mailpit في 5 خطوات
إنشاء الدليل وملف Compose
mkdir -p /opt/mailpit && cd /opt/mailpitأنشئ ملف
docker-compose.ymlالتالي:services: mailpit: image: axllent/mailpit:latest container_name: mailpit restart: unless-stopped ports: - "127.0.0.1:1025:1025" - "127.0.0.1:8025:8025" environment: MP_MAX_MESSAGES: 500 MP_SMTP_AUTH_ACCEPT_ANY: "true" MP_SMTP_AUTH_ALLOW_INSECURE: "true" MP_UI_AUTH: "admin:changeme" volumes: - mailpit_data:/data volumes: mailpit_data:المنافذ مرتبطة بـ
127.0.0.1فقط: لا يُكشف Mailpit مباشرة على IP العام. المتغيرMP_UI_AUTHيفعّل مصادقة HTTP الأساسية على واجهة الويب — غيّر كلمة المرور.MP_MAX_MESSAGESيحد من عدد الرسائل المحفوظة في الذاكرة لكل جلسة.تشغيل الحاوية
docker compose up -d docker compose logs -f mailpitالسطر
starting on [::]:1025يؤكد أن خادم SMTP يستمع. تحقق من ربط المنافذ بـ localhost:ss -tlnp | grep -E '1025|8025'المتوقع:
127.0.0.1:1025و127.0.0.1:8025فقط — ليس0.0.0.0أبدًا.تكوين الوكيل العكسي Nginx
أنشئ
/etc/nginx/sites-available/mailpit:server { listen 443 ssl; server_name mail.your-domain.com; ssl_certificate /etc/letsencrypt/live/mail.your-domain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/mail.your-domain.com/privkey.pem; location / { proxy_pass http://127.0.0.1:8025; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_read_timeout 86400; } }proxy_read_timeout 86400ضروري لاتصالات WebSocket المستخدمة من قبل الواجهة الفورية. فعّل vhost وأعد تحميل Nginx:ln -s /etc/nginx/sites-available/mailpit /etc/nginx/sites-enabled/ nginx -t && systemctl reload nginxaحصل على شهادة Let's Encrypt إذا لم يكن ذلك مكتملًا:
certbot --nginx -d mail.your-domain.comاختبار الإرسال باستخدام curl
تحقق من استقبال خادم SMTP للرسالة:
curl --url 'smtp://127.0.0.1:1025' \ --mail-from '[email protected]' \ --mail-rcpt '[email protected]' \ --upload-file - <<EOF From: [email protected] To: [email protected] Subject: Mailpit Test Test message body. EOFافتح بعد ذلك
https://mail.your-domain.comفي متصفحك. يجب أن تظهر الرسالة في الواجهة. إذا قمت بتكوينMP_UI_AUTH، أدخل بيانات الاعتماد عند مطالبة المصادقة الأساسية.تكوين تطبيقك للإشارة إلى Mailpit
في ملف
.env(Laravel، Symfony، n8n، Django…)، استبدل تكوين SMTP بـ:MAIL_HOST=127.0.0.1 MAIL_PORT=1025 MAIL_ENCRYPTION=null MAIL_USERNAME=null MAIL_PASSWORD=nullللتطبيقات التي تعمل في Docker على المضيف نفسه، استخدم اسم شبكة Docker أو IP للبوابة (
172.17.0.1افتراضيًا) بدلاً من127.0.0.1.
Mailpit في CI/CD: اختبار البريد الإلكتروني في خط الأنابيب
في بيئات CI، يتكامل Mailpit كخدمة مرافقة. يبدأ في ثوانٍ ولا يحتاج إلى تكوين خارجي.
تكامل CI/CD حسب إطار العمل
GitHub Actions — خدمة Mailpit
services: mailpit: image: axllent/mailpit:latest ports: - 1025:1025 - 8025:8025في متغيرات بيئة مهمتك، عيّن
MAIL_HOST=127.0.0.1وMAIL_PORT=1025. يقبل Mailpit أي بريد إلكتروني بدون مصادقة افتراضيًا — لا حاجة لتكوين SMTP إضافي.Laravel — PHPUnit
في
phpunit.xml، استبدل وسيلة النقل بـ SMTP:<env name="MAIL_MAILER" value="smtp"/> <env name="MAIL_HOST" value="127.0.0.1"/> <env name="MAIL_PORT" value="1025"/>في اختبارك، أرسل البريد ثم استعلم API Mailpit للتحقق من الاستقبال:
$response = Http::get('http://127.0.0.1:8025/api/v1/messages'); $this->assertSame($response->json('total'), 1); $this->assertStringContainsString( 'Welcome', $response->json('messages.0.Subject') );Django — pytest
في
settings.py(أوsettings_test.py):EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = '127.0.0.1' EMAIL_PORT = 1025في اختبار pytest الخاص بك، تحقق عبر API Mailpit:
import requests def test_welcome_email_sent(): r = requests.get('http://127.0.0.1:8025/api/v1/messages') assert r.json()['total'] == 1 assert 'Welcome' in r.json()['messages'][0]['Subject']n8n — اختبار سير العمل
في عقدة Send Email في n8n، قم بتكوين خادم SMTP على
127.0.0.1:1025بدون مصادقة. للتحقق تلقائيًا من أن سير العمل قد أطلق إرسالاً، استدعGET http://127.0.0.1:8025/api/v1/messagesمن عقدة HTTP Request وتحقق من الإجمالي في عقدة IF.
تأمين الوصول إلى Mailpit
يحتفظ Mailpit بالبريد الإلكتروني في الذاكرة فقط — لا ملفات على القرص، ولا قاعدة بيانات. هذه ميزة للسرية (لا آثار مستمرة)، ولكنها أيضًا قيد: إعادة التشغيل تفرغ صندوق البريد دون تحذير.
تقييد الشبكة. المنافذ 1025 و8025 مرتبطة بـ 127.0.0.1 في تكوين Docker Compose أعلاه. لا تعرضهما أبدًا على 0.0.0.0 في الإنتاج أو على خادم مشترك.
مصادقة HTTP الأساسية على الواجهة. المتغير MP_UI_AUTH=user:password يفعّل مصادقة أساسية على واجهة الويب. استخدم كلمة مرور قوية — الواجهة تكشف المحتوى الكامل لرسائل الاختبار.
SMTP المُصادق عليه. للبيئات متعددة الفرق، فعّل MP_SMTP_AUTH مع ملف حسابات بدلاً من MP_SMTP_AUTH_ACCEPT_ANY.
نصيحة: إفراغ صندوق البريد بين الاختبارات
API Mailpit تكشف نقطة نهاية للمسح: DELETE http://127.0.0.1:8025/api/v1/messages. استدعها في setUp() الخاص بـ PHPUnit أو أداة الاختبار في pytest لبدء كل اختبار بصندوق بريد فارغ، دون الحاجة إلى إعادة تشغيل الحاوية.
استكشاف الأخطاء — 4 حالات شائعة
المنفذ 1025 مشغول بالفعل. قد يكون خادم Postfix أو Sendmail محليًا يستمع على هذا المنفذ. تحقق بـ ss -tlnp | grep 1025. إذا كان الأمر كذلك، غيّر المنفذ الرئيسي في docker-compose.yml (مثل 1026:1025) وحدّث MAIL_PORT في تطبيقاتك.
رفض الوصول من حاوية CI. حاويات Docker في GitHub Actions يمكنها الوصول إلى 127.0.0.1 للمشغّل، ولكن ليس إلى الخدمات الأخرى عبر localhost إذا لم تكن الشبكة مشتركة بشكل صحيح. استخدم شبكة host للمشغّل أو أشر إلى الخدمة باسمها (mailpit:1025) في ملف سير العمل.
الواجهة غير قابلة للوصول خلف الوكيل العكسي. يمكن أن تُقطع اتصالات WebSocket للواجهة الفورية بسبب مهلة Nginx قصيرة. تحقق من أن proxy_read_timeout مضبوط على 86400.
الأداء مع آلاف الرسائل. يحتفظ Mailpit بكل شيء في الذاكرة. إذا أنتج خط أنابيبك مئات الرسائل لكل تشغيل، اضبط MP_MAX_MESSAGES على قيمة معقولة (100-500).
Mailpit مقابل MailHog وMailtrap وInbucket وsmtp4dev
مرّر الجدول أفقيًا
| الأداة | الصيانة | RAM في الخمول | REST API | الاستمرارية | مصادقة SMTP |
|---|---|---|---|---|---|
| **Mailpit** | نشط (2024) | أقل من 50 ميغابايت | نعم (v1 + v2) | الذاكرة فقط | اختياري |
| MailHog | متوقف (2022) | ~30 ميغابايت | نعم (v1 فقط) | الذاكرة فقط | لا |
| Mailtrap (SaaS) | نشط | غير متاح (سحابة) | نعم | السحابة (30 يومًا) | نعم (سحابة) |
| Inbucket | نشط | ~20 ميغابايت | نعم | الذاكرة أو القرص | لا |
| smtp4dev | نشط | ~80 ميغابايت (.NET) | نعم | SQLite اختياري | لا |
حالات الاستخدام المتقدمة
الاعتراض متعدد المشاريع. يمكن لمثيل Mailpit واحد استقبال رسائل البريد الإلكتروني من مشاريع متعددة في وقت واحد. استخدم البحث في النص الكامل أو الفلترة حسب المستلم في الواجهة لعزل الرسائل من كل تطبيق.
Webhook إلى Slack أو n8n. المتغير MP_WEBHOOK_URL يطلق JSON POST عند كل استقبال. اربطه بسير عمل n8n لتوجيه رسائل الاختبار إلى قناة Slack للفريق.
التصدير وإعادة التشغيل. تكشف API الرسائل بتنسيق EML (GET /api/v1/message/<id>.eml). نزّل رسالة معترضة لإعادة تشغيلها في عميل بريد حقيقي أو للاحتفاظ بها كأداة اختبار.
Mailpit في مجموعة تطوير كاملة. أضف Mailpit كخدمة في docker-compose.yml الرئيسي لمشروعك. يتكامل بشكل طبيعي مع Laravel Sail وSymfony Docker وn8n ذاتي الاستضافة — أمر docker compose up واحد يشغّل بيئة التطوير بأكملها مع اعتراض SMTP.