> ## Content Index
> Fetch the complete content index at: https://arabroot.io/llms.txt
> Use this file to discover other available public pages before exploring further.

# تثبيت Postal لإرسال البريد التفاعلي من تطبيقاتك
- URL: https://arabroot.io/articles/تثبيت-postal-لارسال-البريد-التفاعلي/
- Published: 2026-10-05T01:30:00.000Z
- Updated: 2026-10-05T06:10:40.000Z
- Description: منصة إرسال مفتوحة المصدر على سيرفرك تشبه Amazon SES، ترسل منها تطبيقاتك رسائل التسجيل واستعادة كلمة المرور عبر SMTP أو HTTP API. يشرح هذا الدليل تثبيت Postal بالأداة الرسمية، وسجلات DNS التي يطلبها، وWebhooks والنسخ الاحتياطي والتحديث.
- Author: فريق عرب رووت
- Tags: الأدلة التقنية, البريد الإلكتروني, DevOps وCI/CD, الاستضافة الذاتية, Postal

في هذا الدليل سوف نثبت [Postal](https://postalserver.io/?ref=arabroot.io) على سيرفر مستقل، ونجعل تطبيقاتك ترسل منه رسائل التسجيل واستعادة كلمة المرور والفواتير عبر SMTP أو عبر HTTP API، ثم نتابع كل رسالة في سجل الرسائل Message Log ونستقبل نتيجتها في تطبيقك عبر Webhooks. أما ما هو البريد التفاعلي Transactional Email، ولماذا يجب أن يخرج من مسار مستقل عن بريد الموظفين والنشرات، وكيف تختار بين خدمة مدارة ومنصة تستضيفها بنفسك، فقد شرحناه في مقال [البريد التفاعلي Transactional Email](https://arabroot.io/articles/%D8%A7%D9%84%D8%A8%D8%B1%D9%8A%D8%AF-%D8%A7%D9%84%D8%AA%D9%81%D8%A7%D8%B9%D9%84%D9%8A-transactional-email/)، والصورة الكاملة لبريد المؤسسة في [دليل استضافة البريد الإلكتروني للمؤسسات](https://arabroot.io/articles/%D8%AF%D9%84%D9%8A%D9%84-%D8%A7%D8%B3%D8%AA%D8%B6%D8%A7%D9%81%D8%A9-%D8%A7%D9%84%D8%A8%D8%B1%D9%8A%D8%AF-%D8%A7%D9%84%D8%A5%D9%84%D9%83%D8%AA%D8%B1%D9%88%D9%86%D9%8A-%D9%84%D9%84%D9%85%D8%A4%D8%B3%D8%B3%D8%A7%D8%AA/)، وهنا نبدأ من قرار أنك تريد منصة الإرسال على سيرفرك.

في هذا المقال سوف نتناول:

- ما هو Postal وما الذي يقدمه، ومتى تختاره بدل Amazon SES، ولماذا لا يصلح خادماً لبريد الموظفين.
- المتطلبات والمنافذ Ports، وسجلات DNS الخاصة بالمنصة نفسها، ثم التثبيت بالأداة الرسمية `postal` مع MariaDB وCaddy.
- إنشاء المؤسسة Organization وخادم البريد Mail Server والنطاق Domain، والسجلات التي يطلبها Postal لكل نطاق ترسل منه.
- بيانات الدخول Credentials، والإرسال عبر SMTP على المنفذين 25 و587 مع TLS، والإرسال عبر HTTP API، مع مخرجات حقيقية.
- Webhooks لنتائج التسليم والارتدادات Bounces، والشهادة خلف Reverse Proxy، والأمان، والنسخ الاحتياطي Backup، والتحديث Upgrade، وأشهر المشكلات وحلولها.

## ما هو Postal وما الذي يقدمه؟

Postal منصة إرسال بريد Mail Delivery Platform مفتوحة المصدر تحت [ترخيص MIT](https://github.com/postalserver/postal/blob/main/MIT-LICENCE?ref=arabroot.io)، وفكرتها أن تقدم لك على سيرفرك ما تقدمه خدمات مثل Mailgun وAmazon SES: تطبيقك يسلم الرسالة إلى Postal بكلمة مرور خاصة به، وPostal يوقعها ويضعها في الطابور Queue ويسلمها إلى سيرفرات المستلمين، ويعيد المحاولة Retry إذا تأخر المستلم، ويسجل كل محاولة، ثم يخبر تطبيقك بالنتيجة. والإصدار الحالي هو [3.3.7](https://github.com/postalserver/postal/releases/tag/3.3.7?ref=arabroot.io) الصادر في يونيو 2026، ويعمل في ثلاث Containers من نفس ال Docker Image هي `web` للواجهة وAPI، و`smtp` لاستقبال الرسائل، و`worker` للتسليم والمهام الخلفية، ومعها قاعدة بيانات MariaDB، ولم يعد يحتاج منذ الإصدار 3 إلى RabbitMQ كما كانت الإصدارات القديمة.

والمفاهيم التي سوف تتعامل معها في الواجهة قليلة ومرتبة من الأعلى إلى الأسفل كما يلي:

- **المؤسسة Organization:** المستوى الأعلى في Postal، وتجعل فيه فريقاً أو عميلاً، ولكل مؤسسة مستخدموها ونطاقاتها.
- **خادم البريد Mail Server:** ليس سيرفراً حقيقياً، وإنما مساحة إرسال منطقية داخل المؤسسة، ولكل واحد منها قاعدة بيانات مستقلة للرسائل، وبيانات دخول ونطاقات وWebhooks خاصة به، لذلك فالأنسب أن تنشئ خادماً لكل تطبيق أو لكل بيئة، مثل خادم لتطبيق الإنتاج وآخر لبيئة الاختبار.
- **بيانات الدخول Credentials:** من ثلاثة أنواع: SMTP لكلمة مرور يستخدمها التطبيق في SMTP، وAPI لمفتاح يرسل في الترويسة `X-Server-API-Key`، وSMTP-IP للسماح بالإرسال من عنوان IP دون كلمة مرور.
- **المسارات Routes ونقاط التسليم Endpoints:** للبريد الوارد، فرسالة تصل إلى `support@example.com` مثلاً يحولها Postal إلى رابط HTTP في تطبيقك أو إلى سيرفر SMTP آخر أو إلى عنوان بريد.
- **Webhooks:** طلبات HTTP يرسلها Postal إلى تطبيقك عند كل حدث، مثل التسليم والتأخير والفشل والارتداد.
- **سجل الرسائل:** كل رسالة بترويساتها ومحتواها ومحاولات تسليمها، مع البحث والتصفية، وقائمة الحظر Suppression List للعناوين التي فشل التسليم إليها مرات متكررة.
- **مجموعات عناوين IP (IP Pools):** إذا كان لسيرفرك أكثر من عنوان IP، فتستطيع أن تخصص عنواناً لكل خادم بريد أو لكل نوع من الرسائل كما يشرح [التوثيق](https://docs.postalserver.io/features/ip-pools?ref=arabroot.io).

### Postal ليس خادماً لبريد الموظفين

لا يوجد في Postal صناديق بريد Mailboxes ولا IMAP ولا بريد عبر الويب Webmail، فلا يستطيع موظف أن يفتح Outlook ويقرأ بريده منه، والمشروع نفسه يقول في [صفحة الأسئلة الشائعة](https://docs.postalserver.io/welcome/faqs?ref=arabroot.io) إنه وكيل نقل بريد Mail Transport Agent وليس مدير قوائم بريدية. لذلك فإذا كنت تبحث عن بريد للموظفين فالخيارات الصحيحة هي mailcow أو Stalwart أو Postfix مع Dovecot كما في [دليل استضافة البريد الإلكتروني للمؤسسات](https://arabroot.io/articles/%D8%AF%D9%84%D9%8A%D9%84-%D8%A7%D8%B3%D8%AA%D8%B6%D8%A7%D9%81%D8%A9-%D8%A7%D9%84%D8%A8%D8%B1%D9%8A%D8%AF-%D8%A7%D9%84%D8%A5%D9%84%D9%83%D8%AA%D8%B1%D9%88%D9%86%D9%8A-%D9%84%D9%84%D9%85%D8%A4%D8%B3%D8%B3%D8%A7%D8%AA/)، وإذا كنت تبحث عن نشرات بريدية Newsletters بقوائم مشتركين وإلغاء اشتراك فهذا عمل [listmonk](https://arabroot.io/articles/%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-listmonk-%D9%84%D9%84%D9%86%D8%B4%D8%B1%D8%A7%D8%AA-%D8%A7%D9%84%D8%A8%D8%B1%D9%8A%D8%AF%D9%8A%D8%A9/)، وPostal يمكن أن يكون الجهة التي يرسل عبرها listmonk.

### متى تختار Postal بدل Amazon SES؟

وقد يتساءل البعض: لماذا أتعب نفسي بسيرفر إرسال بينما يرسل Amazon SES الرسالة بجزء صغير من السنت كما في [دليل الإرسال عبر Amazon SES](https://arabroot.io/articles/%D8%A7%D8%B1%D8%B3%D8%A7%D9%84-%D8%A8%D8%B1%D9%8A%D8%AF%D9%83-%D8%B9%D8%A8%D8%B1-amazon-ses/)؟ والإجابة أن الفرق ليس في السعر، وإنما في من يملك السمعة Reputation ومن يملك البيانات. ففي SES تخرج رسائلك من عناوين IP لها تاريخ طويل مع Gmail وOutlook، ولا تحتاج إلى المنفذ 25 ولا إلى سجل PTR، ولكن محتوى رسائلك وعناوين عملائك يمر عبر AWS، وحسابك معلق بنسب الارتداد والشكاوى التي تراقبها AWS. أما في Postal فالرسائل والسجلات على سيرفرك، ولا يوجد حد لعدد الرسائل غير قدرة السيرفر، ولكنك أنت المسؤول عن سمعة عنوان IP من أول رسالة، وعن قوائم الحظر Blocklists، وعن سجل PTR والمنفذ 25.

لذلك فالحكم العملي كما يلي: إذا كان مزودك يحجب المنفذ 25، أو كان حجم إرسالك صغيراً وتريد أن تصل الرسائل من اليوم الأول، فابدأ بـ Amazon SES. أما إذا كانت سياسة جهتك تمنع خروج بيانات العملاء إلى مزود خارجي، أو كنت ترسل بحجم كبير ومستقر يكفي لبناء سمعة عنوانك، أو تريد سجلاً كاملاً لكل رسالة تحت يدك، فـ Postal هو الأنسب، بشرط أن تخصص له سيرفراً بعنوان IP نظيف.

## ما تحتاجه قبل أن تبدأ Requirements

### السيرفر

- **سيرفر مخصص Dedicated لـ Postal وحده:** [صفحة المتطلبات](https://docs.postalserver.io/getting-started/prerequisites?ref=arabroot.io) توصي بشدة ألا يعمل على السيرفر أي برنامج آخر، والسبب أن Postal يعمل بشبكة السيرفر مباشرة Host Network ويحتاج إلى المنافذ 25 و80 و443، وأن عنوان IP هو سمعة الإرسال نفسها، فلا تخلطه بتطبيقات أخرى.
- **الذاكرة RAM والمعالج CPU والقرص Disk:** الحد الأدنى في التوثيق 4 GB من الذاكرة ونواتان و25 GB من القرص، وزد القرص بحسب حجم الرسائل ومدة الاحتفاظ بها كما سيأتي.
- **المنفذ 25 الصادر Outbound مفتوح، وسجل PTR:** كثير من المزودين يحجبون المنفذ 25 ولا يسمحون بتعديل PTR إلا بطلب، فتحقق من الأمرين قبل الشراء كما شرحنا في [دليل اختيار خادم VPS](https://arabroot.io/articles/%D9%83%D9%8A%D9%81-%D8%AA%D8%AE%D8%AA%D8%A7%D8%B1-%D8%AE%D8%A7%D8%AF%D9%85%D8%A7-%D8%A7%D9%81%D8%AA%D8%B1%D8%A7%D8%B6%D9%8A%D8%A7-vps/)، وتأكد أن عنوان IP ليس في قوائم الحظر، فالتوثيق نفسه ينبه إلى أن العنوان الذي يعطيك إياه المزود قد يكون محظوراً من مستخدم سابق.
- **النظام:** أي نظام يعمل عليه Docker، ونحن نفترض Ubuntu 24.04 مع Docker Engine وإضافة Docker Compose كما في [دليل تثبيت Docker على Ubuntu](https://arabroot.io/articles/%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-docker-%D8%B9%D9%84%D9%89-ubuntu/)، وإذا كان السيرفر جديداً فابدأ بـ [دليل تأمين خادم VPS من أول دخول](https://arabroot.io/articles/%D8%AA%D8%A3%D9%85%D9%8A%D9%86-%D8%AE%D8%A7%D8%AF%D9%85-vps-%D9%85%D9%86-%D8%A3%D9%88%D9%84-%D8%AF%D8%AE%D9%88%D9%84/).

وتأكد من المنفذ 25 الصادر قبل أي شيء آخر، فإذا انتهت المهلة Timeout دون اتصال فالمزود يحجبه، ولا فائدة من أي إعداد بعد ذلك:

```bash
nc -vz -w 5 gmail-smtp-in.l.google.com 25
```

### عنوان IP جديد يحتاج إلى تسخين Warm-up

السيرفرات الكبيرة مثل Gmail وOutlook تتعامل بحذر مع عنوان IP ليس له تاريخ إرسال، فإذا بدأ عنوان جديد يرسل آلاف الرسائل في يومه الأول فسوف تؤخرها أو تضعها في Spam، وهذا ما يذكره [التوثيق](https://docs.postalserver.io/welcome/faqs?ref=arabroot.io) صراحة بأن العناوين الجديدة التي ترسل بحجم كبير لن تصل رسائلها جيداً في البداية. لذلك ابدأ بالرسائل التي ينتظرها المستلم فعلاً، مثل رموز التحقق واستعادة كلمة المرور، فهي التي تفتح ويرد عليها، وزد الحجم تدريجياً على مدى أسابيع، واستخدم حد الإرسال Send Limit الذي يضبطه المدير لكل خادم بريد من **Settings › Advanced Settings** كما في [صفحة إعدادات الخادم](https://docs.postalserver.io/features/mail-server-settings?ref=arabroot.io)، فإذا تجاوز التطبيق العدد المسموح في الساعة يحجز Postal الرسائل الزائدة Held بدل أن يرسلها، ويرسل لك تنبيهاً.

### المنافذ: ما الذي يفتح للإنترنت؟

| المنفذ         | الخدمة                               | القرار                                                                                                   |
| -------------- | ------------------------------------ | -------------------------------------------------------------------------------------------------------- |
| 25/tcp         | SMTP في Postal                       | مفتوح، وبه يستقبل الارتدادات والبريد الوارد، ويقبل عليه أيضاً رسائل تطبيقاتك بعد المصادقة Authentication |
| 587/tcp        | SMTP إضافي للتطبيقات                 | اختياري، ولا يستمع عليه Postal افتراضياً، ونضيفه في قسم الإرسال عبر SMTP                                 |
| 80 و443/tcp    | Caddy                                | مفتوحان، للواجهة وAPI ولإصدار الشهادة                                                                    |
| 5000/tcp       | واجهة Postal دون تشفير               | على 127.0.0.1 فقط، ويصل إليها Caddy من داخل السيرفر                                                      |
| 3306/tcp       | MariaDB                              | على 127.0.0.1 فقط، ولا يفتح للإنترنت أبداً                                                               |
| 9090 و9091/tcp | فحص الصحة Health Check للعامل و SMTP | على 127.0.0.1 افتراضياً                                                                                  |

ولأن Containers الخاصة بـ Postal تعمل بشبكة السيرفر مباشرة، فالمنفذ الذي يستمع عليه البرنامج هو المنفذ المفتوح فعلاً على السيرفر دون أي ربط Publish من Docker، لذلك فقواعد جدار الحماية Firewall هنا تعمل كما تتوقع:

```bash
sudo ufw allow 25,587,80,443/tcp
```

### سجلات DNS الخاصة بالمنصة نفسها

هنا نوعان من السجلات يخلط بينهما كثيرون، فالأول سجلات المنصة نفسها، وتنشرها مرة واحدة قبل التثبيت لاسم السيرفر مثل `postal.example.com`، والثاني سجلات كل نطاق ترسل منه تطبيقاتك، وسوف يولدها Postal لك بعد التثبيت. ولن نشرح هنا معنى كل نوع من السجلات، فقد شرحنا ذلك في [شرح DNS وسجلاته للمبتدئين](https://arabroot.io/articles/%D8%B4%D8%B1%D8%AD-dns-%D9%88%D8%B3%D8%AC%D9%84%D8%A7%D8%AA%D9%87-%D9%84%D9%84%D9%85%D8%A8%D8%AA%D8%AF%D8%A6%D9%8A%D9%86/) و[شرح SPF وDKIM وDMARC للمبتدئين](https://arabroot.io/articles/%D8%B4%D8%B1%D8%AD-spf-%D9%88-dkim-%D9%88-dmarc-%D9%84%D9%84%D9%85%D8%A8%D8%AA%D8%AF%D8%A6%D9%8A%D9%86/)، وإنما نكتب ما يطلبه Postal بالضبط بحسب [صفحة إعداد DNS](https://docs.postalserver.io/getting-started/dns-configuration?ref=arabroot.io)، وضع عنوان سيرفرك مكان `203.0.113.10`:

```text
postal.example.com.                       A      203.0.113.10
mx.postal.example.com.                    A      203.0.113.10
spf.postal.example.com.                   TXT    "v=spf1 ip4:203.0.113.10 ~all"
rp.postal.example.com.                    A      203.0.113.10
rp.postal.example.com.                    MX     10 postal.example.com.
rp.postal.example.com.                    TXT    "v=spf1 a mx include:spf.postal.example.com ~all"
postal._domainkey.rp.postal.example.com.  TXT    (القيمة من الأمر postal default-dkim-record بعد التثبيت)
routes.postal.example.com.                MX     10 postal.example.com.
track.postal.example.com.                 A      203.0.113.10
```

في السجلات أعلاه لاحظ التالي:

- **spf.postal.example.com:** سجل SPF مركزي فيه عناوين المنصة، وكل نطاق ترسل منه يضيف `include:spf.postal.example.com` إلى سجله، فإذا غيرت عنوان IP يوماً ما عدلت هذا السجل وحده.
- **rp.postal.example.com:** نطاق مسار الرجوع Return Path الافتراضي، وهو العنوان الذي تعود إليه الارتدادات، ويوقع به Postal الرسائل بمفتاح المنصة إذا لم يكن مفتاح DKIM الخاص بنطاقك جاهزاً بعد، لذلك يحتاج إلى سجل DKIM خاص به سوف نولده بعد التثبيت.
- **routes وtrack:** الأول لاستقبال البريد الذي تحوله إلى المسارات، والثاني لتتبع الفتح والنقرات Open and Click Tracking، وإذا لم تكن تحتاجهما الآن فاتركهما.
- **PTR:** اضبطه لدى مزود السيرفر على `postal.example.com` تماماً، وهو نفس الاسم الذي يقدمه Postal في أمر EHLO، وإذا كنت تستخدم Cloudflare فاجعل هذه السجلات على وضع DNS only، لأن ال Proxy لا يمرر SMTP.

## التثبيت بالأداة الرسمية postal

طريقة التثبيت الرسمية ليست ملف Compose تكتبه بيدك، وإنما [مستودع مساعد التثبيت](https://github.com/postalserver/install?ref=arabroot.io) وفيه سكربت Bash باسم `postal` يولد ملف Compose من قالب Template لكل إصدار، ويغلف أوامر Docker Compose في أوامر قصيرة مثل `postal start` و`postal upgrade` كما في [صفحة الأمر postal](https://docs.postalserver.io/getting-started/postal-command?ref=arabroot.io)، وسوف نلتزم بها لأن التحديث لاحقاً يعتمد عليها.

### الأدوات ومستودع التثبيت

بعد تثبيت Docker ثبت الأدوات التي يحتاجها السكربت، ثم انسخ المستودع واجعل الأمر `postal` متاحاً في كل مكان:

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

### قاعدة البيانات MariaDB

يحتاج Postal إلى MariaDB بالإصدار 10.6 أو أحدث، ولا يدعم MySQL بدلاً منها، ويحتاج إلى صلاحية إنشاء قواعد البيانات، والسبب أنه ينشئ قاعدة مستقلة باسم `postal-server-N` لكل خادم بريد تنشئه في الواجهة. أنشئ كلمة مرور قوية واحفظها في مدير كلمات المرور Password Manager:

```bash
openssl rand -hex 24
```

ثم شغل MariaDB كما في التوثيق مع ثلاثة تعديلات سوف نشرحها، وضع كلمة المرور مكان `DB_PASSWORD`:

```bash
docker run -d \
  --name postal-mariadb \
  -p 127.0.0.1:3306:3306 \
  --restart always \
  -v postal-mariadb:/var/lib/mysql \
  -e MARIADB_DATABASE=postal \
  -e MARIADB_ROOT_PASSWORD=DB_PASSWORD \
  mariadb:11.8.9 \
  --innodb-log-file-size=256M
```

في الإعداد أعلاه لاحظ التالي:

- **الوسم Tag:** ثبتنا `mariadb:11.8.9` بدل `mariadb` دون وسم كما في التوثيق، والسبب أن الأمر دون وسم يسحب أحدث إصدار رئيسي في أي يوم تعيد فيه إنشاء ال Container، وقاعدة البيانات آخر ما تريد أن يتحدث دون قرار منك.
- **ال Volume باسم:** أمر التوثيق لا يحدد Volume، فتذهب البيانات إلى Volume مجهول الاسم Anonymous Volume يضيع أثره إذا حذفت ال Container وأنشأته من جديد، أما `postal-mariadb` فتعرفه وتنسخه وتنقله.
- **حجم سجل InnoDB:** تنبه [صفحة المتطلبات](https://docs.postalserver.io/getting-started/prerequisites?ref=arabroot.io) إلى أن `innodb_log_file_size` يجب أن يكون عشرة أضعاف أكبر رسالة ترسلها على الأقل، وأكبر رسالة يقبلها Postal افتراضياً 14 MB، لذلك رفعناه إلى 256M.
- **المنفذ 3306:** مربوط بالعنوان `127.0.0.1` فقط، لأن Postal يعمل بشبكة السيرفر ويصل إليه من هناك، ولا يوجد سبب ليراه أحد من الخارج.

### توليد الإعداد بالأمر postal bootstrap

الآن نولد ملفات الإعداد لاسم السيرفر، ونمرر رقم الإصدار صراحة حتى نعرف ما الذي نثبته بدل أن يسأل السكربت GitHub عن أحدث إصدار:

```bash
sudo postal bootstrap postal.example.com --version 3.3.7
```

والمخرج سوف يكون كما يلي:

```text
Using version: 3.3.7
=> Creating /opt/postal/config/postal.yml
=> Creating /opt/postal/config/Caddyfile
=> Creating signing private key
```

ثلاثة ملفات في `/opt/postal/config`: ملف الإعداد `postal.yml`، وملف `Caddyfile` للواجهة، ومفتاح التوقيع `signing.key`، وهو مفتاح RSA يوقع به Postal رسائل نطاق مسار الرجوع وطلبات Webhooks، فاعتبره من أهم ما على السيرفر. وولد السكربت أيضاً `/opt/postal/install/docker-compose.yml` من القالب، وفيه ال Image `ghcr.io/postalserver/postal:3.3.7` للخدمات الثلاث.

افتح الآن `/opt/postal/config/postal.yml`، وسوف تجد أنه يحتاج إلى ثلاثة تعديلات، والملف بعد التعديل سوف يكون كما يلي:

```yaml
version: 2

postal:
  web_hostname: postal.example.com
  web_protocol: https
  smtp_hostname: postal.example.com

main_db:
  host: 127.0.0.1
  username: root
  password: DB_PASSWORD
  database: postal

message_db:
  host: 127.0.0.1
  username: root
  password: DB_PASSWORD
  prefix: postal

smtp_server:
  default_bind_address: "::"

dns:
  mx_records:
    - mx.postal.example.com
  spf_include: spf.postal.example.com
  return_path_domain: rp.postal.example.com
  route_domain: routes.postal.example.com
  track_domain: track.postal.example.com

smtp:
  host: 127.0.0.1
  port: 25
  username:
  password:
  from_name: Postal
  from_address: postal@example.com

rails:
  secret_key: القيمة-التي-ولدها-السكربت
```

في الإعداد أعلاه لاحظ التالي:

- **كلمة مرور قاعدة البيانات:** القالب يأتي بكلمة المرور `postal` في القسمين `main_db` و`message_db`، فضع مكانها كلمة المرور التي ولدتها.
- **قسم `smtp`:** هذا ليس إعداد الإرسال لتطبيقاتك، وإنما السيرفر الذي يرسل عبره Postal رسائله الخاصة، مثل استعادة كلمة مرور الواجهة وتنبيهات حد الإرسال. والقالب يضع المنفذ `2525` بينما يستمع Postal على 25، لذلك غيرناه، وسوف نملأ اسم المستخدم وكلمة المرور بعد أن ننشئ بيانات دخول في الواجهة.
- **العنوان `from_address`:** بعد الأمر `bootstrap` ستجد القيمة `postal.example.com` دون علامة @، والسبب أن السكربت يستبدل النص `postal.yourdomain.com` بتعبير `sed` تطابق فيه النقطة أي حرف، فتطابق أيضاً `postal@yourdomain.com` وتحولها إلى اسم السيرفر، فصححها بيدك إلى عنوان كامل.
- **قسم `dns`:** نفس الأسماء التي نشرتها في DNS، فإذا اخترت أسماء أخرى فاكتبها هنا قبل الخطوة التالية، والقائمة الكاملة للخيارات في [ملف الإعداد المرجعي](https://github.com/postalserver/postal/blob/main/doc/config/yaml.yml?ref=arabroot.io).

### تهيئة قاعدة البيانات والمستخدم الأول

الأمر التالي يسحب ال Image وينشئ الجداول في قاعدة `postal`:

```bash
sudo postal initialize
```

والمخرج سوف ينتهي بما يلي:

```text
Initializing database
Loading config from /config/postal.yml
Database 'postal' already exists
No schema migrations exist. Loading schema with db:schema:load
```

ثم أنشئ المدير الأول Global Administrator، والأمر يسألك عن البريد والاسم وكلمة المرور:

```bash
sudo postal make-user
```

والمخرج سوف يكون كما يلي:

```text
Postal User Creator
Enter the information required to create a new Postal user.
This tool is usually only used to create your initial admin user.

E-Mail Address      : admin@example.com
First Name          : Admin
Last Name           : User
Initial Password    : ****************

User has been created with e-mail address admin@example.com
```

وهذا الأمر ينشئ مديراً في كل مرة، فإذا أغلقت على نفسك الدخول يوماً ما فهو طريقك للعودة. والآن اطبع سجل DKIM الخاص بنطاق مسار الرجوع، وانشره باسم `postal._domainkey.rp.postal.example.com` كما في جدول السجلات أعلاه:

```bash
sudo postal default-dkim-record
```

والمخرج سوف يكون سطراً واحداً بهذا الشكل، والمفتاح عندك مختلف:

```text
v=DKIM1; t=s; h=sha256; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCnGFfFLoVr69y7u4F9wX1C2CE1EZEf3weso0pwMbZErJiiiv1roifep6ugxQ7qYUBlJ+RPtjcERbCyWx+1ncViUuo6K8WPihYbMp+hxd2e8jhmkwQ/gwGAVswhx4CGKQV71KJgvBP1vPTwxRKPDXGAOc8HntW0mzo5uW4hbIEqQIDAQAB;
```

### تشغيل Postal وCaddy

الآن سوف نقوم بالتشغيل:

```bash
sudo postal start
sudo postal status
```

ستجد ثلاث Containers باسم المشروع `postal` هي `postal-web-1` و`postal-smtp-1` و`postal-worker-1`، وإذا ظهر تحذير أن الحقل `version` في ملف Compose قديم Obsolete فهو تحذير من Docker Compose عن سطر في القالب، ولا يؤثر على التشغيل. وتحقق من السجل أن SMTP يستمع على المنفذ 25:

```bash
sudo postal logs smtp | grep Listening
```

والمخرج سوف يكون مشابهاً لما يلي:

```text
smtp-1  | 2026-10-05 05:24:22 +0000 INFO   Listening on :::25 component=smtp-server
```

بقيت الواجهة، فهي تستمع على `127.0.0.1:5000` دون تشفير، ويقدمها للإنترنت [Caddy](https://caddyserver.com/?ref=arabroot.io) الذي يصدر شهادة Let's Encrypt ويجددها بنفسه، والملف `Caddyfile` الذي ولده `bootstrap` يوجه `postal.example.com` إلى `127.0.0.1:5000`، فشغله كما في [صفحة التثبيت](https://docs.postalserver.io/getting-started/installation?ref=arabroot.io) مع تثبيت الوسم:

```bash
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:2.11.6
```

بعد دقيقة افتح `https://postal.example.com` وادخل بحساب المدير، وإذا كان لديك Reverse Proxy على السيرفر يملك المنفذين 80 و443 فلا تشغل Caddy، وانتقل إلى قسم الشهادة خلف Reverse Proxy.

## المؤسسة الأولى وخادم البريد

بعد الدخول تعرض الصفحة الرئيسية الزر **Create the first organization**، فاكتب اسم المؤسسة مثل `Example Inc` ومعرفها المختصر Permalink مثل `example`، ثم من صفحة المؤسسة اضغط **Build your first mail server**، واكتب الاسم `App Notifications` والمعرف `app`، واختر الوضع Mode:

- **Live:** ترسل الرسائل إلى المستلمين فعلاً.
- **Development:** تحجز كل رسالة Held ولا تخرج، ولكنها تظهر في السجل بمحتواها، وهذا مفيد جداً لخادم بريد مخصص لبيئة الاختبار، فلا يصل بريد تجريبي إلى عميل حقيقي بالخطأ.

ولاحظ أن إنشاء خادم البريد قد يستغرق دقيقة، لأن Postal ينشئ له قاعدة بيانات كاملة في MariaDB. والصورة التالية تبين صفحة الخادم بعد إرسال الرسائل التجريبية التي سوف نرسلها في الأقسام التالية:

![صفحة خادم البريد App Notifications في Postal مع عدد الرسائل الصادرة والرسم البياني وآخر الرسائل المرسلة](https://arabroot.io/content/images/2026/10/postal-01-server-overview.webp)

صفحة خادم البريد: الرسائل المحجوزة والطابور ونسبة الارتداد في الأعلى، ثم الرسم البياني للرسائل، ثم آخر الرسائل وحالة كل منها

والقائمة في الأعلى هي كل ما يخص هذا الخادم: **Messages** للسجل، و**Domains** للنطاقات، و**Routing** للبريد الوارد، و**Credentials** لبيانات الدخول، و**Webhooks**، و**Settings**. والتحذير الأحمر **1 domain has misconfigured DNS records** سببه أن سجلات النطاق الذي أضفناه لم تنشر بعد، وهو ما نعالجه في القسم التالي.

## إضافة النطاق والسجلات التي يطلبها Postal

لا يرسل Postal من أي عنوان إلا إذا كان نطاقه مضافاً إلى خادم البريد أو إلى المؤسسة ومتحققاً منه. افتح **Domains** ثم **Add new domain** واكتب `example.com`، وإذا كنت المدير فالنطاق يعتبر متحققاً منه مباشرة، أما المستخدم العادي فيثبت ملكيته بسجل TXT قيمته `postal-verification` ثم رمز عشوائي، أو برمز يصل إلى عنوان مثل `postmaster@` كما في [صفحة نطاقات الإرسال](https://docs.postalserver.io/features/sending-domains?ref=arabroot.io). وبعد الإضافة تفتح صفحة **DNS Setup** مباشرة:

![صفحة DNS Setup في Postal للنطاق example.com مع سجل SPF وسجل DKIM وسجل Return Path](https://arabroot.io/content/images/2026/10/postal-02-domain-dns-setup.webp)

صفحة **DNS Setup** للنطاق `example.com`: سجل SPF، ثم سجل DKIM باسم المحدد الذي ولده Postal، ثم CNAME لمسار الرجوع، وفي الأسفل MX للبريد الوارد

والسجلات التي تعرضها الصفحة بصيغة نصية كما يلي، مع اختصار المفتاح:

```text
example.com.                           TXT    "v=spf1 a mx include:spf.postal.example.com ~all"
postal-OA6ryL._domainkey.example.com.  TXT    "v=DKIM1; t=s; h=sha256; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD6ElQQ…IDAQAB;"
psrp.example.com.                      CNAME  rp.postal.example.com.
example.com.                           MX     10 mx.postal.example.com.
```

في السجلات أعلاه لاحظ التالي:

- **SPF:** إذا كان لنطاقك سجل SPF لبريد الموظفين فلا تنشئ سجلاً ثانياً، وإنما أضف `include:spf.postal.example.com` إلى السجل الموجود، والواجهة نفسها تقول ذلك، وإذا لم يجد Postal هذا الجزء يعرض الحالة `Invalid`.
- **DKIM:** يولد Postal لكل نطاق مفتاحاً خاصاً به، واسم المحدد Selector يبدأ بـ `postal-` ثم ستة حروف عشوائية، فانسخ الاسم والقيمة من صفحتك وليس من هنا.
- **مسار الرجوع psrp:** اختياري، ولكنه يجعل عنوان المغلف Envelope Sender على نطاقك بدل `rp.postal.example.com`، وبدونه لا يتطابق SPF مع نطاق المرسل عند فحص DMARC. وPostal لا يولد سجل DMARC، فسياسة DMARC لنطاقك تكتبها أنت كما شرحنا في [مقال SPF وDKIM وDMARC](https://arabroot.io/articles/%D8%B4%D8%B1%D8%AD-spf-%D9%88-dkim-%D9%88-dmarc-%D9%84%D9%84%D9%85%D8%A8%D8%AA%D8%AF%D8%A6%D9%8A%D9%86/).
- **MX:** فقط إذا أردت أن يستقبل Postal بريد هذا النطاق، ولا تضفه أبداً إلى نطاق عليه صناديق بريد الموظفين، لأن البريد الوارد سوف يذهب إلى Postal بدل صناديقهم. وهذا سبب إضافي لما أوصينا به في [مقال البريد التفاعلي](https://arabroot.io/articles/%D8%A7%D9%84%D8%A8%D8%B1%D9%8A%D8%AF-%D8%A7%D9%84%D8%AA%D9%81%D8%A7%D8%B9%D9%84%D9%8A-transactional-email/) من أن ترسل من نطاق فرعي Subdomain مثل `notify.example.com`، فإذا فعلت ذلك فأضفه هو في Postal بدل `example.com`، ولاحظ أن Postal يطابق النطاق حرفياً، فالإرسال من `notify.example.com` يحتاج إلى إضافته هو تحديداً.

بعد النشر اضغط **Check my records are correct**، ويعيد Postal الفحص تلقائياً كل ساعة، ويستعلم من سيرفرات الأسماء الرسمية Authoritative Nameservers للنطاق مباشرة، فلا تنتظر انتهاء التخزين المؤقت Cache. والنطاق يعتبر جاهزاً عندما يكون SPF وDKIM بالحالة `OK`.

وماذا يحدث إذا أرسلت قبل أن يصبح DKIM جاهزاً؟ لا يرفض Postal الرسالة، وإنما يوقعها بمفتاح المنصة على نطاق مسار الرجوع، وهذه ترويسات رسالة خرجت قبل نشر سجلات `example.com`، مع حذف قيم التوقيع وبعض الأسطر:

```text
Return-Path: <yr9s6z@rp.postal.example.com>
Resent-Sender: yr9s6z@rp.postal.example.com
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
	d=rp.postal.example.com;
	s=postal; t=1791178923;
	h=date:to:from:subject:message-id;
X-Postal-MsgID: ZLheqYCxZXBrOUr3
From: noreply@example.com
```

لاحظ أن التوقيع بالنطاق `d=rp.postal.example.com` والمحدد `s=postal`، أي بالسجل الذي نشرته من `postal default-dkim-record`، بينما المرسل في `From` هو `example.com`، وبالتالي فالتوقيع صحيح ولكنه لا يتطابق مع نطاق المرسل، وسوف تفشل الرسالة في DMARC لدى من يطبقه. لذلك لا ترسل بريداً حقيقياً من نطاق قبل أن يصبح DKIM الخاص به `OK`، وعندها يصبح التوقيع `d=example.com`.

## بيانات الدخول لكل تطبيق Credentials

افتح **Credentials** ثم **Add another credential**، واختر النوع واكتب اسماً يدل على التطبيق، واترك الحقل **Key** فارغاً ليولده Postal، وفي الحقل **Hold** تستطيع أن تجعل كل رسائل هذا المفتاح تحجز دون إرسال، وهذا مفيد لبيئة اختبار تشارك نفس الخادم. أنشأنا مفتاحين، الأول `web-app` من نوع SMTP للتطبيق الذي يرسل عبر SMTP، والثاني `backend` من نوع API:

![قائمة بيانات الدخول في Postal وفيها مفتاح API باسم backend ومفتاح SMTP باسم web-app](https://arabroot.io/content/images/2026/10/postal-03-credentials.webp)

بيانات الدخول لخادم البريد: نوع كل مفتاح واسمه وقيمته وآخر استخدام له

والقاعدة هنا مفتاح لكل تطبيق، والسبب أنك إذا اشتبهت في تسريب مفتاح فتحذفه وحده دون أن يتوقف بقية التطبيقات، وفي صفحة كل رسالة يظهر اسم المفتاح الذي أرسلها، فتعرف مباشرة أي تطبيق أرسل رسالة غريبة. ولاحظ أن المفتاح يعمل على خادم البريد كله، أي على كل نطاقاته، ولا يوجد في Postal مفتاح مقيد بنطاق واحد، فإذا أردت فصلاً أشد بين تطبيقين فاجعل لكل واحد منهما خادم بريد مستقلاً. أما النوع SMTP-IP فيسمح بالإرسال من عنوان أو شبكة دون كلمة مرور، و[التوثيق](https://docs.postalserver.io/features/smtp-authentication?ref=arabroot.io) يحذر من أنه قد يجعل سيرفرك مفتوحاً للترحيل Open Relay إذا وضعت شبكة أوسع من اللازم، فلا تستخدمه إلا لعنوان سيرفر تعرفه.

والآن عد إلى قسم `smtp` في `postal.yml` وضع في `password` مفتاح SMTP، وفي `username` أي قيمة مثل `example/app`، ثم أعد التشغيل واختبر رسائل المنصة نفسها:

```bash
sudo postal restart
sudo postal test-app-smtp admin@example.com
```

## الإرسال عبر SMTP

أغلب التطبيقات تعرف SMTP، ويكفيها أربعة إعدادات: السيرفر `postal.example.com`، والمنفذ، واسم المستخدم، وكلمة المرور. ويقبل Postal في [المصادقة](https://docs.postalserver.io/features/smtp-authentication?ref=arabroot.io) الطرق PLAIN وLOGIN وCRAM-MD5، ومع PLAIN وLOGIN يمكن أن يكون اسم المستخدم أي نص، وكلمة المرور هي قيمة المفتاح، أما مع CRAM-MD5 فاسم المستخدم هو معرف المؤسسة ومعرف الخادم بالصيغة `example/app`. ولكن قبل أن تعطي التطبيق هذه البيانات هناك أمران يجب أن تصلحهما.

### تفعيل TLS على SMTP

يعمل SMTP في Postal افتراضياً دون TLS كما تنص [صفحة SMTP TLS](https://docs.postalserver.io/features/smtp-tls?ref=arabroot.io)، وهذا يعني أن مفتاح التطبيق ومحتوى الرسائل يمران دون تشفير إذا كان التطبيق على سيرفر آخر، وأن السيرفرات الأخرى لا تستطيع تسليمك الارتدادات بتشفير. والحل أن تضع شهادة لاسم السيرفر في الملفين `/opt/postal/config/smtp.cert` و`/opt/postal/config/smtp.key` بصيغة PEM، ثم تفعل TLS في `postal.yml`:

```yaml
smtp_server:
  default_bind_address: "::"
  tls_enabled: true
```

وبما أن Caddy يصدر شهادة Let's Encrypt لنفس الاسم `postal.example.com`، فأسهل مصدر للشهادة هو مجلد بيانات Caddy، والسكربت التالي ينسخها إلى مجلد الإعداد إذا تغيرت ويعيد تشغيل خدمات SMTP فقط، فاحفظه في `/usr/local/bin/postal-smtp-cert` وأضفه إلى `crontab` الخاص بالمستخدم root ليعمل يومياً:

```bash
#!/bin/bash
set -e
SRC=/opt/postal/caddy-data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/postal.example.com
if ! cmp -s "$SRC/postal.example.com.crt" /opt/postal/config/smtp.cert; then
  install -o 999 -g 999 -m 644 "$SRC/postal.example.com.crt" /opt/postal/config/smtp.cert
  install -o 999 -g 999 -m 600 "$SRC/postal.example.com.key" /opt/postal/config/smtp.key
  postal dc restart smtp
fi
```

في السكربت أعلاه لاحظ التالي:

- البرنامج داخل ال Container يعمل بالمستخدم `postal` ورقمه UID 999 كما في [ملف Dockerfile](https://github.com/postalserver/postal/blob/main/Dockerfile?ref=arabroot.io)، بينما ملف المفتاح الذي يكتبه Caddy لا يقرؤه إلا root، لذلك ننسخه بالأمر `install` بملكية 999 حتى يستطيع Postal قراءته دون أن نفتحه لبقية المستخدمين.
- يقرأ Postal الشهادة عند التشغيل فقط، وبدون إعادة التشغيل يستمر بالشهادة القديمة حتى تنتهي صلاحيتها، ولاحظ أن `postal dc` يمرر أي أمر إلى Docker Compose، فنعيد تشغيل SMTP وحده دون الواجهة.
- إذا أضفت خدمة المنفذ 587 في الخطوة التالية فأضف اسمها `smtp-submission` بعد `smtp` في سطر إعادة التشغيل.

### المنفذ 587 للتطبيقات

يستمع Postal على المنفذ 25 فقط، وتستطيع تطبيقاتك أن ترسل عليه بعد المصادقة، ولكن كثيراً من مزودي السحابة يحجبون المنفذ 25 الصادر من سيرفرات التطبيقات نفسها، وبعض المكتبات تفترض 587 للإرسال، لذلك نضيف عملية SMTP ثانية على 587\. ويسمح Postal بذلك عبر متغير البيئة `PORT` كما في [صفحة الإعداد](https://docs.postalserver.io/getting-started/configuration?ref=arabroot.io)، ولكن ملف `docker-compose.yml` يولد من جديد مع كل تحديث، لذلك نضع الخدمة في ملف `/opt/postal/install/docker-compose.override.yml` الذي يدمجه Docker Compose تلقائياً ولا يلمسه التحديث:

```yaml
services:
  smtp-submission:
    extends:
      file: docker-compose.yml
      service: smtp
    environment:
      PORT: "587"
      SMTP_SERVER_DEFAULT_HEALTH_SERVER_PORT: "9092"
```

في الإعداد أعلاه لاحظ التالي:

- `extends` يأخذ تعريف الخدمة `smtp` كما هو من الملف المولد، بما في ذلك ال Image ورقم إصداره، وبالتالي فعندما يغير `postal upgrade` الإصدار في `docker-compose.yml` تتبعه هذه الخدمة دون أن تعدل شيئاً.
- غيرنا منفذ فحص الصحة إلى 9092، والسبب أن الخدمتين تعملان بشبكة السيرفر نفسها، وكلاهما يحاول افتراضياً أن يستمع على 9091، فتفشل الثانية.

ثم شغل الخدمة الجديدة، وتحقق من السجل:

```bash
sudo postal start
sudo postal logs smtp-submission | grep Listening
```

والمخرج سوف يكون مشابهاً لما يلي:

```text
smtp-submission-1  | 2026-10-05 05:40:07 +0000 INFO   Listening on :::587 component=smtp-server
```

### إرسال أول رسالة عبر SMTP

الآن نرسل من سيرفر التطبيق رسالة استعادة كلمة مرور بأداة [swaks](https://github.com/jetmore/swaks?ref=arabroot.io) (تثبتها بالأمر `sudo apt install swaks`) على المنفذ 587 مع STARTTLS، وضع مفتاح SMTP مكان كلمة المرور، و`user@example.net` عنوان مستلم تملكه:

```bash
swaks --server postal.example.com --port 587 --ehlo app.example.com --tls \
  --auth PLAIN --auth-user web-app --auth-password 'CvGcSGVHYdceAefrukViRRJz' \
  --from noreply@example.com --to user@example.net \
  --header 'Subject: Verify your email address' \
  --body 'Your verification code is 482913.'
```

والمخرج سوف يكون كما يلي، وهنا الأسطر المهمة فقط:

```text
<-  220 postal.example.com ESMTP Postal/723HDHIY
<-  250-My capabilities are
<-  250-STARTTLS
<-  250 AUTH CRAM-MD5 PLAIN LOGIN
<-  220 Ready to start TLS
=== TLS started with cipher TLSv1.3:TLS_AES_256_GCM_SHA384:256
<~  250-My capabilities are
<~  250 AUTH CRAM-MD5 PLAIN LOGIN
<~  235 Granted for example/app
<~  250 OK
<~  250 OK
<~  354 Go ahead
<~  250 OK
<~  221 Closing Connection
```

في المخرج أعلاه لاحظ التالي:

- السطر `250-STARTTLS` لا يظهر إلا بعد تفعيل TLS، فإذا لم تجده فالسيرفر يقبل كلمة المرور دون تشفير، والأسطر التي تبدأ بـ `<~` هي ما بعد بدء التشفير.
- الرد `235 Granted for example/app` يخبرك أي مؤسسة وأي خادم بريد يملك المفتاح، وهذا مفيد عندما يكون لديك عدة خوادم وتريد أن تتأكد أن التطبيق يستخدم المفتاح الصحيح.
- الرد `250 OK` بعد البيانات يعني أن Postal قبل الرسالة ووضعها في الطابور، وليس أنها وصلت، فالتسليم يقوم به ال Worker بعد ذلك، ونتيجته في السجل وفي Webhooks.

والآن لنكسر الأمر لنفهمه، فنغير ثلاثة أشياء في نفس الأمر واحداً واحداً، وهذه ردود Postal:

```text
# --from noreply@example.org (نطاق غير مضاف إلى الخادم)
<** 530 From/Sender name is not valid

# --auth-password بمفتاح خاطئ
<** 535 Invalid credential

# دون --auth إلى عنوان خارجي
<** 530 Authentication required
```

الأول هو أشهر خطأ عند ربط تطبيق جديد، والسبب أن التطبيق يرسل باسم عنوان على نطاق لم تضفه إلى هذا الخادم، أو على نطاق فرعي لم تضفه بعينه. والثالث هو ما تريد أن تراه، أي أن سيرفرك لا يرحل بريداً لأحد دون مصادقة.

## الإرسال عبر HTTP API

إذا كان تطبيقك يستطيع أن يرسل طلب HTTP فال API أبسط من SMTP في أمور كثيرة: يعود لك مباشرة رقم الرسالة الذي تخزنه مع الطلب في قاعدة بياناتك، وتضيف وسماً Tag يصنف الرسالة في السجل. ويرسل الطلب بصيغة JSON مع المفتاح في الترويسة `X-Server-API-Key` كما في [توثيق ال API](https://docs.postalserver.io/developer/api?ref=arabroot.io)، والحقول كلها في [مرجع الإرسال](https://postalserver.github.io/postal-api/controllers/send/message?ref=arabroot.io):

```bash
curl -s -X POST https://postal.example.com/api/v1/send/message \
  -H 'X-Server-API-Key: HiyP7aQQjhacodqgHsxbgXGl' \
  -H 'Content-Type: application/json' \
  -d '{"to":["user@example.net"],"from":"noreply@example.com","subject":"Your order has shipped","plain_body":"Order 1042 is on its way.","tag":"shipping"}'
```

والمخرج سوف يكون كما يلي:

```json
{"status":"success","time":0.99,"flags":{},"data":{"message_id":"41816855-8ae8-4a3c-95ec-f781f66ef9c3@rp.postal.example.com","messages":{"user@example.net":{"id":2,"token":"dl5RdM1uAMzlrgor"}}}}
```

لاحظ أن الرد يعطيك رقماً لكل مستلم في `messages`، فإذا أرسلت إلى ثلاثة مستلمين فهي ثلاث رسائل منفصلة في Postal لكل واحدة نتيجتها، وهذا الرقم `id` هو ما يصلك لاحقاً في Webhooks، فخزنه. ولاحظ أيضاً أن ال API يعيد الحالة HTTP 200 حتى عند الخطأ، والخطأ في الحقل `status`، فلا يكفي في الكود أن تفحص رمز HTTP:

```json
{"status":"error","time":0.002,"flags":{},"data":{"message":"The API token provided in X-Server-API-Key was not valid.","token":"wrongkey","code":"InvalidServerAPIKey"}}
{"status":"error","time":0.053,"flags":{},"data":{"message":"The From address is not authorised to send mail from this server","code":"UnauthenticatedFromAddress"}}
```

### سجل الرسائل: ما الذي حدث لكل رسالة؟

كل رسالة تقبلها المنصة تظهر في **Messages › Outgoing Messages** بحالتها، وتبحث فيها بالمستلم أو الوسم أو الحالة:

![سجل الرسائل الصادرة في Postal وفيه خمس رسائل بالحالة SENT](https://arabroot.io/content/images/2026/10/postal-04-message-log.webp)

سجل الرسائل الصادرة: الرسائل الخمس التي أرسلناها عبر SMTP وال API، وكلها بالحالة `SENT`

وفي صفحة كل رسالة تبويب **Activity** بمحاولات التسليم، وفيه رد سيرفر المستلم كما هو، وهذه أسطر ال Worker لنفس الرسالة من الأمر `postal logs worker`:

```text
INFO   Sending message 1::2 to user@example.net log_id=ITQYXPYO component=worker
INFO   Accepted by 192.168.80.2:1025 (mailpit) for user@example.net log_id=ITQYXPYO component=worker
INFO   message processing complete component=worker
```

ولاحظ أن هذه الأسطر من سيرفر يوجه كل البريد الصادر إلى سيرفر SMTP وسيط عبر الخيار `postal.smtp_relays`، وهو هنا Mailpit المحلي، لذلك ترى `mailpit` مكان سيرفر المستلم. وعلى سيرفرك سوف ترى اسم سيرفر MX الخاص بالمستلم ورده مثل `250 2.0.0 OK`. وإذا كانت الحالة `SoftFail` فـ Postal يعيد المحاولة بفواصل تزيد تدريجياً حتى 18 محاولة، وإذا كانت `HardFail` فالمستلم رفض الرسالة نهائياً، وبعد فشلين نهائيين للعنوان نفسه خلال 24 ساعة يضعه Postal في قائمة الحظر **Suppressions** ويحجز ما يرسل إليه بعد ذلك 30 يوماً، وهذا يحمي سمعة عنوانك من تكرار الإرسال إلى عناوين غير موجودة.

⚠️

يحفظ Postal المحتوى الكامل لكل رسالة 30 يوماً افتراضياً، وبيانات الرسالة 60 يوماً كما في [إعدادات الاحتفاظ Retention](https://docs.postalserver.io/features/mail-server-settings?ref=arabroot.io)، وهذا يعني أن روابط استعادة كلمة المرور ورموز التحقق التي يرسلها تطبيقك موجودة في قاعدة البيانات وفي كل نسخة احتياطية منها، ويقرؤها كل مستخدم في المؤسسة من الواجهة. لذلك اجعل صلاحية الروابط في تطبيقك قصيرة، وقلل مدة الاحتفاظ بالمحتوى من **Settings › Advanced Settings** إلى ما تحتاجه فعلاً للتحقيق في المشكلات.

## نتائج التسليم والارتدادات عبر Webhooks

الرد `250 OK` من Postal لا يخبر تطبيقك هل وصلت الرسالة، والطريقة الصحيحة لمعرفة ذلك أن يرسل Postal إلى تطبيقك طلب HTTP عند كل حدث. افتح **Webhooks** ثم أضف رابطاً في تطبيقك مثل `https://app.example.com/postal/events`، واختر كل الأحداث أو بعضها، وأهمها كما في [صفحة Webhooks](https://docs.postalserver.io/developer/webhooks?ref=arabroot.io):

- `MessageSent` عند التسليم، و`MessageDelayed` عند كل تأخير، و`MessageDeliveryFailed` عند الفشل النهائي، و`MessageHeld` عند الحجز.
- `MessageBounced` عندما يصل ارتداد لرسالة قبلها سيرفر المستلم ثم أعادها، وفيه الرسالة الأصلية والارتداد معاً.
- `DomainDNSError` عندما يكتشف الفحص الدوري أن سجلات أحد النطاقات تعطلت، وهذا تنبيه مفيد جداً إذا عدل أحد سجلات DNS دون أن يخبرك.
- `MessageLinkClicked` و`MessageLoaded` إذا فعلت تتبع النقرات والفتح.

والطلب الذي يصل إلى تطبيقك بعد تسليم رسالة أرسلت عبر ال API سوف يكون كما يلي:

```json
{"event":"MessageSent","timestamp":1791179215.160438,"payload":{"message":{"id":4,"token":"Hx1U6NMXAZHBwkPZ","direction":"outgoing","message_id":"be51dded-f9c3-4cde-b6b0-32728878b08a@rp.postal.example.com","to":"user@example.net","from":"noreply@example.com","subject":"Your invoice is ready","timestamp":1791179202.885616,"spam_status":"NotChecked","tag":"invoice"},"status":"Sent","details":"Message for user@example.net accepted by 192.168.80.2:1025 (mailpit)","output":"250 2.0.0 Ok: queued as 60fYlvoUrilHmnDA4N1mPI","sent_with_ssl":false,"timestamp":1791179214.844055,"time":0.08},"uuid":"d3a987cf-b6fe-4dab-8b33-3179e3cf26a7"}
```

في الطلب أعلاه لاحظ التالي:

- `payload.message.id` هو نفس الرقم الذي أعاده ال API عند الإرسال، فتربط به الحدث بالطلب في قاعدة بياناتك، وتعرف مثلاً أن رسالة التفعيل لمستخدم معين فشلت فتعرض له خيار تغيير البريد.
- يحمل الطلب الترويسة `X-Postal-Signature-256`، وهي توقيع RSA-SHA256 لمحتوى الطلب بمفتاح `signing.key`، والمفتاح العام منشور على `https://postal.example.com/.well-known/jwks.json`، فتحقق من التوقيع في تطبيقك قبل أن تثق بالطلب، والسبب أن رابط Webhook معروف لكل من يرى إعدادك، وأي شخص يستطيع أن يرسل إليه طلباً مزيفاً.
- يجب أن يرد تطبيقك بسرعة برمز 2xx، وإذا فشل الطلب يعيد Postal المحاولة لاحقاً، فاجعل معالجة الحدث تتحمل وصوله مرتين.

والآن لنكسر الأمر لنفهمه، فلنفرض أن تطبيقك على شبكة داخلية وأن رابط Webhook يشير إلى عنوانه الخاص، فلن يصل أي طلب، وسوف تجد في سجل ال Worker ما يلي:

```text
ERROR  Received -4 status code. That's not OK. component=worker thread=work1 webhook=1 webhook_request=1
INFO   Will retry 2026-10-05 05:46:24 UTC (this was attempt 1) component=worker thread=work1 webhook=1 webhook_request=1
```

والسبب أن الإصدار 3.3.7 أضاف كما في [ملاحظات الإصدار](https://github.com/postalserver/postal/releases/tag/3.3.7?ref=arabroot.io) حماية من SSRF، أي أن Postal يرفض أن يرسل طلبات Webhooks ونقاط التسليم HTTP إلى العناوين الخاصة مثل `10.0.0.0/8` و`192.168.0.0/16` و`127.0.0.1` وعنوان بيانات السحابة `169.254.169.254`، والرمز `-4` هو رمزه الداخلي لطلب محظور. فإذا كان تطبيقك فعلاً على شبكة خاصة فأضف عنوانه أو اسمه صراحة إلى القائمة `allowed_request_destinations` في `postal.yml` ثم نفذ `postal restart`:

```yaml
postal:
  web_hostname: postal.example.com
  web_protocol: https
  smtp_hostname: postal.example.com
  allowed_request_destinations:
    - 10.0.0.5
```

ولا تضف شبكة كاملة إلى هذه القائمة، والسبب أن كل مستخدم في أي مؤسسة يستطيع أن ينشئ Webhook، فإذا سمحت بالشبكة كلها فقد أعطيته طريقاً إلى كل خدماتك الداخلية.

### البريد الوارد والمسارات Routes

إذا أردت أن يستقبل تطبيقك البريد، مثل الردود على تذاكر الدعم، فأضف سجل MX للنطاق كما في صفحة DNS Setup، ثم من **Routing** أنشئ نقطة تسليم Endpoint من نوع HTTP برابط في تطبيقك، ثم مساراً Route يربط عنواناً مثل `support` أو `*` لكل عناوين النطاق بها، فيرسل Postal كل رسالة واردة إلى تطبيقك طلب POST. وإذا كان للنطاق سيرفر بريد آخر فلا تغير MX، وإنما حول الرسائل منه إلى العنوان الخاص بالمسار على `routes.postal.example.com` كما يشرح [توثيق المسارات](https://docs.postalserver.io/features/routing-incoming-email?ref=arabroot.io). وينبه التوثيق نفسه إلى أن الخيار STARTTLS في نقاط التسليم من نوع SMTP لا يعمل في 3.3.7 بسبب خطأ في الكود ويتصرف كأنه دون تشفير، فاستخدم `Auto` أو `TLS` حتى يصلح.

## الواجهة خلف Reverse Proxy

إذا كان على السيرفر Reverse Proxy يملك المنفذين 80 و443 مثل [Nginx Proxy Manager](https://arabroot.io/articles/nginx-proxy-manager-%D9%86%D8%B7%D8%A7%D9%82%D8%A7%D8%AA-%D9%88%D8%B4%D9%87%D8%A7%D8%AF%D8%A7%D8%AA-tls/) أو [Traefik](https://arabroot.io/articles/%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-traefik-reverse-proxy/) أو [Caddy](https://arabroot.io/articles/%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-caddy-reverse-proxy/) الذي تستخدمه لتطبيقات أخرى، فلا تشغل Caddy الخاص بـ Postal، ووجه ال Proxy إلى الواجهة. والقاعدة الأولى أن ال Proxy يخدم HTTP فقط، أي الواجهة وال API وروابط التتبع، أما SMTP على 25 و587 فيبقى مباشرة من Postal، لأنه بروتوكول TCP وليس HTTP، ولأن فحص SPF على البريد الوارد يعتمد على عنوان المرسل الحقيقي.

والمسألة الثانية أن الواجهة تستمع على `127.0.0.1:5000` في شبكة السيرفر، بينما ال Proxy في Container على شبكة Docker لا يرى `127.0.0.1` الخاص بالسيرفر. والحل أن تجعل الواجهة تستمع على عنوان شبكة Docker الافتراضية في السيرفر بدل أن تفتحها على كل العناوين، ثم توجه ال Proxy إلى هذا العنوان، وتخبر Postal أن هذا ال Proxy موثوق حتى يقرأ عنوان المستخدم الحقيقي من الترويسات:

```yaml
postal:
  web_hostname: postal.example.com
  web_protocol: https
  smtp_hostname: postal.example.com
  trusted_proxies:
    - 172.16.0.0/12

web_server:
  default_bind_address: 172.17.0.1
```

في الإعداد أعلاه لاحظ التالي:

- `172.17.0.1` هو عنوان السيرفر على الشبكة `docker0` في التثبيت الافتراضي، فتأكد منه بالأمر `ip -4 addr show docker0`، ثم وجه ال Proxy Host إلى `http://172.17.0.1:5000`، وإذا كان `ufw` مفعلاً فاسمح بالمنفذ 5000 من شبكات Docker فقط، كما شرحنا في [دليل شبكات Docker](https://arabroot.io/articles/%D8%B4%D8%A8%D9%83%D8%A7%D8%AA-docker-%D9%88%D8%A3%D9%81%D8%B6%D9%84-%D8%A7%D9%84%D9%85%D9%85%D8%A7%D8%B1%D8%B3%D8%A7%D8%AA/).
- يجب أن يمرر ال Proxy الترويسة `Host` كما هي، لأن Postal يرفض أي طلب لا يطابق `web_hostname` كما سيأتي في المشكلات الشائعة، وNPM وTraefik يفعلان ذلك افتراضياً.
- إذا فعلت تتبع النقرات فاسم التتبع مثل `click.example.com` يحتاج إلى Proxy Host خاص يضيف الترويسة `X-Postal-Track-Host: 1` كما في [توثيق التتبع](https://docs.postalserver.io/features/click-and-open-tracking?ref=arabroot.io).

## تأمين المنصة

- **واجهة الإدارة:** من يدخل الواجهة يقرأ كل الرسائل ويولد مفاتيح جديدة ويرسل باسم نطاقاتك، لذلك لا تتركها مفتوحة للعالم إذا لم تكن مضطراً، وقيدها في ال Proxy بعناوين مكتبك، أو اجعلها لا تفتح إلا عبر [شبكة WireGuard الخاصة](https://arabroot.io/articles/%D8%B4%D8%A8%D9%83%D8%A9-%D8%AE%D8%A7%D8%B5%D8%A9-%D9%85%D8%B9-wireguard-%D9%88-wg-easy/)، مع ملاحظة أن مسار ال API `/api/` وروابط التتبع يجب أن تبقى متاحة للتطبيقات والمستلمين.
- **الصلاحيات Permissions:** بحسب [صفحة المستخدمين والصلاحيات](https://docs.postalserver.io/features/users-and-permissions?ref=arabroot.io) فالمستخدم العادي في مؤسسة يملك صلاحية كاملة على كل خوادم البريد فيها، ولا توجد صلاحية قراءة فقط ولا صلاحية لخادم واحد، لذلك افصل الفرق في مؤسسات مختلفة، وقلل عدد المديرين. وإذا كان لديك نظام دخول موحد SSO فـ Postal يدعم [OpenID Connect](https://docs.postalserver.io/features/oidc?ref=arabroot.io)، ويمكنك أن تربطه بـ [authentik](https://arabroot.io/articles/%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-authentik-%D9%84%D9%84%D8%AF%D8%AE%D9%88%D9%84-%D8%A7%D9%84%D9%85%D9%88%D8%AD%D8%AF/).
- **المفاتيح:** مفتاح لكل تطبيق كما ذكرنا، وفي الكود ضعه في متغير بيئة أو مدير أسرار Secrets Manager، ولا تكتبه في المستودع، وإذا ظهر في سجل أو في رسالة دعم فاحذفه وأنشئ غيره.
- **مفتاح التوقيع:** الأمر `bootstrap` يجعل صلاحية `signing.key` القيمة 644، أي يقرؤه أي مستخدم على السيرفر، ومن يملكه يستطيع أن يوقع رسائل باسم نطاق مسار الرجوع وطلبات Webhooks تقبلها تطبيقاتك، فاجعل ملكيته للمستخدم 999 الذي يعمل به Postal واقصر قراءته عليه بالأمرين `sudo chown 999:999 /opt/postal/config/signing.key` و`sudo chmod 600 /opt/postal/config/signing.key`.
- **التحديثات الأمنية:** الإصدار 3.3.7 أغلق ثغرة SQL Injection في قواعد بيانات الرسائل، وثغرة SSRF في Webhooks، كما في [ملاحظات الإصدار](https://github.com/postalserver/postal/releases/tag/3.3.7?ref=arabroot.io)، فلا تؤجل التحديثات، وراقب [صفحة الإصدارات](https://github.com/postalserver/postal/releases?ref=arabroot.io).

## التحقق من النجاح Verification

- صفحة النطاق تعرض SPF وDKIM بالحالة `OK`، والتحذير الأحمر في أعلى صفحة الخادم اختفى.
- رسالة عبر SMTP ورسالة عبر ال API بالحالة `SENT` في السجل، وكل منهما يظهر عليها المفتاح الذي أرسلها.
- أرسل رسالة إلى حساب Gmail وافتح **Show original**، وتأكد أن SPF وDKIM وDMARC بالحالة `PASS`، وأن التوقيع `d=example.com` وليس `d=rp.postal.example.com`، وللتقييم الكامل أرسل إلى [mail-tester.com](https://www.mail-tester.com/?ref=arabroot.io) كما يقترح [التوثيق](https://docs.postalserver.io/welcome/faqs?ref=arabroot.io).
- تطبيقك استقبل حدث `MessageSent` وتحقق من توقيعه.
- محاولة إرسال دون مصادقة إلى نطاق خارجي ترد بـ `530 Authentication required`.

سجل PTR يعيد اسم السيرفر، والاسم يعيد نفس العنوان:

```bash
dig +short -x 203.0.113.10
dig +short A postal.example.com
```

## النسخ الاحتياطي والاستعادة Restore

كل ما يحتاجه Postal في مكانين: قواعد البيانات في MariaDB، أي `postal` للإعداد والمستخدمين والنطاقات والمفاتيح، وقاعدة `postal-server-N` لكل خادم بريد وفيها الرسائل، ثم مجلد `/opt/postal/config` وفيه `postal.yml` و`signing.key` وشهادة SMTP. ولا تنس `signing.key` بالذات، فإذا ضاع فسوف تحتاج إلى نشر سجل DKIM جديد لنطاق مسار الرجوع، وإلى تحديث المفتاح العام في كل تطبيق يتحقق من توقيع Webhooks. أما ملف `docker-compose.override.yml` إذا أضفته فاحفظه معهما.

والسكربت التالي ينسخ كل قواعد Postal بأداة [mariadb-dump](https://mariadb.com/kb/en/mariadb-dump/?ref=arabroot.io) دون إيقاف الخدمة، والخيار `--single-transaction` يأخذ صورة متسقة من جداول InnoDB أثناء العمل، ثم ينسخ مجلد الإعداد:

```bash
#!/bin/bash
set -e
DB_PASSWORD='DB_PASSWORD'
OUT=/opt/backup/postal
mkdir -p "$OUT"
DBS=$(docker exec postal-mariadb mariadb -uroot -p"$DB_PASSWORD" -N -e "SHOW DATABASES LIKE 'postal%'")
docker exec postal-mariadb mariadb-dump -uroot -p"$DB_PASSWORD" \
  --single-transaction --routines --databases $DBS | gzip > "$OUT/postal-db-$(date +%F).sql.gz"
tar czf "$OUT/postal-config-$(date +%F).tar.gz" -C /opt/postal config install/docker-compose.override.yml
chmod 600 "$OUT"/*
```

في السكربت أعلاه لاحظ التالي:

- ملفات النسخ فيها الرسائل ومفتاح التوقيع، لذلك جعلنا صلاحيتها 600، ثم انقلها إلى تخزين خارجي Offsite Storage بأداة مثل [restic](https://restic.net/?ref=arabroot.io)، والسبب أن نسخة على قرص السيرفر نفسه لا تحميك إذا تعطل السيرفر.
- إذا لم تكن قد أضفت ملف `docker-compose.override.yml` فاحذف اسمه من سطر `tar`.

الاستعلام `SHOW DATABASES LIKE 'postal%'` يجمع القاعدة الرئيسية وكل قواعد خوادم البريد، فإذا أنشأت خادماً جديداً غداً دخل في النسخة تلقائياً، والمخرج في سيرفر عليه خادم بريد واحد كما يلي:

```text
postal
postal-server-1
```

وللاستعادة على سيرفر جديد ثبت Docker ومستودع التثبيت وMariaDB كما في قسم التثبيت بنفس كلمة المرور، ثم فك مجلد الإعداد إلى `/opt/postal`، واستورد قواعد البيانات، ثم شغل الإصدار نفسه:

```bash
sudo tar xzf postal-config-2026-10-05.tar.gz -C /opt/postal
gunzip -c postal-db-2026-10-05.sql.gz | docker exec -i postal-mariadb mariadb -uroot -p'DB_PASSWORD'
sudo postal set-version 3.3.7
sudo postal upgrade-db
sudo postal start
```

الأمر `set-version` يولد ملف Compose للإصدار الذي أخذت منه النسخة، و[التوثيق](https://docs.postalserver.io/getting-started/postal-command?ref=arabroot.io) يوصي بالأمر `upgrade-db` بعد استعادة قاعدة من تثبيت آخر حتى تطبق أي تعديلات ناقصة على الجداول. وتذكر بعد الاستعادة أن عنوان IP تغير غالباً، فعدل سجل `spf.postal.example.com` وسجلات A وPTR، وإذا كان العنوان الجديد جديداً فعلاً فهو يحتاج إلى تسخين من البداية.

## التحديث إلى إصدار أحدث

التحديث في Postal أمر واحد كما في [صفحة التحديث](https://docs.postalserver.io/getting-started/upgrading?ref=arabroot.io)، فهو يسحب آخر نسخة من مستودع التثبيت، ثم ال Image الجديد، ثم يطبق تعديلات قاعدة البيانات، ثم يعيد تشغيل كل الخدمات، ولكنه ليس تحديثاً دون توقف Zero Downtime، لذلك نفذه في وقت هادئ وبعد نسخة احتياطية:

```bash
cd /opt/postal/install
sudo git pull origin
sudo postal upgrade 3.3.7
```

ولاحظ أننا كتبنا رقم الإصدار، والسبب أن `postal upgrade` دون رقم ينتقل إلى أحدث إصدار منشور على GitHub أياً كان، أما مع الرقم فأنت تقرأ [ملاحظات الإصدار](https://github.com/postalserver/postal/releases?ref=arabroot.io) أولاً ثم تقرر، فضع مكان `3.3.7` الإصدار الذي تريد الانتقال إليه. وبعد التحديث تأكد من الإصدار الفعلي:

```bash
sudo postal version
```

والمخرج سوف يكون كما يلي:

```text
Loading config from /config/postal.yml
3.3.7
```

ثم احذف ال Image القديم بوسمه، مثل `docker image rm ghcr.io/postalserver/postal:3.3.6`، فكل Image من Postal قرابة 1.3 GB. ولا تحدث MariaDB في نفس اليوم، بل حدثها في نافذة منفصلة بعد نسخة احتياطية، حتى إذا ظهرت مشكلة تعرف سببها.

## مشكلات شائعة وحلولها Troubleshooting

### الواجهة ترد 403 Forbidden

يقبل Postal الطلبات فقط إذا كانت الترويسة `Host` تطابق `web_hostname` في `postal.yml`، فإذا فتحت الواجهة بعنوان IP أو باسم آخر، أو كان ال Proxy يغير الترويسة، فالرد 403 دون أي صفحة خطأ، وفي سجل الواجهة `postal logs web` ستجد الطلبات بالرمز 403\. افتحها بالاسم الذي كتبته في الإعداد، وإذا غيرت الاسم فعدل `web_hostname` ثم نفذ `postal restart`.

### postal initialize يفشل بخطأ طويل من Rails

إذا انتهى المخرج بالسطر `Tasks: TOP => db:create` بعد صفحة من أسطر Ruby، فـ Postal لم يستطع الاتصال بـ MariaDB، والسبب الأشهر أنك نفذت الأمر قبل أن تكمل MariaDB تهيئتها في أول تشغيل، أو أن كلمة المرور في `postal.yml` لا تطابق `MARIADB_ROOT_PASSWORD`. انتظر حتى تجد في `docker logs postal-mariadb` السطر `ready for connections`، وراجع كلمة المرور، ثم أعد الأمر، فهو آمن للتكرار.

### التطبيق يأخذ 530 From/Sender name is not valid

نطاق العنوان في `From` غير مضاف إلى خادم البريد الذي يملك المفتاح ولا إلى مؤسسته، أو أنه نطاق فرعي لم تضفه بعينه، أو أن النطاق مضاف ولم يتحقق منه بعد. وفي ال API نفس المشكلة تظهر بالرمز `UnauthenticatedFromAddress`. أضف النطاق إلى الخادم الصحيح، وتأكد أن التطبيق يستخدم مفتاح هذا الخادم.

### Webhooks لا تصل والسجل يقول -4

الرابط يشير إلى عنوان خاص أو داخلي، وحماية SSRF في 3.3.7 تمنعه، فأضف العنوان بعينه إلى `allowed_request_destinations` كما في قسم Webhooks. وإذا كان الرمز `-3` فالمشكلة في شهادة HTTPS لتطبيقك، فـ Postal يتحقق منها ولا يقبل شهادة موقعة ذاتياً Self-signed. وتجد تاريخ كل طلب ورده في **Webhooks › View History**.

### رسائل استعادة كلمة مرور الواجهة لا تصل

هذه الرسائل تخرج عبر قسم `smtp` في `postal.yml` وليس عبر خادم بريد في الواجهة، فتأكد أن المنفذ 25 وليس 2525 كما في القالب، وأن `from_address` عنوان كامل بعلامة @ وليس `postal.example.com` الذي تركه `bootstrap`، وأن كلمة المرور مفتاح SMTP صالح ونطاق العنوان مضاف إلى خادم البريد، ثم اختبر بالأمر `postal test-app-smtp`.

### رسائلك تصل إلى Spam

- **التوقيع بنطاق المنصة:** إذا وجدت `d=rp.postal.example.com` في ترويسة DKIM فسجل DKIM الخاص بنطاقك ليس `OK` بعد، فراجع صفحة DNS Setup.
- **PTR واسم EHLO:** تأكد أن PTR يعيد `postal.example.com`، وهو نفس `smtp_hostname` الذي يقدمه Postal للسيرفرات الأخرى.
- **عنوان IP في قوائم الحظر:** افحصه لدى [Spamhaus](https://www.spamhaus.org/?ref=arabroot.io) و[MXToolbox](https://mxtoolbox.com/blacklists.aspx?ref=arabroot.io).
- **عنوان جديد بحجم كبير:** خفف الحجم وارجع إلى قسم التسخين، واستخدم حد الإرسال حتى لا يغرق تطبيق واحد سمعة السيرفر كله.

### الرسائل تبقى في الطابور Queue

افتح **Messages › Queue** ثم سجل ال Worker بالأمر `postal logs worker`، فإذا وجدت محاولات اتصال تنتهي مهلتها إلى المنفذ 25 لكل المستلمين فالمزود يحجب المنفذ الصادر، وارجع إلى اختبار `nc` في قسم المتطلبات. وإذا كانت الرسائل بالحالة Held وليست في الطابور، فالسبب أحد أسباب الحجز: الخادم في وضع Development، أو المفتاح مضبوط على Hold، أو المستلم في قائمة الحظر، أو تجاوز حد الإرسال، وتجد السبب في صفحة الرسالة.

## الخلاصة

وصلنا لنهاية الموضوع، وأهم ما فيه:

- Postal منصة إرسال مثل Amazon SES على سيرفرك تحت ترخيص MIT، للبريد الذي ترسله تطبيقاتك وليس لصناديق الموظفين، وتختاره عندما تريد البيانات والسجل تحت يدك وتستطيع أن تبني سمعة عنوان IP بنفسك.
- ثبته بالأداة الرسمية `postal` على سيرفر مخصص فيه المنفذ 25 مفتوح وPTR صحيح، مع MariaDB بوسم ثابت وVolume باسم، وصحح في `postal.yml` كلمة المرور ومنفذ قسم `smtp` والعنوان `from_address`.
- انشر سجلات المنصة مرة واحدة، ثم لكل نطاق انشر SPF وDKIM و`psrp` التي تعرضها صفحة DNS Setup، ولا ترسل بريداً حقيقياً قبل أن يصبح DKIM بالحالة `OK`، ولا تضع MX لـ Postal على نطاق عليه بريد الموظفين.
- مفتاح لكل تطبيق، وفعل TLS على SMTP، وأضف المنفذ 587 بملف override، واستخدم ال API عندما تريد رقم الرسالة مباشرة، ثم Webhooks موقعة لتعرف ما حدث لكل رسالة.
- انسخ قواعد `postal%` ومجلد الإعداد ومعه `signing.key` يومياً إلى تخزين خارجي، وحدث بالأمر `postal upgrade` مع رقم الإصدار بعد قراءة ملاحظاته.

وإذا قررت أن البداية الأنسب لك خدمة مدارة، أو أردت أن تراجع المفاهيم التي بني عليها هذا الدليل، فهذه المقالات تكمل الصورة:

[![](https://arabroot.io/content/images/2026/10/transactional-email-cover-cover.webp)دليلالبريد التفاعلي Transactional Email: كيف تصل رسائل تطبيقك في وقتهارابط استعادة كلمة المرور الذي لا يصل يعني مستخدماً لا يستطيع الدخول، لذلك نشرح ما هو البريد التفاعلي ولماذا تفصله عن النشرات بنطاق وسمعة مستقلين، وكيف ترسله من تطبيقك بطابور وإعادة محاولة، ومتى تختار Amazon SES أو منصة تستضيفها بنفسك مثل Postal.](https://arabroot.io/articles/%D8%A7%D9%84%D8%A8%D8%B1%D9%8A%D8%AF-%D8%A7%D9%84%D8%AA%D9%81%D8%A7%D8%B9%D9%84%D9%8A-transactional-email/)[![](https://arabroot.io/content/images/2026/10/amazon-ses-relay-cover-cover.webp)دليلإرسال بريد خادمك عبر Amazon SES مع mailcow وPostfix وStalwartإذا كان مزودك يحجب المنفذ 25 أو كانت رسائل سيرفرك الجديد تصل إلى Spam، فسوف نرسل البريد الصادر عبر Amazon SES ويبقى الاستقبال والصناديق على سيرفرك، مع DKIM وMAIL FROM وDMARC والارتدادات، والإعداد الدقيق لكل خادم بريد وأي تطبيق.](https://arabroot.io/articles/%D8%A7%D8%B1%D8%B3%D8%A7%D9%84-%D8%A8%D8%B1%D9%8A%D8%AF%D9%83-%D8%B9%D8%A8%D8%B1-amazon-ses/)[![](https://arabroot.io/content/images/2026/10/email-authentication-cover-cover.webp)دليلشرح SPF وDKIM وDMARC للمبتدئين: كيف تثبت أن رسائلك منك فعلاًلماذا يستطيع أي شخص أن يرسل باسم نطاقك، وكيف جاء كل من SPF وDKIM وDMARC ليسد ثغرة تركها الذي قبله، مع قراءة السجلات جزءاً جزءاً وطرق اختبار بريدك بالخدمات المجانية.](https://arabroot.io/articles/%D8%B4%D8%B1%D8%AD-spf-%D9%88-dkim-%D9%88-dmarc-%D9%84%D9%84%D9%85%D8%A8%D8%AA%D8%AF%D8%A6%D9%8A%D9%86/)[![](https://arabroot.io/content/images/2026/10/email-hosting-guide-cover-cover.webp)دليلكيف تستضيف بريد مؤسستك بنفسك: دليل عملي من القرار إلى التشغيلمتى تستضيف بريد شركتك أو جامعتك بنفسك ومتى يكون البريد المستضاف أنسب، وما الذي تجهزه قبل البدء، وكيف تنقل المستخدمين على مراحل دون أن تضيع رسالة، مع مسار قراءة يجمع كل أدلة البريد على الموقع.](https://arabroot.io/articles/%D8%AF%D9%84%D9%8A%D9%84-%D8%A7%D8%B3%D8%AA%D8%B6%D8%A7%D9%81%D8%A9-%D8%A7%D9%84%D8%A8%D8%B1%D9%8A%D8%AF-%D8%A7%D9%84%D8%A5%D9%84%D9%83%D8%AA%D8%B1%D9%88%D9%86%D9%8A-%D9%84%D9%84%D9%85%D8%A4%D8%B3%D8%B3%D8%A7%D8%AA/)

## سجل التحديثات Changelog

- أكتوبر 2026: كتابة الدليل واختباره على Postal 3.3.7.