في هذا الدليل سوف نثبت mailcow على سيرفر واحد، وهو حزمة جاهزة من عدة مكونات Components تعمل كلها في Docker Containers، حيث يرسل Postfix البريد ويستقبله، ويدير Dovecot صناديق البريد Mailboxes عبر IMAP وPOP3، ويكافح Rspamd الرسائل المزعجة Spam ويوقع Signs الرسائل بـ DKIM، ويفحص ClamAV المرفقات Attachments، ويقدم SOGo البريد عبر الويب Webmail مع التقويم Calendar وجهات الاتصال Contacts، وتتحكم في ذلك كله لوحة إدارة Admin Panel واحدة، ومعها سكربتات Scripts رسمية للتثبيت Installation والتحديث Update والنسخ الاحتياطي Backup. ويناسب mailcow الشركات الصغيرة والمتوسطة، والجهات التي تريد أن يبقى بريدها على سيرفراتها، ومن يدير عدة نطاقات Domains من لوحة واحدة، أما إذا كان كل ما تحتاجه إرسال رسائل آلية Transactional Emails من تطبيقاتك، فخدمة إرسال مثل Amazon SES أو خادم SMTP وسيط SMTP Relay أبسط بكثير.
وإذا لم تقرر بعد هل تستضيف بريد مؤسستك بنفسك، وما الذي تتحمله في المقابل من سمعة Reputation ومتابعة، فابدأ بـ دليل استضافة البريد الإلكتروني للمؤسسات، فهو يشرح الصورة الكاملة من القرار إلى خطة النقل، ثم عد إلى هذا الدليل للتثبيت.
وسوف نناقش في هذا المقال ما يلي:
- متطلبات السيرفر والمنافذ واسم السيرفر، ولماذا يحدد مزود الاستضافة نجاح خادم البريد قبل أن تبدأ.
- سجلات DNS المطلوبة: A وMX وSPF وDKIM وDMARC وPTR، والسجلات الاختيارية مثل MTA-STS وTLS-RPT.
- تثبيت mailcow بالسكربت
generate_config.sh، ثم إضافة النطاق وصناديق البريد ومفتاح DKIM. - تشغيل mailcow خلف Reverse Proxy، والتحقق من النجاح، والنسخ الاحتياطي، والتحديث.
- أشهر مشكلات وصول الرسائل Deliverability وحلولها.
ما تحتاجه قبل أن تبدأ Requirements
السيرفر
- الذاكرة RAM: يحتاج الإعداد الافتراضي Default Configuration إلى 6 GiB من الذاكرة على الأقل مع 1 GiB من swap، وإلى 8 GiB لفريق من 5 إلى 10 مستخدمين، وأكثر المكونات استهلاكاً للذاكرة ClamAV ومحرك البحث النصي FTS، ويمكنك إيقافهما في السيرفرات الصغيرة.
- المعالج CPU والقرص Disk: معالج x86_64 أو ARM64، و20 GiB للنظام وال Containers دون حساب الرسائل نفسها، ثم احسب مساحة البريد من عدد الصناديق وحصة Quota كل صندوق.
- نوع الأجهزة الافتراضية Virtualization: يعمل mailcow على المنصات التي تقدم جهازاً افتراضياً كاملاً مثل KVM وESX وHyper-V، أما OpenVZ وVirtuozzo وLXC وأجهزة NAS مثل Synology وQNAP فلا يدعمها، لذلك اسأل المزود عن نوع الأجهزة الافتراضية إذا كان سعر الخطة رخيصاً بشكل لافت.
- النظام: توزيعة Linux Distribution حديثة مثل Debian أو Ubuntu LTS، مع Docker Engine 24 أو أحدث وإضافة Plugin Docker Compose، وإذا لم يكن Docker مثبتاً فاتبع دليل تثبيت Docker على Ubuntu. وتحتاج أيضاً إلى
gitوopensslوcurlوjq(صار مطلوباً منذ إصدار 2025-09)، وإلى مزامنة الوقت NTP مفعلة، فتأكد بالأمرtimedatectlأن السطرين NTP service وSystem clock synchronized قيمتهما active وyes. - عنوان IP ثابت Static IP ونظيف: سيرفر افتراضي VPS بعنوان IPv4 ثابت غير مدرج في قوائم الحظر Blocklists، ويجب أن يسمح المزود بالاتصال الصادر Outbound Connection على المنفذ 25 وأن يتيح لك ضبط سجل PTR. وكثير من المزودين يحجبون المنفذ 25 افتراضياً، فمثلاً تحجب Hetzner المنفذين 25 و465 على كل سيرفرات Cloud ولا تفتحهما إلا بطلب بعد شهر من التسجيل ودفع أول فاتورة، وتحجب DigitalOcean منافذ SMTP على كل Droplets، وتقيد AWS المنفذ 25 على EC2 حتى تقدم طلباً لرفع القيد. لذلك تحقق من ذلك قبل الشراء، وراجع دليل اختيار خادم VPS. أما خادم بريد على اتصال الإنترنت المنزلي Residential Connection فهو غير عملي في الغالب، والسبب أن عناوين IP المنزلية مدرجة عادة في قوائم الحظر، وسجل PTR بيد مزود خدمة الإنترنت ISP وليس بيدك.
- سيرفر مخصص Dedicated Server للبريد إن أمكن: يستخدم mailcow المنفذين 80 و443 وعدة منافذ للبريد، ويعمل أفضل عندما ينفرد بها، ويمكن تشغيله مع تطبيقات ويب أخرى خلف Reverse Proxy كما سيأتي في قسم مستقل.
المنافذ
يسرد دليل المتطلبات الرسمي المنافذ التالية:
| المنفذ | الخدمة | الاستخدام |
|---|---|---|
| 25/tcp | SMTP | استقبال البريد من السيرفرات الأخرى وإرساله إليها |
| 465/tcp | SMTPS | إرسال البريد من برامج المستخدمين Mail Clients عبر TLS مباشر |
| 587/tcp | Submission | إرسال البريد من برامج المستخدمين عبر STARTTLS |
| 143/tcp و993/tcp | IMAP وIMAPS | قراءة البريد من البرامج والهواتف |
| 110/tcp و995/tcp | POP3 وPOP3S | قراءة البريد بطريقة POP3 (اختياري) |
| 4190/tcp | ManageSieve | إدارة قواعد الفرز Filtering Rules من برامج البريد |
| 80/tcp و443/tcp | HTTP وHTTPS | لوحة الإدارة وSOGo وActiveSync وautodiscover والتحقق عبر HTTP (HTTP Challenge) لشهادة Let's Encrypt |
افتح هذه المنافذ في جدار الحماية Firewall، وفي لوحة المزود أيضاً إذا كان فيها جدار حماية خارجي، والأمر التالي يفتحها مع ufw:
sudo ufw allow 22,25,80,443,110,143,465,587,993,995,4190/tcpثم تأكد أنه لا توجد خدمة أخرى على السيرفر تستخدم هذه المنافذ، مثل Postfix أو Exim اللذين يأتيان أحياناً مع النظام:
sudo ss -tlpn | grep -E ':(25|80|110|143|443|465|587|993|995|4190)\s'اسم السيرفر Hostname والنطاق
هنا اسمان مختلفان يخلط بينهما كثيرون، فالأول هو اسم خادم البريد (FQDN) مثل mail.example.com، وبه يعرف السيرفر نفسه أمام السيرفرات الأخرى وله تصدر الشهادة Certificate، والثاني هو نطاق البريد مثل example.com، وهو ما يظهر بعد @ في العناوين، ولاحظ أن سيرفراً واحداً باسم mail.example.com يستطيع أن يخدم عدة نطاقات. ابدأ بضبط اسم السيرفر في النظام:
sudo hostnamectl set-hostname mail.example.com
hostname -fسجلات DNS
سجلات DNS هي التي تحدد هل تصل رسائلك أم تضيع، فمنها يقرأ السيرفر المستقبل SPF وDKIM وDMARC والاستعلام العكسي PTR، وقد شرحنا ما يفعله كل واحد منها ولماذا يوجد في شرح SPF وDKIM وDMARC للمبتدئين، وأنواع السجلات نفسها في شرح DNS وسجلاته للمبتدئين. والآن سوف نضيف السجلات التالية في لوحة DNS الخاصة بنطاقك، وضع عنوان سيرفرك مكان 203.0.113.10:
| الاسم | النوع | القيمة | الغرض |
|---|---|---|---|
mail.example.com | A | 203.0.113.10 | عنوان خادم البريد (أضف سجل AAAA إذا كان IPv6 مضبوطاً لديك) |
example.com | MX | 10 mail.example.com | يخبر السيرفرات الأخرى أين تسلم بريد النطاق، والقيمة اسم وليست عنوان IP |
example.com | TXT | v=spf1 mx a -all | SPF: السيرفر المذكور في سجل MX هو وحده المصرح له بالإرسال |
dkim._domainkey.example.com | TXT | v=DKIM1;k=rsa;t=s;s=email;p=MIIB… | المفتاح العام Public Key لتوقيع DKIM، وتنسخه من لوحة mailcow بعد إضافة النطاق |
_dmarc.example.com | TXT | v=DMARC1; p=none; rua=mailto:[email protected] | سياسة DMARC وعنوان استقبال التقارير |
autodiscover.example.com | CNAME | mail.example.com | الإعداد التلقائي Autoconfiguration في Outlook والهواتف |
autoconfig.example.com | CNAME | mail.example.com | الإعداد التلقائي في Thunderbird |
_autodiscover._tcp.example.com | SRV | 0 1 443 mail.example.com | بديل autodiscover لبعض البرامج |
203.0.113.10 (عكسي) | PTR | mail.example.com | الاستعلام العكسي، ويضبط من لوحة مزود السيرفر وليس من لوحة DNS |
في الجدول أعلاه لاحظ التالي:
- PTR أو rDNS: يجب أن يطابق اسم السيرفر تماماً، وأن يشير السجل A لهذا الاسم إلى العنوان نفسه، وستجده في لوحة مزود ال VPS باسم Reverse DNS أو rDNS، وإذا أضفت سجل AAAA فاضبط PTR لعنوان IPv6 أيضاً. وبدون هذا التطابق ترفض Gmail وغيرها كثيراً من الرسائل أو تصنفها رسائل مزعجة.
- SPF: سجل واحد فقط لكل نطاق، فإذا كنت ترسل أيضاً عبر خدمة أخرى مثل نشرة بريدية Newsletter أو نظام تذاكر Ticketing System فأضفها إلى السجل نفسه، مثل
v=spf1 mx a include:amazonses.com -all، والسبب أن وجود سجلي SPF يجعل الفحص يفشل في الحالتين. - DMARC: المثال في التوثيق الرسمي يبدأ مباشرة بالقيمة
p=reject، ولكن الأسلم أن تبدأ بالقيمةp=noneثم تنتقل إلىp=quarantineثم إلىp=rejectبعد أن تقرأ التقارير، كما شرحنا في قسم المراحل من شرح SPF وDKIM وDMARC للمبتدئين. - قواعد Gmail وYahoo: منذ فبراير 2024 تشترط Gmail على كل من يرسل إلى حساباتها SPF أو DKIM وسجل PTR مطابقاً والاتصال عبر TLS، وقواعد Yahoo مشابهة، وقد جمعنا الشروط كاملة ولمن تنطبق في شرح SPF وDKIM وDMARC للمبتدئين. والإعداد في هذا الدليل يحقق شروط المرسل العادي كلها.
- MTA-STS وTLS-RPT (اختياريان): يخبر MTA-STS السيرفرات الأخرى أن بريد نطاقك يجب أن يصل عبر TLS فقط، ويدعمه mailcow من لوحة الإدارة منذ إصدار 2025-09 مع سجل TXT باسم
_mta-stsوسجل CNAME باسمmta-sts، ويضيف إليه سجل TLS-RPT باسم_smtp._tlsعنواناً تصلك عليه تقارير فشل TLS. أضفهما بعد أن يستقر كل شيء، وابدأ بالوضعtesting. - إذا كنت تستخدم Cloudflare أو خدمة مشابهة، فاجعل سجلات
mailوautodiscoverوautoconfigعلى وضع DNS only دون ال Proxy، والسبب أن ال Proxy يمرر HTTP فقط ولا يمرر منافذ البريد. - كل نطاق تضيفه لاحقاً إلى mailcow يحتاج إلى سجلاته الخاصة: MX وSPF وDKIM وDMARC وautodiscover وautoconfig، أما سجلا A وPTR لاسم السيرفر فيبقيان كما هما.
بعد نشر السجلات تحقق منها من أي جهاز:
dig +short A mail.example.com
dig +short MX example.com
dig +short TXT example.com
dig +short TXT _dmarc.example.com
dig +short -x 203.0.113.10التثبيت
تنزيل mailcow
نثبت mailcow من مستودعه على GitHub Repository، ولاحظ أن المستودع نفسه يحفظ ملف الإعداد Configuration File والبيانات الدائمة Persistent Data، لذلك ضعه في مسار دائم مثل /opt/mailcow-dockerized. وتتطلب السكربتات أن تكون قيمة umask هي 0022 حتى تنشئ الملفات بالصلاحيات Permissions الصحيحة، فتأكد منها أولاً:
umaskثم نزل المستودع بصلاحيات root:
sudo -i
cd /opt
git clone https://github.com/mailcow/mailcow-dockerized
cd mailcow-dockerizedالفرع Branch الافتراضي master هو الفرع المستقر، ويحمل آخر إصدار منشور (2026-09 وقت كتابة الدليل). ولا تستخدم الوسم Tag latest ولا تغير وسوم ال Images يدوياً، والسبب أن كل إصدار من mailcow يثبت وسوم ال Images الخاصة به في docker-compose.yml، وسكربت التحديث وحده هو الذي ينقلك بين الإصدارات.
إنشاء ملف الإعداد
السكربت generate_config.sh يولد الملف mailcow.conf بكلمات مرور عشوائية Random Passwords لقاعدة البيانات Database وRedis وغيرهما، وينشئ أيضاً شهادة مؤقتة Self-signed Certificate تعمل حتى تصدر شهادة Let's Encrypt:
./generate_config.shوعند تشغيل الأمر سوف يسألك السكربت عن القيم التالية:
- Mail server hostname (FQDN): اسم السيرفر مثل
mail.example.com، وليس نطاق البريد. - Timezone: المنطقة الزمنية مثل
UTCأو منطقتك المحلية بالصيغةRegion/City. - الفرع: اختر
1للفرع المستقرmaster. - إذا كانت الذاكرة 2.5 GiB أو أقل فسوف يقترح السكربت إيقاف ClamAV، فوافق على ذلك في السيرفرات الصغيرة.
ويتحقق السكربت أيضاً من دعم IPv6 على السيرفر ويضبط ENABLE_IPV6 تلقائياً، ويضيف إلى الملف الخيار SPAMHAUS_DQS_KEY، والسبب أن Spamhaus تمنع الاستعلام المجاني عن قوائمها من شبكات بعض المزودين مثل OVH وAWS وCloudflare، فإذا كان سيرفرك في إحداها عطل mailcow قوائم Spamhaus عند التشغيل، إلا إذا أنشأت حساباً مجانياً لخدمة DQS ووضعت مفتاحها في هذا الخيار.
أهم خيارات mailcow.conf
افتح الملف وراجع القيم التالية قبل التشغيل الأول، ولاحظ أن الملف .env في المجلد هو رابط Symlink إلى mailcow.conf، لذلك يقرأ Docker Compose القيم منه مباشرة:
nano mailcow.conf# اسم الخادم كما أدخلته
MAILCOW_HOSTNAME=mail.example.com
# منافذ الواجهة؛ اتركها 80 و443 إن كان mailcow يملك الخادم وحده
HTTP_PORT=80
HTTP_BIND=
HTTPS_PORT=443
HTTPS_BIND=
# تحويل HTTP إلى HTTPS تلقائيًا
HTTP_REDIRECT=y
# أسماء إضافية في الشهادة، مثل imap.* وsmtp.* لكل نطاق
ADDITIONAL_SAN=
# شهادات Let's Encrypt عبر حاوية acme-mailcow
SKIP_LETS_ENCRYPT=n
# الخدمات الثقيلة: أوقفها في الخوادم الصغيرة
SKIP_CLAMD=n
SKIP_FTS=n
# إشعارات watchdog عند تعطل خدمة
USE_WATCHDOG=y
[email protected]
# شبكة Docker الداخلية؛ غيّرها فقط إن تعارضت مع شبكة موجودة
IPV4_NETWORK=172.22.1في الإعداد أعلاه لاحظ التالي:
- لا تغير
DBPASSوDBROOTوREDISPASSبعد التشغيل الأول، والسبب أن هذه القيم تسجل في قاعدة البيانات عند إنشائها. - يستخدم
IPV4_NETWORKالشبكة172.22.1.0/24، فإذا كانت لديك شبكة Docker أو VPN في هذا النطاق فاختر قيمة أخرى مثل172.29.1. - في الملف كلمات مرور، وصلاحياته
600ويجب أن تبقى كذلك، وهو جزء من النسخ الاحتياطي.
التشغيل الأول
docker compose pull
docker compose up -dالتنزيل الأول يجلب قرابة 18 Image حجمها عدة غيغابايتات، والإقلاع الأول يستغرق بضع دقائق لأن MariaDB تنشئ الجداول Tables وClamAV يحمل قواعد التواقيع Signature Databases، وتستطيع متابعة الحالة بهذين الأمرين:
docker compose ps
docker compose logs -f --tail=50 nginx-mailcow acme-mailcowوفي سجلات Logs ال Container acme-mailcow سوف ترى التحقق من السجل A لاسم السيرفر ثم إصدار الشهادة، وإذا فشل الإصدار لأن سجلات DNS لم تنتشر Propagation بعد فسوف يعيد ال Container المحاولة تلقائياً، ويمكنك إعادة تشغيله بنفسك بعد ضبط السجلات:
docker compose restart acme-mailcowالدخول الأول وتغيير كلمة مرور المدير Administrator
افتح https://mail.example.com/admin، ولاحظ أن في لوحة mailcow ثلاثة أنواع من الدخول: المدير في /admin، ومدير النطاق Domain Administrator في /domainadmin، والمستخدم العادي Regular User في الصفحة الرئيسية. وبيانات المدير الافتراضية Default Credentials هي اسم المستخدم admin وكلمة المرور moohoo، وهي معروفة للجميع، لذلك غيرها قبل أي خطوة أخرى.

