> ## 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.

# تثبيت خادم البريد Stalwart باستخدام Docker Compose
- URL: https://arabroot.io/articles/تثبيت-خادم-البريد-stalwart/
- Published: 2026-10-04T20:30:00.000Z
- Updated: 2026-10-05T06:20:53.000Z
- Description: خادم بريد كامل في برنامج واحد بدل عدة مكونات تضبط كلاً منها على حدة. يشرح هذا الدليل تثبيت Stalwart على Ubuntu، ونشر سجلات DNS التي يولدها لك، والشهادة والنسخ الاحتياطي والتحديث.
- Author: فريق عرب رووت
- Tags: الأدلة التقنية, البريد الإلكتروني, الاستضافة الذاتية, Stalwart

في هذا الدليل سوف نثبت [Stalwart](https://stalw.art/?ref=arabroot.io)، وهو خادم بريد Mail Server في برنامج واحد مكتوب بلغة Rust يقوم بكل الأدوار من الداخل: SMTP لاستقبال البريد وإرساله، وIMAP وPOP3 و[JMAP](https://jmap.io/?ref=arabroot.io) لقراءته، وManageSieve لقواعد الفرز Filtering Rules، وCalDAV وCardDAV وWebDAV للتقويم Calendar وجهات الاتصال Contacts والملفات، ومعها فلتر للرسائل المزعجة Spam، وتوقيع DKIM والتحقق من SPF وDMARC وARC، وإصدار شهادات Let's Encrypt عبر ACME، ولوحة إدارة Admin Panel من المتصفح. وبالتالي فبدل أن تضبط عشرة ملفات إعداد Configuration Files وتتأكد أنها متفقة فيما بينها كما في [دليل خادم البريد مع Postfix وDovecot](https://arabroot.io/articles/%D8%AE%D8%A7%D8%AF%D9%85-%D8%A8%D8%B1%D9%8A%D8%AF-postfix-%D9%88-dovecot-%D9%8A%D8%AF%D9%88%D9%8A%D8%A7/)، أو تشغل حزمة من عدة Containers كما في [دليل mailcow](https://arabroot.io/articles/%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-%D8%AE%D8%A7%D8%AF%D9%85-%D8%A8%D8%B1%D9%8A%D8%AF-mailcow/)، سوف تشغل Container واحداً وتجيب على خمس شاشات في معالج الإعداد Setup Wizard.

وإذا لم تقرر بعد هل تستضيف بريد مؤسستك بنفسك، وأي الخيارات الثلاثة يناسبك، فالصورة الكاملة من القرار إلى خطة النقل في [دليل استضافة البريد الإلكتروني للمؤسسات](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/).

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

- ما هو Stalwart، وهل هو ناضج بما يكفي لبريد شركتك، وما الفرق بين الإصدار المجاني والإصدار التجاري Enterprise.
- المتطلبات والمنافذ Ports، والتثبيت باستخدام Docker Compose على Ubuntu 24.04، ثم معالج الإعداد الأول وكلمة مرور المدير المؤقتة.
- إضافة النطاقات Domains وصناديق البريد، وسجلات DNS التي يولدها Stalwart لك وطريقة نشرها، وسجل PTR لدى المزود.
- الشهادة عبر ACME المدمج أو خلف Reverse Proxy، وأي المنافذ يجب أن تبقى مباشرة.
- فلتر الرسائل المزعجة، والتحقق من الإرسال والاستقبال، والنسخ الاحتياطي Backup، والتحديث Upgrade، وأشهر المشكلات وحلولها.

## ما هو Stalwart ولماذا خادم واحد بدل عدة خوادم؟

لكي تفهم ما الذي يغيره Stalwart، تخيل رسالة تصل إلى سيرفر Server بريد تقليدي: يستقبلها Postfix على المنفذ 25، ثم يمررها إلى Rspamd عبر بروتوكول Milter ليفحصها، ثم يسلمها إلى Dovecot عبر LMTP ليحفظها في صندوق المستخدم، وعندما يرسل المستخدم رداً يتحقق Postfix من كلمة مروره بسؤال Dovecot عبر SASL، ثم يمرر الرسالة إلى برنامج التوقيع ليضيف DKIM. وكل سهم في هذه السلسلة هو إعداد عليك أن تكتبه بنفسك، وكل برنامج يحتاج إلى تحديث منفصل، وعندما لا تصل رسالة فأنت تبحث في أربعة سجلات مختلفة.

والحل الذي جاء به mailcow هو أن يجمع هذه البرامج في Containers مضبوطة مسبقاً، وهذا حل ممتاز ومجرب، ولكنه لا يلغي التعدد، وإنما يخفيه خلف سكربت Script تثبيت، لذلك يحتاج mailcow إلى [6 GiB من الذاكرة على الأقل](https://docs.mailcow.email/getstarted/prerequisite-system/?ref=arabroot.io) وإلى قرابة 18 Docker Image. أما Stalwart فكتب كل هذه الوظائف في برنامج واحد يشترك في قاعدة بيانات واحدة وسجل واحد ولوحة واحدة، وبالتالي تكفيه [قرابة 1 GB من الذاكرة لفريق من 5 إلى 10 مستخدمين](https://stalw.art/docs/install/requirements/?ref=arabroot.io)، ويحتاج وهو خامل إلى نحو 100 MB فقط بحسب التوثيق.

ولاحظ أن Stalwart لا يتضمن بريداً عبر الويب Webmail مثل SOGo في mailcow، حيث تقدم [واجهته](https://stalw.art/docs/management/webui/?ref=arabroot.io) مسارين فقط: `/admin` لإدارة السيرفر، و`/account` ليغير المستخدم كلمة مروره ويدير كلمات مرور التطبيقات App Passwords والتحقق الثنائي Two-Factor Authentication. أما قراءة البريد فتكون من برامج البريد Mail Clients مثل Thunderbird وOutlook وتطبيقات الهواتف، فإذا كان فريقك يعتمد على البريد من المتصفح فعليك أن تضيف تطبيق Webmail مستقلاً، أو تختار mailcow.

### هل Stalwart ناضج بما يكفي مقارنة بـ Postfix وDovecot؟

وقد يتساءل البعض: كيف أضع بريد الشركة على برنامج إصداره 0.16، بينما يعمل [Postfix](https://www.postfix.org/?ref=arabroot.io) و[Dovecot](https://www.dovecot.org/?ref=arabroot.io) منذ أكثر من عشرين عاماً على عدد كبير من سيرفرات البريد في العالم؟ والإجابة تحتاج إلى تفصيل، فمن جهة يذكر [التوثيق الرسمي](https://stalw.art/docs/faq/?ref=arabroot.io) أن Stalwart يعمل في بيئات إنتاج Production حول العالم، وأنه اجتاز [تدقيقاً أمنياً Security Audit](https://stalw.art/blog/security-audit?ref=arabroot.io) أجرته شركة Radically Open Security في أكتوبر 2023 دون أن تجد ثغرات، ولغة Rust تمنع فئة كاملة من أخطاء الذاكرة Memory Safety Bugs التي عانت منها برامج البريد المكتوبة بلغة C. ومن جهة أخرى فهذا التدقيق كان على إصدار 0.3 والكود تغير كثيراً منذ ذلك الوقت، والمشروع نفسه يقول في التوثيق إن إصدارات ما قبل 1.0 قد تغير طريقة تخزين البيانات والإعداد وتحتاج إلى ترحيل Migration.

وهذا ليس كلاماً نظرياً، ففي الإصدار 0.16 تغيرت طبقة الإعداد والإدارة بالكامل، حيث اختفت ملفات TOML وأصبح كل الإعداد كائنات Objects داخل قاعدة البيانات تديرها عبر JMAP، واختفت واجهة `/api` القديمة، وأصبح اسم كل حساب عنوان بريد كاملاً، وتصف [وثيقة الترقية من 0.15](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING/v0%5F16.md?ref=arabroot.io) هذا التغيير بأنه غير متوافق كلياً مع كل ما سبقه ويحتاج إلى ترحيل من عدة خطوات مع توقف للخدمة. لذلك فالحكم العملي كما يلي: إذا كنت تبني بريداً جديداً لفريق صغير أو متوسط وتقبل أن تقرأ ملاحظات الإصدار Release Notes قبل كل ترقية، فـ Stalwart خيار جيد وخفيف وحديث، أما إذا كانت جهتك لا تحتمل أي ترحيل غير مخطط له، أو تحتاج إلى بريد عبر الويب جاهز، فـ mailcow أو Postfix مع Dovecot هما الأنسب حتى يصدر Stalwart 1.0.

### ما الذي تحصل عليه مجاناً وما الذي يحتاج ترخيص Enterprise؟

يصدر Stalwart بترخيصين Licenses على [نفس الكود](https://github.com/stalwartlabs/stalwart?ref=arabroot.io)، فالإصدار المجتمعي Community Edition مجاني تحت ترخيص [AGPL-3.0](https://github.com/stalwartlabs/stalwart/blob/main/LICENSES/AGPL-3.0-only.txt?ref=arabroot.io)، والإصدار التجاري Enterprise تحت [ترخيص Stalwart Enterprise License v2](https://github.com/stalwartlabs/stalwart/blob/main/LICENSES/LicenseRef-SEL.txt?ref=arabroot.io) ويباع اشتراكاً لكل صندوق بريد. ويتضمن الإصدار المجاني كل ما يحتاجه هذا الدليل: البروتوكولات كلها، وDKIM وSPF وDMARC وMTA-STS وDANE، وإدارة سجلات DNS التلقائية وتدوير Rotation مفاتيح DKIM، وفلتر الرسائل المزعجة، وLDAP وOpenID Connect، والتشفير على القرص Encryption at Rest. أما الميزات الحصرية للإصدار التجاري كما تسردها [صفحة المقارنة](https://stalw.art/compare/?ref=arabroot.io) فأهمها: لوحة المعلومات Dashboard بالإحصاءات المباشرة، وتعدد المستأجرين Multi-tenancy، وفلتر الرسائل المزعجة بالذكاء الاصطناعي AI / LLM، وأرشفة الحسابات واستعادة الرسائل المحذوفة، وSCIM، وسجل تسليم الرسائل Message Delivery History، والتنبيهات على المقاييس Metric Alerts. ولهذا السبب سوف ترى بجوار **Dashboard** و**Tenants** في القائمة الجانبية رمز قفل في الإصدار المجاني.

ويجدر الإشارة هنا إلى أمرين: الأول أن ترخيص AGPL لا يفرض عليك شيئاً ما دمت تشغل البرنامج كما هو، وإنما يلزمك بنشر الكود إذا عدلته وقدمته خدمة عبر الشبكة، والثاني أن [المشروع](https://github.com/stalwartlabs/stalwart?ref=arabroot.io#sponsorship) يمنح ترخيص Enterprise تلقائياً لمن يدعمه عبر [Open Collective](https://opencollective.com/stalwart?ref=arabroot.io) بخمسة دولارات شهرياً أو أكثر.

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

### السيرفر

- **الذاكرة RAM والمعالج CPU:** نواة واحدة و1 GB من الذاكرة تكفي لفريق صغير بحسب [صفحة المتطلبات](https://stalw.art/docs/install/requirements/?ref=arabroot.io)، ونحن ننصح بـ 2 GB على الأقل حتى يبقى هامش لنظام التشغيل وDocker وللحظات الضغط، وزد الموارد مع عدد الاتصالات المتزامنة Concurrent Connections، فالحد الافتراضي 8192 اتصالاً تتشاركها كل الخدمات.
- **القرص Disk:** الـ Docker Image نفسه قرابة 400 MB، وبقية المساحة للرسائل، فاحسبها من عدد الصناديق وحصة Quota كل صندوق.
- **النظام:** Ubuntu 24.04 مع Docker Engine وإضافة Docker Compose، وإذا لم يكن Docker مثبتاً فاتبع [دليل تثبيت 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/).
- **الاتصال الصادر Outbound:** عند التشغيل الأول ينزل Stalwart واجهة الإدارة من [إصدارات GitHub](https://stalw.art/docs/management/webui/?ref=arabroot.io)، ويتصل بـ Let's Encrypt لإصدار الشهادة، ويستعلم من DNS على المنفذ 53، فإذا كان جدار الحماية Firewall لدى المزود يمنع الاتصال الصادر فاسمح بهذه الثلاثة.
- **عنوان IP ثابت Static IP ونظيف، والمنفذ 25 مفتوح:** كثير من المزودين يحجبون المنفذ 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/)، وسوف نعود إلى المنفذ 25 في قسم مستقل.

### المنافذ: ما الذي يفتح للإنترنت وما الذي يبقى مغلقاً؟

ينشئ Stalwart عند الإعداد مستمعات Listeners لعدة خدمات، ولكن [توصية التوثيق الرسمي](https://stalw.art/docs/install/security/?ref=arabroot.io) أن تفتح فقط ما تحتاجه، والسبب أن كل منفذ مفتوح هو باب إضافي لمحاولات التخمين Brute-force والفحص Scanning حتى لو كانت الخدمة خلفه آمنة. والجدول التالي يلخص القرار:

| المنفذ    | الخدمة                                        | القرار                                                                                                              |
| --------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| 25/tcp    | SMTP                                          | مفتوح للإنترنت، وبه تستقبل البريد من السيرفرات الأخرى                                                               |
| 465/tcp   | SMTPS (Submission عبر TLS مباشر Implicit TLS) | مفتوح، وبه يرسل المستخدمون من برامج البريد، والتوثيق يفضله على 587                                                  |
| 993/tcp   | IMAPS                                         | مفتوح، لقراءة البريد من البرامج والهواتف                                                                            |
| 443/tcp   | HTTPS                                         | مفتوح، للوحة الإدارة وJMAP وautoconfig وMTA-STS وللتحقق من ملكية الاسم عند إصدار الشهادة                            |
| 8080/tcp  | HTTP                                          | للإعداد الأول فقط، ولا يفتح للإنترنت أبداً، ونغلقه بعد الإعداد                                                      |
| 995 و4190 | POP3S وManageSieve                            | لهما مستمعان افتراضياً، ولكن لا تنشرهما إلا إذا احتاجهما مستخدموك                                                   |
| 587 و143  | Submission عبر STARTTLS وIMAP دون تشفير       | لا ينشئ الإعداد الافتراضي في 0.16 مستمعاً لهما، وتضيفهما من Settings › Network › Listeners إذا احتاجهما برنامج قديم |

ولاحظ أن Docker ينشر المنافذ Publish متجاوزاً قواعد `ufw` كما شرحنا في [دليل تثبيت Docker](https://arabroot.io/articles/%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-docker-%D8%B9%D9%84%D9%89-ubuntu/)، لذلك فقائمة `ports` في ملف Compose هي جدار الحماية الحقيقي لهذه الخدمة، فلا تضع فيها منفذاً لا تريده مفتوحاً، ومع ذلك أضف القواعد إلى `ufw` حتى يبقى الإعداد واضحاً لمن يأتي بعدك:

```bash
sudo ufw allow 25,465,993,443/tcp
```

### أين يحفظ Stalwart بياناته؟

يقسم Stalwart التخزين Storage إلى [أربعة مخازن](https://stalw.art/docs/install/store/?ref=arabroot.io): مخزن البيانات Data Store للبيانات المنظمة مثل ترويسات الرسائل والمجلدات والتقويم وكل إعدادات السيرفر، ومخزن الملفات Blob Store لمحتوى الرسائل والمرفقات Attachments، ومخزن البحث Search Store لفهرس البحث النصي Full-text Search، والمخزن المؤقت In-memory Store للعدادات وحدود المعدل Rate Limits والجلسات. والإعداد الافتراضي أن تكون الأربعة كلها في [RocksDB](https://rocksdb.org/?ref=arabroot.io)، وهي قاعدة بيانات مدمجة Embedded Database تعمل داخل البرنامج نفسه وتحفظ ملفاتها في مجلد واحد، وهذا هو الأنسب لسيرفر واحد.

وفي الأنظمة الكبيرة يمكنك أن تنقل مخزن البيانات إلى PostgreSQL أو MySQL أو FoundationDB، والملفات إلى خدمة متوافقة مع S3، والبحث إلى Elasticsearch أو Meilisearch، والمخزن المؤقت إلى Redis، ولكن تغيير الخلفية Backend بعد التشغيل يحتاج إلى [ترحيل البيانات بالتصدير والاستيراد](https://stalw.art/docs/management/maintenance/migration/?ref=arabroot.io) والسيرفر متوقف، لذلك قرر من البداية، ونحن نبقى في هذا الدليل على RocksDB.

### اسم السيرفر وسجل A قبل التشغيل

هنا اسمان مختلفان يخلط بينهما كثيرون، فالأول هو **اسم خادم البريد** Hostname مثل `mail.example.com`، وبه يعرف السيرفر نفسه أمام السيرفرات الأخرى وله تصدر الشهادة، والثاني هو **نطاق البريد** مثل `example.com`، وهو ما يظهر بعد @ في العناوين. وإذا لم تكن مصطلحات DNS واضحة لديك فراجع [دليل مصطلحات الاستضافة الذاتية](https://arabroot.io/articles/%D9%85%D8%B5%D8%B7%D9%84%D8%AD%D8%A7%D8%AA-%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B6%D8%A7%D9%81%D8%A9-%D8%A7%D9%84%D8%B0%D8%A7%D8%AA%D9%8A%D8%A9-%D9%84%D9%84%D9%85%D8%A8%D8%AA%D8%AF%D8%A6%D9%8A%D9%86/). أضف الآن سجل A للاسم `mail.example.com` يشير إلى عنوان سيرفرك، وضع عنوانك مكان `203.0.113.10`، ثم تأكد منه قبل التثبيت، والسبب أن معالج الإعداد سوف يطلب الشهادة لهذا الاسم مباشرة بعد إعادة التشغيل:

```bash
dig +short A mail.example.com
```

وبقية السجلات (MX وSPF وDKIM وDMARC وغيرها) لا تكتبها الآن، لأن Stalwart سوف يولدها لك بقيمها الصحيحة بعد الإعداد كما سيأتي.

## التثبيت باستخدام Docker Compose

أنشئ مجلد الخدمة:

```bash
sudo mkdir -p /opt/stalwart
sudo chown $USER: /opt/stalwart
cd /opt/stalwart
```

والملف `/opt/stalwart/compose.yaml` سوف يكون كما يلي:

```yaml
services:
  stalwart:
    image: stalwartlabs/stalwart:v0.16.24
    container_name: stalwart
    restart: unless-stopped
    hostname: mail.example.com
    ports:
      - "25:25"
      - "465:465"
      - "993:993"
      - "443:443"
      - "127.0.0.1:8080:8080"
    volumes:
      - stalwart_etc:/etc/stalwart
      - stalwart_data:/var/lib/stalwart

volumes:
  stalwart_etc:
    name: stalwart_etc
  stalwart_data:
    name: stalwart_data
```

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

- **الوسم Tag:** ثبتنا الإصدار `v0.16.24` ولم نستخدم `latest`، والسبب أن [صفحة الترقية](https://stalw.art/docs/install/upgrade/?ref=arabroot.io) تحذر من أن `latest` قد يسحب إصداراً غير متوافق مع بياناتك دون أن تنتبه. وينشر المشروع أيضاً الوسم المختصر `v0.16` الذي يتحرك مع الإصدارات التصحيحية Patch Releases داخل نفس السلسلة، فإذا أردت التحديثات التصحيحية تلقائياً عند كل `pull` فاستخدمه، أما نحن فنفضل الوسم الكامل حتى يكون كل تغيير بقرار منك.
- **ال Volumes:** يحفظ `/etc/stalwart` ملف الإعداد `config.json` فقط، ويحفظ `/var/lib/stalwart` قاعدة RocksDB وفيها كل شيء آخر: الرسائل والحسابات والإعدادات ومفاتيح DKIM، وهما معاً كل ما تحتاج إلى نسخه احتياطياً. ويعمل البرنامج داخل ال Container بالمستخدم `stalwart` ورقمه UID 2000، و[التوثيق](https://stalw.art/docs/install/platform/docker/?ref=arabroot.io) ينبه إلى أنك إذا استخدمت مجلدات من السيرفر Bind Mounts بدل ال Volumes فيجب أن تكون ملكيتها لهذا الرقم (`chown 2000:2000`).
- **المنفذ 8080:** ربطناه بالعنوان `127.0.0.1` فقط، لأن معالج الإعداد يعمل عليه عبر HTTP دون تشفير، وكلمة مرور المدير المؤقتة تمر فيه، فلا يصح أن يكون مفتوحاً للإنترنت ولو لدقائق.
- **hostname:** يأخذ منه المعالج الاسم الافتراضي للسيرفر والنطاق، فاكتب اسم سيرفرك الحقيقي.

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

```bash
docker compose up -d
```

عند التشغيل الأول لا يجد Stalwart ملف `config.json`، فيدخل في وضع التهيئة Bootstrap Mode، وينشئ مديراً مؤقتاً بكلمة مرور عشوائية ويطبعها مرة واحدة فقط في السجل، فاقرأها بالأمر التالي:

```bash
docker logs stalwart 2>&1 | grep -A8 'bootstrap mode'
```

والمخرج سوف يكون كما يلي (وكلمة المرور عندك ستة عشر حرفاً عشوائياً):

```text
🔑 Stalwart bootstrap mode - temporary administrator account

   username: admin
   password: XXXXXXXXXXXXXXXX

Use these credentials to complete the initial setup at the
/admin web UI. Once setup is done, Stalwart will provision a
permanent administrator and this temporary account will no
longer apply.
```

وإذا أردت كلمة مرور ثابتة بدل البحث في السجل، فيمكنك أن تمرر متغير البيئة Environment Variable `STALWART_RECOVERY_ADMIN` بالصيغة `admin:كلمة-المرور`، ولكن تذكر أن تحذفه بعد الإعداد كما يوصي التوثيق، والسبب أنه باب خلفي ثابت إلى لوحة الإدارة.

## معالج الإعداد الأول Setup Wizard

المنفذ 8080 مربوط بالعنوان `127.0.0.1`، لذلك سوف نصل إليه من جهازك عبر نفق SSH Tunnel، فنفذ الأمر التالي على جهازك وليس على السيرفر:

```bash
ssh -L 8080:127.0.0.1:8080 user@203.0.113.10
```

ثم افتح `http://127.0.0.1:8080/admin` في متصفحك، واكتب `admin` ثم كلمة المرور المؤقتة، فيظهر المعالج مباشرة. والصورة التالية تبين الشاشة الأولى منه:

![الشاشة الأولى من معالج إعداد Stalwart: اسم السيرفر والنطاق الافتراضي والشهادة ومفاتيح DKIM](https://arabroot.io/content/images/2026/10/stalwart-01-setup-wizard.webp)

الخطوة الأولى من المعالج: اسم السيرفر `mail.example.com` والنطاق `example.com`، ومعهما خيارا الشهادة التلقائية ومفاتيح التوقيع

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

1. **هوية السيرفر Server Identity:** اسم السيرفر `mail.example.com` ونطاق البريد الافتراضي `example.com`، ثم خياران تتركهما مفعلين: **Automatically Obtain TLS Certificate** لطلب شهادة Let's Encrypt تلقائياً، و**Generate Email Signing Keys** لإنشاء مفاتيح DKIM للنطاق. ولا تعطل خيار الشهادة إلا إذا كنت سوف تضع Stalwart خلف Reverse Proxy أو ترفع شهادتك بنفسك.
2. **التخزين Storage:** اترك RocksDB في المسار `/var/lib/stalwart/`، واترك المخازن الثلاثة الأخرى على **Use data store**.
3. **دليل الحسابات Account Directory:** اترك **Use the internal directory** لتدير الحسابات من اللوحة، أو اختر LDAP أو OIDC إذا كان لديك نظام دخول موحد SSO.
4. **السجلات Logging:** غير القيمة من **Log file** إلى **Console**، والسبب كما يشرح [التوثيق](https://stalw.art/docs/install/platform/docker/?ref=arabroot.io) أن ملفات السجل داخل ال Container تضيع عند إعادة إنشائه، أما Console فيكتب إلى المخرج القياسي Standard Output الذي يحفظه Docker وتقرؤه بـ `docker logs`.
5. **إدارة DNS التلقائية:** اترك **Manual DNS server management** إذا كنت سوف تنشر السجلات بيدك، أو اختر مزودك إذا كان في القائمة الطويلة (Cloudflare وAWS Route53 وDigitalOcean وHetzner وOVH وGoDaddy وNamecheap وغيرها، وخادم BIND عبر RFC 2136)، فينشر Stalwart السجلات ويحدثها بنفسه عبر API المزود.

وعند الضغط على **Finish setup** يعرض المعالج حساب المدير الدائم، وهو بالصيغة `admin@example.com` مع كلمة مرور عشوائية جديدة، فاحفظهما الآن في مدير كلمات المرور Password Manager، لأن الشاشة لا تظهر مرة ثانية وكلمة المرور لا تكتب في السجل. ثم أعد تشغيل ال Container ليعمل بالإعداد الجديد:

```bash
docker compose restart stalwart
```

ولاحظ ما كتبه المعالج على القرص:

```bash
docker exec stalwart cat /etc/stalwart/config.json
```

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

```json
{"@type":"RocksDb","path":"/var/lib/stalwart/","blobSize":16834,"bufferSize":134217728,"poolWorkers":null,"cacheSize":134217728}
```

سطر واحد يصف قاعدة البيانات فقط، ولا يوجد فيه نطاق ولا حساب ولا منفذ، والسبب أن كل ذلك أصبح منذ الإصدار 0.16 كائنات داخل قاعدة البيانات نفسها، وبالتالي فلا يوجد ملف إعداد تعدله بيدك، وإنما تعدل كل شيء من اللوحة أو من أداة سطر الأوامر [stalwart-cli](https://stalw.art/docs/management/cli/?ref=arabroot.io). والآن تأكد من المستمعات التي بدأت بعد إعادة التشغيل:

```bash
docker logs stalwart 2>&1 | grep listen-start
```

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

```text
INFO Network listener started (network.listen-start) listenerId = "smtp", localIp = ::, localPort = 25, tls = false
INFO Network listener started (network.listen-start) listenerId = "submissions", localIp = ::, localPort = 465, tls = true
INFO Network listener started (network.listen-start) listenerId = "imaps", localIp = ::, localPort = 993, tls = true
INFO Network listener started (network.listen-start) listenerId = "pop3s", localIp = ::, localPort = 995, tls = true
INFO Network listener started (network.listen-start) listenerId = "sieve", localIp = ::, localPort = 4190, tls = false
INFO Network listener started (network.listen-start) listenerId = "https", localIp = ::, localPort = 443, tls = true
INFO Network listener started (network.listen-start) listenerId = "http", localIp = ::, localPort = 8080, tls = false
```

وتجد القائمة نفسها في اللوحة تحت **Settings › Network › Listeners**، ومنها تضيف مستمعاً أو تحذفه:

![قائمة المستمعات في إعدادات Stalwart مع البروتوكول والمنفذ وTLS المباشر](https://arabroot.io/content/images/2026/10/stalwart-02-listeners.webp)

المستمعات السبعة التي ينشئها الإعداد الافتراضي، والعمود الأخير يبين أيها يعمل بـ TLS مباشر Implicit TLS

بعد ذلك ادخل من العنوان النهائي `https://mail.example.com/admin` بحساب المدير الدائم، فإذا ظهر تحذير الشهادة في أول دقيقة فالسبب أن Stalwart يقدم شهادة مؤقتة Self-signed حتى تصدر شهادة Let's Encrypt، ثم احذف السطر `"127.0.0.1:8080:8080"` من ملف Compose ونفذ `docker compose up -d`، و[التوثيق](https://stalw.art/docs/install/security/?ref=arabroot.io) يوصي أيضاً بحذف المستمع `http` نفسه من القائمة أعلاه إذا لم تكن سوف تضع Stalwart خلف Reverse Proxy.

💡

لا تستخدم حساب المدير لقراءة البريد عبر IMAP أو JMAP في برنامج بريد، و[التوثيق يوصي](https://stalw.art/docs/install/security/?ref=arabroot.io) بذلك صراحة، والسبب أن برامج البريد تحفظ كلمة المرور على الأجهزة والهواتف، وتسريبها من هناك يعني تسريب مفاتيح السيرفر كله. أنشئ لنفسك صندوق بريد عادياً، وفعل التحقق الثنائي لحساب المدير من صفحة الحساب.

## إضافة النطاقات وصناديق البريد

النطاق الذي كتبته في المعالج موجود مسبقاً، وتجده في **Management › Domains › Domains**، ومن الصفحة نفسها تضيف أي نطاق آخر بالزر **Create domain**، ولاحظ أن سيرفراً واحداً باسم `mail.example.com` يستطيع أن يخدم عدة نطاقات، وكل نطاق يحتاج إلى سجلاته الخاصة. وفي صفحة النطاق خيارات مفيدة مثل عنوان الالتقاط Catch-All الذي يستقبل الرسائل الموجهة إلى عناوين غير موجودة، والعناوين الفرعية Sub-addressing مثل `alice+news@example.com`.

ولإنشاء صندوق بريد افتح **Directory › Accounts** ثم **Create user**، واكتب الجزء الأيسر من العنوان في **Username** مثل `alice`، ثم اختر النطاق من زر البحث بجوار **Domain**، ثم من قسم **Credentials** اضغط **Add item** واكتب كلمة المرور، واحفظ بالزر **Create**. ومن نفس النموذج تضيف عناوين بديلة Email Aliases للحساب، وحصة Quota للمساحة، والمجموعات Groups والأدوار Roles. والصورة التالية تبين قائمة الحسابات بعد إنشاء صندوقين:

![قائمة الحسابات في لوحة Stalwart وفيها admin وalice وbob](https://arabroot.io/content/images/2026/10/stalwart-03-accounts.webp)

قائمة الحسابات في **Directory › Accounts**: المدير الذي أنشأه المعالج، والصندوقان `alice@example.com` و`bob@example.com`

ولاحظ أن اسم الدخول في Stalwart 0.16 هو العنوان الكامل دائماً، أي `alice@example.com` وليس `alice`، وفي برامج البريد يكفي غالباً العنوان وكلمة المرور، لأن Stalwart يرد على طلبات الإعداد التلقائي Autoconfiguration، وللإعداد اليدوي استخدم IMAP على `mail.example.com` بالمنفذ 993 مع SSL/TLS، وSMTP بالمنفذ 465 مع SSL/TLS. وللتطبيقات التي ترسل عبر SMTP مثل [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/) أنشئ صندوقاً مخصصاً مثل `noreply@example.com`، واجعل التطبيق يستخدم كلمة مرور تطبيق App Password ينشئها المستخدم من `/account`، والسبب أن تسريبها لا يكشف الحساب كله وتستطيع إلغاءها وحدها.

وإذا كان لديك بريد قائم على سيرفر آخر، فقد شرحنا في [دليل ترحيل البريد بين خادمي mailcow](https://arabroot.io/articles/%D8%AA%D8%B1%D8%AD%D9%8A%D9%84-%D8%A7%D9%84%D8%A8%D8%B1%D9%8A%D8%AF-%D8%A8%D9%8A%D9%86-%D8%AE%D8%A7%D8%AF%D9%85%D9%8A-mailcow/) فكرة النقل بـ imapsync دون توقف، ويقدم Stalwart أداته الخاصة [Vandelay](https://stalw.art/docs/migration/import-export/?ref=arabroot.io) التي تسحب الحساب من IMAP أو JMAP أو Exchange أو Google Takeout وتنقل معه التقويم وجهات الاتصال.

## سجلات DNS التي يولدها Stalwart لك

سجلات DNS هي التي تحدد هل تصل رسائلك أم تضيع، فمنها يقرأ السيرفر المستقبل Receiving Server سجلات SPF وDKIM وDMARC والاستعلام العكسي PTR، وقد شرحنا ما يفعله كل واحد منها في [شرح 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/). وفي الطريقة اليدوية تكتب هذه السجلات بنفسك وتنسخ مفتاح DKIM من ملف إلى لوحة DNS، أما Stalwart فيبني ملف المنطقة Zone File كاملاً من إعداد النطاق نفسه. افتح **Management › Domains › Domains**، ثم من قائمة النقاط الثلاث بجوار النطاق اختر **View Zone File**:

![ملف منطقة DNS الذي يولده Stalwart للنطاق example.com](https://arabroot.io/content/images/2026/10/stalwart-04-dns-zone.webp)

ملف المنطقة للنطاق `example.com`: مفتاحا DKIM وSPF وMX وDMARC وسجلات SRV وMTA-STS وTLS-RPT والإعداد التلقائي

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

```text
v1-ed25519-20261004._domainkey.example.com. IN TXT "v=DKIM1; k=ed25519; h=sha256; p=0Instn1qSGKZvePsvuCv6w+imtzCftifRmN9uqAFSTo="
v1-rsa-20261004._domainkey.example.com. IN TXT (
    "v=DKIM1; k=rsa; h=sha256; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlebb3EoG…"
    "…ZcktLQnuyZ1jVhZQIDAQAB"
)
mail.example.com. IN TXT "v=spf1 a -all"
example.com. IN TXT "v=spf1 mx -all"
example.com. IN MX 10 mail.example.com.
_dmarc.example.com. IN TXT "v=DMARC1; p=reject; rua=mailto:postmaster@example.com"
_caldavs._tcp.example.com. IN SRV 0 1 443 mail.example.com.
_carddavs._tcp.example.com. IN SRV 0 1 443 mail.example.com.
_imaps._tcp.example.com. IN SRV 0 1 993 mail.example.com.
_jmap._tcp.example.com. IN SRV 0 1 443 mail.example.com.
_pop3s._tcp.example.com. IN SRV 0 1 995 mail.example.com.
_submissions._tcp.example.com. IN SRV 0 1 465 mail.example.com.
mta-sts.example.com. IN CNAME mail.example.com.
_mta-sts.example.com. IN TXT "v=STSv1; id=17174664717463327589"
_smtp._tls.example.com. IN TXT "v=TLSRPTv1; rua=mailto:postmaster@example.com"
ua-auto-config.example.com. IN CNAME mail.example.com.
_ua-auto-config.example.com. IN TXT "v=UAAC1; a=sha256; d=4PelYnAaYOkI5V2VklhpKxnMk5ou0cd/AVpeYtRzj2w="
autoconfig.example.com. IN CNAME mail.example.com.
autodiscover.example.com. IN CNAME mail.example.com.
```

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

- **DKIM بمفتاحين:** يوقع Stalwart كل رسالة بتوقيعين، الأول بخوارزمية Ed25519 الحديثة والثاني بـ RSA، والسبب أن بعض السيرفرات المستقبلة لا تدعم Ed25519 بعد فتجد مفتاح RSA. انشر السجلين، وانسخ قيمة RSA كاملة من الملف عندك، ولا مشكلة أن تقسمها لوحة DNS إلى عدة سلاسل Strings بين علامات تنصيص ما دامت متتالية.
- **SPF بسجلين:** سجل للنطاق `example.com` يسمح للسيرفر المذكور في MX بالإرسال، وسجل للاسم `mail.example.com` نفسه، والسبب أن السيرفرات المستقبلة تفحص أيضاً الاسم الذي يقدمه سيرفرك في أمر EHLO. وإذا كنت ترسل باسم النطاق عبر خدمة أخرى مثل نشرة بريدية Newsletter فأضفها إلى سجل النطاق نفسه، مثل `v=spf1 mx include:amazonses.com -all`، ولا تنشئ سجل SPF ثانياً للنطاق، لأن وجود سجلين يجعل الفحص يفشل.
- **DMARC يبدأ بالرفض:** القيمة التي يولدها Stalwart هي `p=reject`، أي أن السيرفرات الأخرى سوف ترفض أي رسالة باسم نطاقك لا تجتاز الفحص، والأسلم أن تنشره أولاً بالقيمة `p=none` وتجمع التقارير على `postmaster@example.com` نحو أسبوعين، ثم تنتقل إلى `p=quarantine` ثم `p=reject`، والسبب أن خدمة نسيتها ترسل باسم نطاقك سوف تختفي رسائلها بصمت إذا بدأت بالرفض. وأنشئ عنوان `postmaster@example.com` اسماً بديلاً Alias لحسابك حتى تصلك التقارير.
- **MTA-STS وTLS-RPT:** يخبر [MTA-STS](https://datatracker.ietf.org/doc/html/rfc8461?ref=arabroot.io) السيرفرات الأخرى أن بريد نطاقك يجب أن يصل عبر TLS بشهادة صالحة، ويخدم Stalwart ملف السياسة Policy بنفسه، ولكن هذا يعني أن الاسم `mta-sts.example.com` يحتاج إلى شهادة صالحة على المنفذ 443، ويرسل لك سجل TLS-RPT تقارير يومية عن فشل TLS.
- **الإعداد التلقائي:** سجلات `autoconfig` و`autodiscover` لبرامج Thunderbird وOutlook، وسجلات SRV للبرامج التي تبحث عنها، وسجلا `ua-auto-config` للبروتوكول الجديد PACC الذي يعمل عليه IETF.
- **ما لا يكتبه Stalwart:** سجل A للاسم `mail.example.com` (وAAAA إذا كان لديك IPv6) تضيفه أنت كما فعلنا قبل التثبيت، وسجل PTR يضبط لدى مزود السيرفر كما سيأتي. وإذا كنت تستخدم Cloudflare فاجعل سجل `mail` على وضع DNS only دون ال Proxy، والسبب أن ال Proxy يمرر HTTP فقط ولا يمرر منافذ البريد.

بعد نشر السجلات تحقق منها من أي جهاز:

```bash
dig +short MX example.com
dig +short TXT example.com
dig +short TXT v1-ed25519-20261004._domainkey.example.com
dig +short TXT _dmarc.example.com
dig +short -x 203.0.113.10
```

### النشر التلقائي وتدوير مفاتيح DKIM

إذا كان مزود DNS لديك في قائمة [المزودين المدعومين](https://stalw.art/docs/domains/dns-records/?ref=arabroot.io)، فاختيار الإدارة التلقائية في المعالج أو في صفحة النطاق يجعل Stalwart ينشر هذه السجلات عند إنشاء النطاق ويحدثها بنفسه، وهذا مهم بشكل خاص لمفاتيح DKIM، لأن Stalwart يدعم [تدوير المفاتيح Key Rotation](https://stalw.art/docs/domains/dkim-rotation/?ref=arabroot.io) كل 90 يوماً افتراضياً، ولكن صفحة النطاق تنص على أن التدوير يحتاج إلى إدارة DNS تلقائية، والسبب منطقي: المفتاح الجديد يجب أن ينشر في DNS قبل أن يبدأ التوقيع به، ولا يستطيع السيرفر فعل ذلك في لوحة لا يصل إليها. ومع الإدارة اليدوية تبقى المفاتيح التي أنشأها المعالج كما هي، فإذا أنشأت مفتاحاً جديداً بنفسك لاحقاً من **Management › Domains › DKIM Signatures** فانشر سجله قبل أن تفعله.

### سجل PTR لدى مزود السيرفر

سجل PTR أو rDNS لا يضبط من لوحة DNS الخاصة بنطاقك، وإنما من لوحة مزود ال VPS باسم Reverse DNS، والسبب شرحناه في [شرح 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/). اضبطه على `mail.example.com` تماماً، وتأكد أن سجل A لهذا الاسم يعيد العنوان نفسه، وبدون هذا التطابق [ترفض Gmail](https://support.google.com/a/answer/81126?ref=arabroot.io) كثيراً من الرسائل أو تصنفها رسائل مزعجة، وإذا أضفت سجل AAAA فاضبط PTR لعنوان IPv6 أيضاً.

## شهادة TLS: ACME المدمج أم Reverse Proxy؟

### الشهادة المدمجة: الطريق الأبسط

إذا كان Stalwart وحده على السيرفر ويملك المنفذ 443، فالخيار الذي تركته مفعلاً في المعالج يكفي، حيث يطلب Stalwart الشهادة من Let's Encrypt ويجددها Renewal بنفسه ويستخدمها في SMTP وIMAP وHTTPS معاً. ويشرح [دليل Docker الرسمي](https://stalw.art/docs/install/platform/docker/?ref=arabroot.io) طريقة التحقق: مع الإدارة اليدوية لسجلات DNS يستخدم Stalwart التحقق عبر TLS-ALPN-01، أي أن Let's Encrypt تتصل مباشرة بسيرفرك على المنفذ 443، لذلك يجب أن يكون المنفذ مفتوحاً للإنترنت، وألا يعترضه Reverse Proxy أو Load Balancer، وأن يشير سجل A إلى السيرفر. أما مع مزود DNS تلقائي فيستخدم التحقق من ملكية النطاق عبر ال DNS (DNS Challenge) بطريقة DNS-01، ولا يحتاج إلى أي منفذ مفتوح. وتجد إعداد الشهادة لكل نطاق في صفحته تحت **Certificate Management**، ومزودي ACME في **Settings › TLS › ACME Providers**.

### كيف تشغل Stalwart خلف Reverse Proxy؟

إذا كان لديك على السيرفر نفسه Reverse Proxy مثل [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/) يملك المنفذين 80 و443 لتطبيقات أخرى، فالقاعدة الأولى أن ال Reverse Proxy يخدم HTTP فقط، أي لوحة الإدارة وJMAP وautoconfig وMTA-STS، أما منافذ البريد 25 و465 و993 فتبقى منشورة مباشرة من Container الخاص بـ Stalwart.

لنأخذ مثالاً مع Nginx Proxy Manager على الشبكة `proxy` التي أنشأناها في دليله، حيث يصل ال Proxy إلى Stalwart باسمه داخل شبكة 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/). فيصبح ملف Compose كما يلي، ولاحظ أن المنفذين 443 و8080 لم يعودا منشورين على السيرفر:

```yaml
services:
  stalwart:
    image: stalwartlabs/stalwart:v0.16.24
    container_name: stalwart
    restart: unless-stopped
    hostname: mail.example.com
    environment:
      STALWART_PUBLIC_URL: https://mail.example.com
    ports:
      - "25:25"
      - "465:465"
      - "993:993"
    volumes:
      - stalwart_etc:/etc/stalwart
      - stalwart_data:/var/lib/stalwart
    networks:
      - proxy

volumes:
  stalwart_etc:
    name: stalwart_etc
  stalwart_data:
    name: stalwart_data

networks:
  proxy:
    external: true
```

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

- في NPM أنشئ Proxy Host للأسماء `mail.example.com` و`autoconfig.example.com` و`autodiscover.example.com` و`mta-sts.example.com` يوجه الطلبات إلى `http://stalwart:8080`، ثم فعل Websockets Support وForce SSL وشهادة Let's Encrypt، وهذا هو نمط HTTP Upstream الذي [يوصي به التوثيق](https://stalw.art/docs/server/reverse-proxy/?ref=arabroot.io) لبساطته.
- المتغير `STALWART_PUBLIC_URL` يخبر Stalwart بالعنوان الذي يراه المستخدمون، لأنه يكتبه في مستندات الاكتشاف Discovery Documents الخاصة بـ OAuth وJMAP، وإذا لم يطابق عنوان ال Proxy فسوف تجد صفحة الدخول تدور في حلقة. وقيمته هنا تطابق القيمة الافتراضية `https://mail.example.com`، ولكننا نكتبه صراحة لأنك سوف تحتاج إلى تغييره إذا نشرت ال Proxy على منفذ آخر غير 443 أو تحت مسار فرعي.
- يرى Stalwart كل الطلبات قادمة من عنوان ال Proxy، ولأن [الحظر التلقائي Auto-ban](https://stalw.art/docs/server/auto-ban/?ref=arabroot.io) يحسب محاولات الدخول الفاشلة لكل عنوان، فقد يحظر ال Proxy نفسه ويغلق اللوحة على الجميع. لذلك فعل الحقل `useXForwarded` في **Settings › Network › HTTP** حتى يقرأ العنوان الحقيقي من الترويسة X-Forwarded-For، وأضف شبكة Docker الخاصة بال Proxy إلى الشبكات الموثوقة Trusted Networks كما يشرح [التوثيق](https://stalw.art/docs/server/reverse-proxy/?ref=arabroot.io).
- أكمل المعالج قبل أن تضع ال Proxy في الطريق، و[التوثيق نفسه ينصح](https://stalw.art/docs/server/reverse-proxy/?ref=arabroot.io) بالوصول إلى `http://<host>:8080/admin` مباشرة أثناء المعالج وأول دخول، ثم إعادة ال Proxy بعد ذلك.

وتبقى مسألة الشهادة على منافذ البريد، فـ SMTP وIMAP يحتاجان إلى شهادة صالحة للاسم `mail.example.com`، ولكن ال Proxy أصبح يملك المنفذ 443، فلا تستطيع Let's Encrypt الوصول إلى Stalwart بطريقة TLS-ALPN-01\. والحل الأنسب أن يصدر Stalwart شهادته عبر DNS-01 مع مزود DNS تلقائي، فلا يحتاج إلى أي منفذ، والبديل الذي يعرضه [دليل Traefik الرسمي](https://stalw.art/docs/server/reverse-proxy/traefik/?ref=arabroot.io) أن يقرأ Stalwart ملفات الشهادة التي يصدرها Traefik من Volume مشترك عبر كائن Certificate في **Settings › TLS › Certificates**.

⚠️

لا تمرر منافذ البريد 25 و465 و993 عبر Proxy Host من نوع HTTP إطلاقاً، فهي بروتوكولات TCP وليست HTTP. وإذا احتجت لسبب ما أن تمر عبر Traefik أو HAProxy في وضع TCP، فيجب أن يرسل ال Proxy العنوان الحقيقي للمرسل عبر Proxy Protocol كما في أمثلة التوثيق، والسبب أن فحص SPF وDMARC يعتمد على عنوان IP المرسل، وبدونه سوف يفحص Stalwart عنوان ال Proxy نفسه وتصبح النتائج بلا معنى.

## المنفذ 25: تأكد منه قبل أن تبحث في الإعداد

أكثر سبب يضيع فيه وقت من يبني خادم بريد لأول مرة هو أن يقضي ساعات في مراجعة الإعداد، والمشكلة أن المزود يحجب المنفذ 25 الصادر من الأساس، فمثلاً [تحجب Hetzner](https://docs.hetzner.com/cloud/servers/faq/?ref=arabroot.io) المنفذين 25 و465 على سيرفرات Cloud حتى تطلب فتحهما، و[تحجب DigitalOcean](https://docs.digitalocean.com/support/why-is-smtp-blocked/?ref=arabroot.io) منافذ SMTP، و[تقيد AWS](https://repost.aws/knowledge-center/ec2-port-25-throttle?ref=arabroot.io) المنفذ 25 على EC2\. لذلك نفذ هذا الأمر من السيرفر نفسه قبل أي شيء، فإذا انتهت المهلة دون اتصال فالمزود يحجبه:

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

ومن جهاز آخر تأكد أن المنفذ 25 الداخل يصل إلى Stalwart:

```bash
nc -v mail.example.com 25
```

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

```text
220 mail.example.com Stalwart ESMTP at your service
```

وإذا رفض المزود فتح المنفذ الصادر، فأرسل عبر خادم وسيط Relay مثل Amazon SES، ويدعم Stalwart ذلك من خلال [مسارات التوجيه Routes](https://stalw.art/docs/mta/outbound/routing/?ref=arabroot.io) من النوع Relay في **Settings › MTA › Outbound › Routes**، وعندها أضف الوسيط إلى سجل SPF وانشر سجلات DKIM التي يطلبها.

## فلتر الرسائل المزعجة المدمج Spam Filter

في mailcow يقوم بهذا الدور Rspamd في Container مستقل، أما Stalwart فيحمل [فلتره داخل البرنامج](https://stalw.art/docs/spamfilter/?ref=arabroot.io)، ومعظم قواعده Rules منقولة من Rspamd مع بعضها من SpamAssassin، ومعه مصنف إحصائي Statistical Classifier يتعلم تلقائياً، وقوائم الحظر DNSBL، وPyzor، والحماية من التصيد Phishing. وطريقة عمله أن كل فحص يضيف وسماً Tag له درجة Score موجبة أو سالبة، فإذا تجاوز المجموع 5.0 (القيمة الافتراضية) صنفت الرسالة رسالة مزعجة، ولاحظ أن الفلتر لا يرفض أي رسالة افتراضياً بسبب درجتها، وإنما يضيف الترويستين `X-Spam-Status` و`X-Spam-Result` وينقل الرسالة إلى مجلد Junk Mail.

والآن لنكسر الأمر لنفهمه، فنرسل من سيرفر خارجي دون مصادقة Authentication رسالة فيها نص الاختبار [GTUBE](https://spamassassin.apache.org/gtube/?ref=arabroot.io) المعروف:

```bash
swaks --server mail.example.com --port 25 --ehlo client.example.net \
  --from someone@example.net --to bob@example.com \
  --header 'Subject: spam test' \
  --body 'XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X'
```

يقبل السيرفر الرسالة بالرد `250 2.0.0 Message queued`، ولكنها لا تصل إلى صندوق الوارد Inbox، وإنما إلى مجلد Junk Mail، وفي ترويستها ما يشبه ما يلي:

```text
X-Spam-Status: Yes
Authentication-Results: mail.example.com;
	spf=none (mail.example.com: no SPF records found for someone@example.net) smtp.mailfrom=someone@example.net;
	dmarc=none header.from=example.net policy.dmarc=none
X-Spam-Result: …
	RCVD_NO_TLS_LAST (0.10),
	HELO_NORES_A_OR_MX (0.30),
	AUTH_NA (1.00),
	DMARC_NA (1.00),
	HELO_IPREV_MISMATCH (1.00),
	DIRECT_TO_MX (2.00),
	PYZOR (3.50)
X-Spam-Score: spam, score=9.50
```

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

- كل سطر في `X-Spam-Result` فحص مستقل ودرجته، وهنا جمعت الرسالة 9.50، أي ضعف الحد تقريباً، وأكبر جزء منها من Pyzor الذي عرف نص الاختبار في قاعدة بصماته المشتركة.
- الترويسة `Authentication-Results` هي نفس ما سوف تراه في Gmail عندما تفحص رسائلك أنت، فإذا ظهر فيها `spf=fail` أو `dkim=fail` لرسالة من نطاقك فالمشكلة في سجلاتك وليست في الفلتر.
- الحد والدرجات تغيرها من **Settings › Spam Filter**، فإذا أردت رفض الرسائل التي تتجاوز درجة معينة بدل نقلها إلى Junk Mail، فهناك حدان مستقلان للرفض Reject والحذف Discard.

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

أول اختبار أن ترسل من صندوق إلى آخر عبر منفذ الإرسال 465 بأداة [swaks](https://www.jetmore.org/john/code/swaks/?ref=arabroot.io) (تثبتها بالأمر `sudo apt install swaks`)، وهذا الاختبار يمر بالمصادقة والتوقيع والتسليم المحلي معاً:

```bash
swaks --server mail.example.com --port 465 --tls-on-connect \
  --auth PLAIN --auth-user alice@example.com --auth-password 'ALICE_PASSWORD' \
  --from alice@example.com --to bob@example.com \
  --header 'Subject: Hello from Stalwart' --body 'First test message.'
```

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

```text
<~  220 mail.example.com Stalwart ESMTP at your service
<~  250-mail.example.com you had me at EHLO
<~  250-SMTPUTF8
<~  250-SIZE 104857600
<~  250-REQUIRETLS
<~  250-PIPELINING
<~  250-NO-SOLICITING
<~  250-ENHANCEDSTATUSCODES
<~  250-CHUNKING
<~  250-BINARYMIME
<~  250-AUTH PLAIN LOGIN XOAUTH2 OAUTHBEARER
<~  250 8BITMIME
<~  235 2.7.0 Authentication succeeded.
<~  250 2.1.0 OK
<~  250 2.1.5 OK
<~  354 Start mail input; end with <CRLF>.<CRLF>
<~  250 2.0.0 Message queued with id 49fa5820c800000.
<~  221 2.0.0 Bye.
```

ثم اقرأ صندوق `bob` عبر IMAPS، ويكفي لذلك `curl` دون برنامج بريد:

```bash
curl --user 'bob@example.com:BOB_PASSWORD' imaps://mail.example.com/INBOX -X 'STATUS INBOX (MESSAGES UNSEEN)'
curl --user 'bob@example.com:BOB_PASSWORD' 'imaps://mail.example.com/INBOX;UID=1'
```

والمخرج سوف يكون كما يلي، مع اختصار قيم التوقيع:

```text
* STATUS "INBOX" (MESSAGES 1 UNSEEN 1)
Delivered-To: bob@example.com
X-Spam-Status: No
DKIM-Signature: v=1; a=ed25519-sha256; s=v1-ed25519-20261004; d=example.com; c=relaxed/relaxed; r=y;
	h=Message-Id:Subject:From:To:Date; t=1791146346; bh=yTj4jPdXqVNiOvyezvK+ypy…
DKIM-Signature: v=1; a=rsa-sha256; s=v1-rsa-20261004; d=example.com; c=relaxed/relaxed; r=y;
	h=Message-Id:Subject:From:To:Date; t=1791146346; bh=yTj4jPdXqVNiOvyezvK+ypy…
Date: Sun, 04 Oct 2026 20:39:05 +0000
To: bob@example.com
From: alice@example.com
Subject: Hello from Stalwart

First test message.
```

لاحظ التوقيعين بالمحددين Selectors `v1-ed25519-20261004` و`v1-rsa-20261004`، وهما نفس أسماء سجلات DKIM في ملف المنطقة، فإذا اختلفا فالسجل الذي نشرته لن يجده أحد. وبعد ذلك أكمل بهذه الفحوص:

- أرسل رسالة إلى حساب Gmail ثم افتح **Show original**، وتأكد أن نتيجة SPF وDKIM وDMARC هي `PASS`، وللتقييم الكامل أرسل رسالة إلى [mail-tester.com](https://www.mail-tester.com/?ref=arabroot.io).

أرسل من حساب خارجي إلى `alice@example.com`، وعند أي مشكلة راجع السجل:

```bash
docker logs --tail 100 stalwart
```

الشهادة من Let's Encrypt وليست الشهادة المؤقتة، على HTTPS وعلى منفذ الإرسال:

```bash
echo | openssl s_client -connect mail.example.com:443 -servername mail.example.com 2>/dev/null | openssl x509 -noout -issuer -dates
echo | openssl s_client -connect mail.example.com:465 2>/dev/null | openssl x509 -noout -issuer
```

وإذا ظهر `CN=rcgen self signed cert` فما زالت الشهادة المؤقتة هي المستخدمة.

السيرفر ليس مفتوحاً للترحيل Open Relay، فنفذ من جهاز خارجي محاولة إرسال إلى نطاق آخر دون مصادقة:

```bash
swaks --server mail.example.com --port 25 --ehlo client.example.net \
  --from someone@example.net --to user@gmail.com --quit-after RCPT
```

والرد الصحيح هو `550 5.1.2 Relay not allowed.`، ولا تكرر هذه المحاولة كثيراً، لأن الحظر التلقائي يحظر العنوان بعد 35 محاولة ترحيل في اليوم افتراضياً.

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

مع RocksDB كل شيء في مجلدين: `/etc/stalwart` وفيه `config.json`، و`/var/lib/stalwart` وفيه قاعدة البيانات بكل الرسائل والحسابات والإعدادات ومفاتيح DKIM، و[التوثيق](https://stalw.art/docs/faq/?ref=arabroot.io) ينص على أن نسخ هذا المجلد يكفي لنسخة كاملة. ولكن RocksDB قاعدة مدمجة تكتب ملفاتها باستمرار، والنسخ والسيرفر يعمل قد يعطيك نسخة غير متسقة، لذلك فالطريقة الآمنة التي يستخدمها [دليل الترقية الرسمي](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING/v0%5F16.md?ref=arabroot.io) نفسه أن توقف ال Container ثم تنسخ ثم تشغله، وهذا يستغرق ثوان، والسيرفرات المرسلة تعيد المحاولة تلقائياً إذا وجدت المنفذ 25 مغلقاً لحظتها:

```bash
sudo mkdir -p /opt/backup/stalwart
cd /opt/stalwart
docker compose stop stalwart
docker run --rm \
  -v stalwart_etc:/etc/stalwart:ro \
  -v stalwart_data:/var/lib/stalwart:ro \
  -v /opt/backup/stalwart:/backup \
  ubuntu:24.04 tar czf /backup/stalwart-$(date +%F).tar.gz /etc/stalwart /var/lib/stalwart
docker compose start stalwart
```

ال Container المؤقت يربط ال Volumes بوضع القراءة فقط `ro` ويضغطهما في ملف واحد باسم التاريخ، ثم يحذف نفسه. وللجدولة Scheduling اليومية ضع الأوامر في سكربت ثم أضفه إلى `crontab` في وقت هادئ مثل الثانية فجراً، ثم انقل الملفات إلى تخزين خارجي Offsite Storage بأداة مثل [restic](https://restic.net/?ref=arabroot.io) أو [rclone](https://rclone.org/?ref=arabroot.io)، والسبب أن النسخة على قرص السيرفر نفسه لا تحميك إذا تعطل السيرفر. واحفظ معها ملف `compose.yaml`.

وللاستعادة على سيرفر جديد ثبت Docker وانسخ `compose.yaml` وملف النسخة، ثم أنشئ ال Volumes فارغة دون تشغيل، وفك النسخة فيها، ثم شغل:

```bash
cd /opt/stalwart
docker compose up --no-start
docker run --rm \
  -v stalwart_etc:/etc/stalwart \
  -v stalwart_data:/var/lib/stalwart \
  -v /opt/backup/stalwart:/backup \
  ubuntu:24.04 tar xzpf /backup/stalwart-2026-10-04.tar.gz -C /
docker compose start stalwart
```

الخيار `p` في `tar` يحفظ الملكية للمستخدم 2000 كما كانت، وعند التشغيل لا يدخل Stalwart في وضع التهيئة لأنه يجد `config.json`، وتعود الحسابات والرسائل كما كانت. ولا تخلط هذا بالخيارين `--export` و`--import` في البرنامج، فهما [لترحيل البيانات بين خلفيات التخزين](https://stalw.art/docs/management/maintenance/migration/?ref=arabroot.io)، والتوثيق ينص صراحة على أنهما ليسا بديلاً عن النسخ الاحتياطي.

🛑

لا تفك النسخة فوق Volume فيه بيانات حالية، والسبب أن RocksDB تحفظ بياناتها في ملفات كثيرة، وفك النسخة فوقها يترك ملفات من الحالة الجديدة بجوار ملفات النسخة فتفسد القاعدة. استعد دائماً إلى Volumes فارغة، وإذا كانت على نفس السيرفر فاحذفها أولاً بالأمر `docker compose down -v` بعد أن تتأكد أن ملف النسخة سليم، واختبر الاستعادة دورياً على سيرفر مؤقت حتى تعرف أن نسخك صالحة فعلاً.

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

يتبع Stalwart [الترقيم الدلالي Semantic Versioning](https://stalw.art/docs/install/upgrade/?ref=arabroot.io)، فالإصدار التصحيحي (الرقم الأخير، مثل الانتقال من 0.16.23 إلى 0.16.24) يحمل إصلاحات متوافقة فقط، والإصدار الثانوي (الرقم الأوسط، مثل 0.17) قد يحتاج إلى تغيير في الإعداد أو ترحيل للبيانات، وقبل 1.0 قد يحمل تغييرات غير متوافقة كما حدث في 0.16\. لذلك فالتحديث التصحيحي بسيط: خذ نسخة احتياطية، ثم غير الوسم في `compose.yaml` إلى الإصدار الجديد من [صفحة الإصدارات](https://github.com/stalwartlabs/stalwart/releases?ref=arabroot.io)، ثم:

```bash
cd /opt/stalwart
docker compose pull
docker compose up -d
docker logs --tail 30 stalwart
```

وتأكد في السجل من السطر `Starting Stalwart Server` ورقم الإصدار الجديد، ثم احذف ال Image القديم بوسمه، مثل `docker image rm stalwartlabs/stalwart:v0.16.23`، والسبب أن `docker image prune` وحده لا يحذف Image ما زال يحمل وسماً. أما الانتقال إلى إصدار ثانوي جديد فلا تفعله قبل أن تقرأ ملاحظات الإصدار وملف الترقية الخاص به في [المجلد UPGRADING](https://github.com/stalwartlabs/stalwart/tree/main/UPGRADING?ref=arabroot.io)، وجربه أولاً على نسخة من بياناتك في سيرفر مؤقت. ولاحظ أن واجهة الإدارة تتحدث وحدها من GitHub بشكل مستقل عن البرنامج، فقد ترى تغييراً في شكلها دون أن تغير الوسم.

📌

في يونيو 2019 أصدر مشروع Exim إصلاحاً للثغرة [CVE-2019-10149](https://www.exim.org/static/doc/security/CVE-2019-10149.txt?ref=arabroot.io) في الإصدارات من 4.87 إلى 4.91، وهي ثغرة تسمح لمهاجم دون أي مصادقة بأن يرسل رسالة مصاغة بعناية إلى المنفذ 25 فينفذ أوامر بصلاحيات root على السيرفر. وفي مايو 2020 [نشرت NSA تحذيراً](https://www.cisa.gov/news-events/alerts/2020/05/28/nsa-releases-advisory-sandworm-actors-exploiting-exim-vulnerability?ref=arabroot.io) من أن مجموعة Sandworm الروسية تستغلها في سيرفرات Exim التي لم تحدث منذ أغسطس 2019 على الأقل، أي بعد شهرين فقط من صدور الإصلاح. ولاحظ أن الثغرة لم تكن خطأ في إدارة الذاكرة، وإنما تحققاً ناقصاً من عنوان المستلم، وهذا النوع من الأخطاء لا تمنعه لغة Rust ولا غيرها، والدرس أن المنفذ 25 مفتوح للعالم كله دون كلمة مرور، لذلك تابع إصدارات Stalwart الأمنية وطبق الإصدارات التصحيحية دون تأجيل.

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

### الصفحة /admin تعطي 404 Not Found

واجهة الإدارة ليست داخل ال Docker Image، وإنما ينزلها Stalwart من GitHub عند التشغيل الأول، فإذا كان الاتصال الصادر بـ `github.com` و`objects.githubusercontent.com` ممنوعاً فلن يجد ما يعرضه، ويبقى باقي السيرفر يعمل بشكل طبيعي. والحل أن تسمح بالاتصال الصادر عبر HTTPS ثم تعيد التشغيل، وفي البيئات المغلقة يمكنك أن تضع الحزمة على سيرفر داخلي وتغير عنوانها كما يشرح [توثيق الواجهة](https://stalw.art/docs/management/webui/?ref=arabroot.io).

### ضاعت كلمة المرور المؤقتة أو حساب المدير

كلمة مرور وضع التهيئة تظهر مرة واحدة، فإذا ضاعت قبل أن تكمل المعالج فأسهل حل أن تبدأ من جديد بالأمر `docker compose down -v` ثم `docker compose up -d`، لأنه لا توجد بيانات بعد. أما إذا فقدت الدخول بعد الإعداد فشغل Stalwart في [وضع الاسترداد Recovery Mode](https://stalw.art/docs/install/platform/docker/?ref=arabroot.io) بإضافة المتغيرين `STALWART_RECOVERY_MODE: "1"` و`STALWART_RECOVERY_ADMIN: admin:كلمة-مرور-مؤقتة` إلى `environment`، وأعد السطر `"127.0.0.1:8080:8080"` إلى قائمة `ports`، فيفتح Stalwart المستمع 8080 ويقبل هذا الحساب، وبعد أن تصلح الحساب احذف المتغيرين والسطر وأعد التشغيل.

### المتصفح وبرامج البريد تحذر من الشهادة

التحذير يعني أن Stalwart ما زال يقدم الشهادة المؤقتة، فراجع `docker logs stalwart` وابحث عن أخطاء ACME، والأسباب المعتادة: سجل A لا يشير إلى السيرفر، أو المنفذ 443 مغلق في جدار الحماية لدى المزود، أو Reverse Proxy يعترض الاتصال فيفشل التحقق بطريقة TLS-ALPN-01، وفي هذه الحالة انتقل إلى DNS-01 كما شرحنا في قسم ال Reverse Proxy.

### الرد 550 5.5.0 Invalid EHLO domain

يرفض Stalwart الاتصال على المنفذ 25 إذا قدم الطرف الآخر في أمر EHLO اسماً غير صالح، مثل اسم Container قصير أو كلمة دون نطاق، وهذا فحص مقصود لأن السيرفرات الحقيقية تقدم اسماً كاملاً FQDN. فإذا ظهر لك هذا الخطأ وأنت تختبر من سكربت أو تطبيق، فمرر اسماً كاملاً مثل `--ehlo client.example.net` في swaks، أو اضبط اسم المضيف Hostname في التطبيق المرسل، وإذا كان التطبيق داخلياً فالأفضل أن يرسل عبر المنفذ 465 بمصادقة.

### التحذير DANE has been disabled في السجل

ستجد في السجل عند التشغيل سطراً مثل:

```text
WARN Configuration build warning (registry.build-warning) source = "DnsResolver", reason = "The configured DNS resolver cannot validate DNSSEC. DANE has been disabled to avoid deferring mail. Ensure the resolver is DNSSEC-capable and reachable over TCP."
```

والمعنى أن خادم DNS الذي يستخدمه السيرفر لا يتحقق من DNSSEC، فعطل Stalwart التحقق عبر DANE حتى لا يؤخر الرسائل، والبريد يعمل بشكل طبيعي. وإذا أردت DANE فاجعل السيرفر يستخدم خادم DNS يتحقق من DNSSEC ويقبل الاستعلامات عبر TCP، ثم أعد التشغيل.

### لا يستطيع أحد الدخول خلف ال Reverse Proxy

إذا كانت اللوحة تعمل ثم توقفت فجأة لكل المستخدمين، فغالب الظن أن الحظر التلقائي حظر عنوان ال Proxy نفسه بعد عدة محاولات دخول فاشلة، لأن Stalwart يرى كل الطلبات قادمة منه. افتح **Settings › Security › Blocked IPs** من داخل الشبكة واحذف العنوان، ثم فعل قراءة العنوان الحقيقي كما في قسم ال Reverse Proxy حتى لا يتكرر ذلك. وإذا كانت صفحة الدخول تدور في حلقة دون رسالة خطأ فالسبب غالباً أن `STALWART_PUBLIC_URL` لا يطابق العنوان الذي يفتحه المستخدم.

### رسائلك تصل إلى الرسائل المزعجة لدى الآخرين

- **PTR غير مطابق:** تأكد أن `dig +short -x 203.0.113.10` يعيد `mail.example.com`، وأن سجل A لهذا الاسم يعيد العنوان نفسه.
- **فشل DKIM:** قارن المحدد في ترويسة `DKIM-Signature` بالسجل المنشور، فالسبب الأشهر مفتاح RSA نسخ ناقصاً أو بمسافات زائدة.
- **عنوان IP في قوائم الحظر:** افحصه لدى [Spamhaus](https://www.spamhaus.org/?ref=arabroot.io) و[MXToolbox](https://mxtoolbox.com/blacklists.aspx?ref=arabroot.io)، فبعض المزودين يعطونك عنواناً يحمل سمعة سيئة من مستخدم سابق.
- **سمعة Reputation جديدة:** السيرفرات الأخرى تتعامل بحذر مع سيرفر ليس له تاريخ إرسال Sending History، لذلك ابدأ بحجم صغير، ولا ترسل الحملات التسويقية من خادم البريد الأساسي.

## الخلاصة

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

- Stalwart خادم بريد كامل في برنامج واحد، يكفيه 1 GB من الذاكرة لفريق صغير بدل 6 GiB في mailcow، ولكنه لا يتضمن بريداً عبر الويب، وما زال في 0.x وقد تحتاج إصداراته الثانوية إلى ترحيل، فثبت الوسم واقرأ ملاحظات كل إصدار.
- ثبته بـ Docker Compose مع Volume للإعداد وآخر للبيانات، واربط المنفذ 8080 بـ `127.0.0.1`، واقرأ كلمة المرور المؤقتة من السجل، ثم احفظ حساب المدير الدائم من الشاشة الأخيرة في المعالج.
- انشر السجلات من ملف المنطقة الذي يولده Stalwart، وابدأ DMARC بالقيمة `p=none` بدل `p=reject`، واضبط PTR لدى المزود، وتأكد من المنفذ 25 قبل أي شيء آخر.
- خلف Reverse Proxy مرر HTTP فقط، واترك 25 و465 و993 مباشرة، واضبط `STALWART_PUBLIC_URL` والعنوان الحقيقي للمستخدمين، واستخدم DNS-01 للشهادة.
- انسخ المجلدين والسيرفر متوقف إلى تخزين خارجي يومياً، واستعد دائماً إلى Volumes فارغة، وطبق الإصدارات التصحيحية دون تأجيل.

ولتختار بين mailcow وStalwart وPostfix مع Dovecot اقرأ [مقارنة خوادم البريد](https://arabroot.io/articles/%D9%85%D9%82%D8%A7%D8%B1%D9%86%D8%A9-mailcow-%D9%88-stalwart-%D9%88-postfix/)، وفيها نقاط القوة ونقاط الضعف في كل منها حتى تختار ما يناسب فريقك.

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

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