/admin، وأسفلها روابط دخول المستخدم ومدير النطاقبعد الدخول افتح System ← Configuration ← Access ← Administrators، ثم اختر Edit بجوار المستخدم admin وأدخل كلمة مرور قوية مرتين واحفظ، وتستطيع توليد كلمة مرور من الطرفية Terminal بالأمر التالي:
openssl rand -base64 24
ومن الصفحة نفسها فعل التحقق الثنائي Two-Factor Authentication (TOTP أو مفتاح FIDO2) لحساب المدير، والسبب أن هذه اللوحة تتحكم في كل صناديق البريد. وإذا نسيت كلمة المرور لاحقاً فالسكربت helper-scripts/mailcow-reset-admin.sh يعيد ضبط Reset الحساب بكلمة مرور عشوائية.
وصفحة System ← Information تعرض حالة كل ال Containers وإصدار كل Image، فراجعها بعد التشغيل الأول لتتأكد أن كل الخدمات في حالة Running.

إضافة نطاق وصناديق بريد
إضافة النطاق
افتح E-Mail ← Configuration ← Domains ثم اختر Add domain، والحقول الأساسية هي:
- Domain: نطاق البريد فقط مثل
example.com، دونmail.. - Max. possible mailboxes / aliases والحصص: حدود النطاق، والحصة الافتراضية لكل صندوق 3 GiB وحدها الأقصى 10 GiB في الإعداد الافتراضي، فعدلها بحسب خطتك.
- Rate limit: أقصى عدد من الرسائل يرسله النطاق، مثل 100 رسالة في الساعة، وهذا الحد يحمي سمعة سيرفرك إذا سرق أحدهم كلمة مرور حساب واستغله في إرسال الرسائل المزعجة.
- Selector وDKIM key length: ينشئ mailcow مفتاح DKIM للنطاق تلقائياً بالمحدد Selector
dkimوبطول 2048 بت، فاترك القيم الافتراضية.

اختر Add domain and restart SOGo حتى يتعرف البريد عبر الويب على النطاق الجديد، وبعد ضبط سجلات DNS للنطاق أعد تشغيل acme-mailcow ليضيف autodiscover.example.com وautoconfig.example.com إلى الشهادة.
إنشاء صندوق بريد
من التبويب Mailboxes اختر Add mailbox، ثم أدخل الجزء الأيسر من العنوان Local Part مثل info والاسم الكامل، واختر النطاق وحدد كلمة المرور والحصة. والخيار Force password update at next login يلزم المستخدم بتغيير كلمة المرور المؤقتة Temporary Password التي أعطيته إياها.

[email protected] مع البروتوكولات المسموح بها وحد الإرسال الخاص به
ومن التبويب نفسه تنشئ Aliases مثل [email protected] توجه الرسائل إلى صندوق أو أكثر، وDomain aliases تجعل نطاقاً ثانياً مرادفاً للأول، ويمكنك تعيين مدير لكل نطاق من Access ← Domain administrators فيدير صناديقه دون أن يصل إلى إعدادات السيرفر.
مفتاح DKIM وفحص DNS
زر DNS بجوار النطاق في قائمة النطاقات يعرض كل السجلات المطلوبة بقيمها الصحيحة وحالتها الحالية في DNS، وهذه الشاشة هي أسرع طريقة لنسخ القيم ولمعرفة السجل الناقص.

وتجد المفتاح العام أيضاً في System ← Configuration ← Options ← ARC/DKIM keys، فانسخ القيمة كاملة وأضفها سجل TXT باسم dkim._domainkey.example.com. ولاحظ أن بعض لوحات DNS تقسم القيم الطويلة إلى عدة سلاسل Strings بين علامات تنصيص، ولا مشكلة في ذلك ما دامت السلاسل متتالية دون فواصل.

dkimالبريد عبر الويب والبرامج
يدخل المستخدم من https://mail.example.com بعنوانه وكلمة مروره، فينقله mailcow إلى SOGo حيث البريد والتقويم وجهات الاتصال، أما برامج البريد مثل Thunderbird وOutlook وتطبيقات الهواتف فيكفيها غالباً العنوان وكلمة المرور، والسبب أن بقية الإعداد تتولاها سجلات autodiscover وautoconfig.
وللإعداد اليدوي Manual Setup استخدم هذه القيم: IMAP على mail.example.com بالمنفذ 993 مع SSL/TLS، وSMTP على المنفذ 465 مع SSL/TLS أو المنفذ 587 مع STARTTLS، واسم المستخدم هو العنوان الكامل.

[email protected] في SOGo بعد الدخول من الصفحة الرئيسية[email protected]، واستخدم كلمة مرور تطبيق App password من إعدادات الصندوق بدلاً من كلمة المرور الأساسية، وحدد له Rate limit مناسباً، والسبب أن تسريب كلمة مرور التطبيق لا يكشف الحساب كله وتستطيع إلغاءها وحدها.كيف تشغل mailcow خلف Reverse Proxy؟
أبسط إعداد وأكثره استقراراً أن ينفرد mailcow بالمنفذين 80 و443 على سيرفر مخصص، فيصدر ال Container acme-mailcow الشهادة ويجددها Renewal ويستخدمها Postfix وDovecot مباشرة. أما إذا كان لديك Reverse Proxy على السيرفر نفسه مثل Nginx Proxy Manager، فانقل واجهة mailcow إلى منافذ داخلية Internal Ports:
HTTP_PORT=8080
HTTP_BIND=127.0.0.1
HTTPS_PORT=8443
HTTPS_BIND=127.0.0.1ثم أعد إنشاء ال Containers:
docker compose up -dداخل شبكة mailcow يستمع ال Container nginx-mailcow على المنفذ نفسه (8080)، لذلك يصل إليه باسمه أي Reverse Proxy يعمل في Docker إذا وصلته بشبكة mailcow، واسم الشبكة <COMPOSE_PROJECT_NAME>_mailcow-network وقيمته الافتراضية mailcowdockerized_mailcow-network:
# في docker-compose.yml الخاص بـ Nginx Proxy Manager
services:
app:
networks:
- default
- mailcow
networks:
mailcow:
name: mailcowdockerized_mailcow-network
external: trueوفي NPM أنشئ Proxy Host للأسماء mail.example.com وautodiscover.example.com وautoconfig.example.com يوجه الطلبات إلى http://nginx-mailcow:8080، ثم فعل Websockets Support وForce SSL وشهادة Let's Encrypt من NPM.
وتبقى مسألة الشهادة على منافذ البريد، حيث يحتاج Postfix وDovecot إلى شهادة صالحة للاسم mail.example.com، ولكن NPM يستقبل طلبات /.well-known/acme-challenge/ لنفسه، فيفشل التحقق عبر HTTP (HTTP Challenge) الذي تعتمد عليه acme-mailcow. والحل الأنسب أن يصدر mailcow شهادته عبر التحقق من ملكية النطاق عبر ال DNS (DNS Challenge) بعيداً عن ال Reverse Proxy، والمثال هنا Cloudflare، والطريقة نفسها تعمل مع أي مزود يدعمه acme.sh:
ACME_DNS_CHALLENGE=y
ACME_DNS_PROVIDER=dns_cf
[email protected]ثم مرر متغيرات البيئة Environment Variables الخاصة بالمزود إلى ال Container من ملف docker-compose.override.yml في مجلد mailcow، ولاحظ أن سكربت التحديث لا يمس هذا الملف:
services:
acme-mailcow:
environment:
- CF_Token=REPLACE_WITH_CLOUDFLARE_API_TOKEN
- CF_Zone_ID=REPLACE_WITH_ZONE_IDdocker compose up -d
docker compose logs --tail=50 acme-mailcowالتحقق من النجاح Verification
- أرسل رسالة من SOGo إلى حساب Gmail ثم افتح Show original، وتأكد أن نتيجة SPF وDKIM وDMARC هي
PASS، وللتقييم الكامل أرسل رسالة إلى أداة مثل mail-tester.com.
أرسل رسالة من حساب خارجي إلى [email protected] وتأكد أنها وصلت، وعند أي مشكلة راجع سجل Postfix:
docker compose logs --tail=100 postfix-mailcowالمنفذ 25 الصادر مفتوح لدى المزود، فنفذ الأمر التالي من السيرفر نفسه، وإذا انتهت المهلة دون اتصال فالمزود يحجبه:
nc -vz -w 5 gmail-smtp-in.l.google.com 25المنفذ 25 يستجيب من خارج السيرفر ويعلن الاسم الصحيح، فنفذ الأمر التالي من جهاز آخر:
nc -v mail.example.com 25والمخرج سوف يكون سطراً يبدأ بـ 220 mail.example.com ESMTP.
الشهادة من Let's Encrypt وليست الشهادة المؤقتة، على HTTPS وعلى منفذ SMTP:
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 -starttls smtp -connect mail.example.com:587 2>/dev/null | openssl x509 -noout -issuerجميع ال Containers في حالة running أو healthy:
docker compose ps --format 'table {{.Service}}\t{{.Status}}'النسخ الاحتياطي والاستعادة Restore
لـ mailcow سكربت رسمي للنسخ الاحتياطي ينسخ كل ما يلزم: الرسائل (vmail) وقاعدة البيانات، ومفاتيح التشفير (crypt) التي لا تقرأ الرسائل المستعادة بدونها، وRedis وفيه مفاتيح DKIM، وبيانات Rspamd، وطوابير Queues ال Postfix، ونسخة من mailcow.conf. ويعمل السكربت والخدمات قيد التشغيل، ويضع كل نسخة في مجلد باسم mailcow-YYYY-MM-DD-HH-MM-SS:
mkdir -p /opt/backup/mailcow
cd /opt/mailcow-dockerized
MAILCOW_BACKUP_LOCATION=/opt/backup/mailcow ./helper-scripts/backup_and_restore.sh backup all --delete-days 7الخيار --delete-days 7 يحذف النسخ التي مضى عليها أكثر من سبعة أيام، وفي أول تشغيل يسحب الأمر Image مساعدة باسم ghcr.io/mailcow/backup. وللجدولة Scheduling اليومية أضف مهمة cron:
sudo crontab -e30 2 * * * cd /opt/mailcow-dockerized && MAILCOW_BACKUP_LOCATION=/opt/backup/mailcow THREADS=2 ./helper-scripts/backup_and_restore.sh backup all --delete-days 7 >/var/log/mailcow-backup.log 2>&1لكن تذكر: النسخة المحفوظة على قرص السيرفر نفسه لا تحميك إذا تعطل السيرفر، لذلك انقل المجلد إلى تخزين خارجي Offsite Storage بأداة مثل restic أو rsync أو rclone، وانسخ معه docker-compose.override.yml وأي ملفات عدلتها في data/conf.
وللاستعادة على سيرفر جديد ثبت mailcow بالإصدار نفسه واسم السيرفر نفسه، وانتظر حتى يعمل بالكامل، وتأكد أن قيمة MAILDIR_SUB في mailcow.conf مطابقة للسيرفر القديم لأن اختلافها يخفي الرسائل بعد الاستعادة، ثم شغل السكربت في وضع restore، فيعرض النسخ المتاحة وتختار نقطة الاستعادة Restore Point وما تريد استعادته، سواءً كل شيء أو جزءاً محدداً:
cd /opt/mailcow-dockerized
MAILCOW_BACKUP_LOCATION=/opt/backup/mailcow ./helper-scripts/backup_and_restore.sh restoreالتحديث إلى إصدار أحدث
يصدر mailcow تحديثاً كل شهر تقريباً باسم مثل 2026-09، وبينها تحديثات تصحيحية Patch Releases بحروف مثل 2026-07a و2026-07b. ولا تحدث ال Images يدوياً بتعديل الوسوم، وإنما استخدم السكربت update.sh الذي يسحب الكود Code الجديد ويدمجه مع تعديلاتك، ثم يحدث وسوم ال Images ويسحبها ويعيد التشغيل. وقبل التحديث خذ نسخة احتياطية واقرأ ملاحظات الإصدار Release Notes على GitHub:
cd /opt/mailcow-dockerized
./update.sh --checkرمز الخروج Exit Code 0 يعني أن هناك تحديثاً، والرمز 3 يعني أنك على آخر إصدار. ولتقصير مدة التوقف Downtime اسحب ال Images أولاً ثم نفذ التحديث:
./update.sh --prefetch
./update.shوقد يحدث السكربت ملفاته المساعدة في المجلد _modules ثم يطلب منك تشغيله مرة ثانية، فنفذه مجدداً، وبعد التحديث احذف ال Images القديمة لتوفير المساحة:
./update.sh --gcوضع تعديلاتك في docker-compose.override.yml وفي ملفات الإعداد المخصصة التي يوثقها mailcow مثل data/conf/postfix/extra.cf، ولا تضعها في docker-compose.yml، والسبب أنها سوف تتعارض مع التحديث. وتنبهك لوحة الإدارة إلى صدور إصدار جديد في صفحة Information.
مشكلات شائعة وحلولها Troubleshooting
لماذا تصل الرسائل إلى مجلد الرسائل المزعجة أو ترفض؟
- PTR غير مطابق: تأكد أن
dig +short -x 203.0.113.10يعيدmail.example.com، وأن السجل A لهذا الاسم يعيد العنوان نفسه. - فشل SPF أو DKIM: راجع الترويسة Header المسماة Authentication-Results في الرسالة المستلمة، فإذا كانت نتيجة DKIM
failأوnoneفالسبب غالباً مفتاح نسخته ناقصاً أو بمسافات زائدة، أو سجل DNS قديم ما زال في الذاكرة المؤقتة Cache. - عنوان IP في قوائم الحظر: افحصه لدى Spamhaus وMXToolbox، فبعض المزودين يعطونك عنواناً جديداً يحمل سمعة سيئة من مستخدمين سابقين، فاطلب رفعه من القائمة أو اطلب عنواناً آخر.
- سمعة جديدة: السيرفرات الأخرى تتعامل بحذر مع سيرفر جديد ليس له تاريخ إرسال Sending History، لذلك ابدأ بحجم إرسال Sending Volume صغير، ولا ترسل الحملات التسويقية Marketing Campaigns من خادم البريد الأساسي، بل خصص لها أداة مستقلة ونطاقاً فرعياً Subdomain، والسبب أن شكاوى حملة واحدة قد تضر بريد الموظفين اليومي.
- Microsoft وOutlook: سجل عنوانك في برنامج Microsoft SNDS، وإذا رفضت Microsoft رسائلك برمز يذكر عنوان IP فاطلب رفع الحظر من صفحة الدعم الخاصة بها.
لماذا يتعذر الإرسال إلى الخارج؟
إذا بقيت الرسائل في الطابور (E-Mail ← Queue Manager) مع الخطأ Connection timed out على المنفذ 25، فالمزود يحجب المنفذ الصادر، فاطلب فتحه من الدعم الفني Support، أو أرسل عبر خادم وسيط Relay مثل Amazon SES. أضف بيانات الوسيط في System ← Configuration ← Routing ← Sender-dependent transports ثم اختره في إعدادات النطاق، وإذا استخدمت وسيطاً فأضفه إلى سجل SPF وأضف سجلات DKIM التي يطلبها.
ال Container unbound-mailcow بحالة unhealthy
يستخدم mailcow خادم DNS داخلياً هو Unbound يستعلم مباشرة من الخوادم الجذرية Root Servers، والسبب أن فحوص الرسائل المزعجة تحتاج إلى استعلامات DNS دقيقة. فإذا كان جدار حماية الشبكة يمنع استعلامات DNS الصادرة على المنفذ 53، يفشل unbound-mailcow في فحص الصحة Health Check وتبقى بقية ال Containers متوقفة في انتظاره. والحل الصحيح أن تسمح بالاتصال الصادر على UDP/TCP 53، ومؤقتاً يمكنك تجاوز الفحص:
SKIP_UNBOUND_HEALTHCHECK=yولا توجه استعلامات Unbound إلى خوادم DNS عامة مثل 8.8.8.8، والسبب أن قوائم الحظر مثل Spamhaus ترفض الاستعلامات القادمة منها.
فشل التشغيل لأن أحد المنافذ مستخدم
إذا ظهر خطأ مثل bind: address already in use على المنفذ 25، فهناك Postfix أو Exim تابع للنظام يعمل على السيرفر، فأوقفه وعطله (systemctl disable --now postfix)، وإذا ظهر على المنفذين 80 و443 فهناك خادم ويب Web Server أو Reverse Proxy آخر، فاتبع قسم ال Reverse Proxy.
الذاكرة لا تكفي
إذا ظل Docker يعيد تشغيل clamd-mailcow أو غيره وظهرت رسائل OOM في dmesg، فاضبط SKIP_CLAMD=y وSKIP_FTS=y في mailcow.conf، ثم أضف ملف swap ونفذ docker compose up -d.
المتصفح Browser وبرامج البريد تحذر من الشهادة
التحذير يعني أن mailcow ما زال يستخدم الشهادة المؤقتة، فراجع docker compose logs acme-mailcow، والأسباب المعتادة هي: السجل A لا يشير إلى السيرفر، أو المنفذ 80 مغلق، أو Reverse Proxy يعترض طلبات التحقق، أو أنك أضفت أسماء في ADDITIONAL_SAN دون سجلات DNS لها.
الخلاصة
وصلنا لنهاية الموضوع، وأهم ما فيه:
- رسالة من سيرفر جديد بلا SPF وDKIM وPTR سوف تصل إلى الرسائل المزعجة أو ترفض، لذلك اضبط السجلات كلها قبل أول رسالة.
- اختر مزوداً يسمح بالمنفذ 25 الصادر وبتعديل PTR، ويقدم جهازاً افتراضياً كاملاً مثل KVM، مع 6 GiB من الذاكرة على الأقل.
- ابدأ DMARC بالقيمة
p=noneوانتقل إلىp=rejectبعد أن تراجع التقارير. - غير كلمة مرور المدير الافتراضية فوراً وفعل التحقق الثنائي، وحدد Rate limit لكل نطاق.
- انسخ vmail وcrypt معاً إلى تخزين خارجي يومياً، واختبر الاستعادة على سيرفر مؤقت، وحدث بالسكربت
update.shدون تأجيل.
سجل التحديثات Changelog
- سبتمبر 2026: كتابة الدليل واختباره على mailcow-dockerized 2026-09.
- أكتوبر 2026: مراجعة الدليل على mailcow-dockerized 2026-09: صححنا وصف فحص Spamhaus (يحدث عند تشغيل ال Containers وليس في
generate_config.sh، ويحله الخيارSPAMHAUS_DQS_KEY)، وأضفناjqومزامنة الوقت NTP وأنواع الأجهزة الافتراضية غير المدعومة إلى المتطلبات، وأضفنا أمثلة حجب المنفذ 25 لدى Hetzner وDigitalOcean وAWS، وقواعد Gmail وYahoo للمرسلين، وسجلات MTA-STS وTLS-RPT الاختيارية، وشرط تطابقMAILDIR_SUBعند الاستعادة، وأنupdate.shقد يطلب إعادة تشغيله بعد تحديث_modules.