วิธีติดตั้ง Mailcow บน VPS ให้ส่งอีเมลถึง Gmail ได้จริง
ตรวจสอบพอร์ต 25 บน VPS ก่อนติดตั้ง Mailcow เพราะหากถูกบล็อกอีเมลจะค้างในคิว พร้อมวิธีตั้งค่า DNS เพื่อแก้ไขข้อผิดพลาด 550 5.7.25 PTR ที่ทำให้ Gmail ปฏิเสธการรับอีเมลของคุณ
สิ่งที่คุณกำลังสร้าง
การสร้างเซิร์ฟเวอร์อีเมลแบบครบวงจรบนเครื่องที่คุณเป็นเจ้าของ: มี SMTP สำหรับรับและส่งอีเมล, IMAP เพื่อให้โทรศัพท์และแล็ปท็อปของคุณซิงค์ข้อมูลกันได้ตลอดเวลา, เว็บเมลไคลเอนต์ และระบบกรองสแปมที่ให้คะแนนทุกข้อความทั้งขาเข้าและขาออก mailcow-dockerized ได้รวมเอา Postfix, Dovecot, Rspamd, SOGo webmail, MariaDB, Redis และ ACME client ไว้ใน Docker Compose stack เดียวกัน ดังนั้นตัวซอฟต์แวร์จึงไม่ใช่ส่วนที่ยาก คุณสามารถติดตั้งให้พร้อมใช้งานได้ภายในครึ่งชั่วโมง
ส่วนที่ยากคือทุกสิ่งที่อยู่รอบตัวมัน อีเมลเป็นบริการเดียวที่อินเทอร์เน็ตส่วนที่เหลือจะระแวงเซิร์ฟเวอร์ที่เพิ่งสร้างใหม่โดยอัตโนมัติ และช่องว่างระหว่าง "มันใช้งานได้" กับ "Gmail กลืนข้อความทั้งหมดโดยไม่แจ้งเตือน" นั้นขึ้นอยู่กับ DNS record 4 รายการ และการตั้งค่า IP-reputation อีกหนึ่งรายการที่คุณอาจควบคุมไม่ได้ทั้งหมด โปรดอ่านข้อกำหนดเบื้องต้นด้านล่างก่อนที่คุณจะเช่าเซิร์ฟเวอร์ใดๆ หากหลังจากอ่านแล้วคุณตัดสินใจว่าการสร้างชื่อเสียงให้กับ IP นั้นไม่คุ้มค่า นั่นก็เป็นเหตุผลที่สมเหตุสมผล โดยใน บทสรุปสิ่งที่คุณควรทำ self-hosting ในปี 2026 ของเรา ได้จัดหมวดหมู่อีเมลไว้ในหัวข้อ "เฉพาะเมื่อคุณตั้งใจจริงเท่านั้น" ด้วยเหตุผลเหล่านี้เอง
สิ่งที่ต้องเตรียมพร้อมคือตัวโครงการเอง
หากขาดข้อใดข้อหนึ่งไป อีเมลที่คุณส่งจะไม่มีวันถึงผู้รับ ต่อไปนี้คือรายการสิ่งที่มักทำให้ผู้ใช้งานประสบปัญหา โดยเรียงลำดับตามความถี่ที่พบบ่อย:
พอร์ตขาออก 25 ต้องเปิดใช้งาน เซิร์ฟเวอร์ของคุณจะส่งอีเมลไปยัง Gmail และ Microsoft ผ่าน TCP พอร์ต 25 ผู้ให้บริการ VPS และ Cloud จำนวนมากบล็อกพอร์ต 25 ขาออกไว้เป็นค่าเริ่มต้นเพื่อป้องกันสแปม การบล็อกนี้จะไม่มีการแจ้งเตือนใดๆ ไม่มีข้อผิดพลาดตอนบูต ทุกอย่างดูปกติ แต่เมลจะค้างอยู่ในคิวตลอดไป ให้ทดสอบพอร์ตนี้ก่อนติดตั้งซอฟต์แวร์ใดๆ หากพอร์ตถูกบล็อก วิธีแก้ไขเดียวคือการเปิดตั๋วสนับสนุน (support ticket) เพื่อขอให้ผู้ให้บริการเปิดพอร์ตให้ บางรายอาจยอมเปิดให้สำหรับบัญชีที่ใช้งานมานาน แต่บางรายอาจไม่ยอมเปิดให้เลย
IP ที่สะอาดและมีชื่อเสียงที่ใช้งานได้ IP ของ VPS ที่ถูกนำกลับมาใช้ใหม่มักจะติดอยู่ในบัญชีดำ (blocklist) จากผู้เช่ารายก่อนที่เคยส่งสแปม ให้ตรวจสอบ IP ของคุณผ่านบริการอย่าง Spamhaus lookup หรือ mxtoolbox ก่อนเริ่มดำเนินการ หาก IP ติดบัญชีดำ คุณจะถูกปฏิเสธการส่งเมลโดยไม่สามารถแก้ไขได้ด้วยการเขียนโค้ด
การควบคุม DNS และบันทึก PTR ที่ถูกต้อง คุณต้องเพิ่มระเบียน (record) ลงในโซนของโดเมน และต้องมี reverse DNS (PTR) สำหรับ IP ของเซิร์ฟเวอร์ที่ชี้กลับไปยัง hostname ของเมลคุณ โดยปกติแล้ว PTR จะไม่ได้ตั้งค่าในแผงควบคุม DNS ของคุณ แต่จะอยู่ที่ผู้เป็นเจ้าของ IP นั้นๆ ดังนั้นคุณต้องตั้งค่าในแผงควบคุมของผู้ให้บริการ VPS หรือเปิดตั๋วสนับสนุนเพื่อขอให้ตั้งค่า
RAM 6 GiB และ 2 vCPU คือระดับขั้นต่ำที่เหมาะสม ความต้องการขั้นต่ำของ mailcow คือ RAM 6 GiB บวกกับ swap 1 GiB สำหรับการติดตั้งส่วนตัว และแนะนำที่ 8 GiB เมื่อมีผู้ใช้งานจำนวนหนึ่ง หาก RAM ต่ำกว่าประมาณ 2.5 GiB ตัว generate_config.sh จะเสนอให้ปิดการทำงานของ ClamAV virus scanner เพื่อป้องกันไม่ให้ kernel สั่ง kill คอนเทนเนอร์ทิ้ง ควรเตรียมพื้นที่ SSD อย่างน้อย 20 GB สำหรับการเริ่มต้น
ชื่อ DNS ไม่ใช่ IP เปล่าๆ เลือก hostname เช่น mail.example.com ชื่อเดียวนี้จะกลายเป็น MAILCOW_HOSTNAME ของคุณ, เป็นหัวข้อของใบรับรอง TLS, เป็นเป้าหมายของ PTR และเป็น SMTP banner ของคุณ โปรดรักษาความสอดคล้องของชื่อนี้ในทุกจุดที่เกี่ยวข้อง
ขั้นตอนที่ 1 ตรวจสอบว่าพอร์ต 25 ขาออกเปิดใช้งานอยู่
ให้ดำเนินการขั้นตอนนี้ก่อน หากขั้นตอนนี้ไม่สำเร็จ การตั้งค่าส่วนอื่นทั้งหมดจะเสียเปล่า จาก VPS เครื่องใหม่ ให้ลองเปิดการสนทนา SMTP กับเมลเซิร์ฟเวอร์จริง:
sudo apt update && sudo apt install -y netcat-openbsd
nc -vz -w 5 gmail-smtp-in.l.google.com 25ผลลัพธ์ที่ใช้งานได้จะแสดงขึ้นทันที:
Connection to gmail-smtp-in.l.google.com (142.250.x.x) 25 port [tcp/smtp] succeeded!หากพอร์ตถูกบล็อก การเชื่อมต่อจะค้างเป็นเวลา 5 วินาทีเต็มแล้วจึงล้มเหลว:
nc: connect to gmail-smtp-in.l.google.com port 25 (tcp) timed out: Operation now in progressการหมดเวลา (timeout) ดังกล่าวคือการบล็อก ซึ่งเป็นตัวกรองเครือข่ายจากฝั่งผู้ให้บริการ ไม่ใช่ไฟร์วอลล์ของคุณ ดังนั้นการแก้ไขในเครื่องจึงไม่สามารถแก้ปัญหานี้ได้ ให้เปิดตั๋วสนับสนุน (ticket) โดยระบุว่า: "โปรดเปิดใช้งานพอร์ต TCP 25 ขาออกสำหรับ VPS ของฉันที่ <IP> เนื่องจากฉันกำลังรันเมลเซิร์ฟเวอร์ที่ถูกต้องตามกฎหมาย" อย่าติดตั้ง mailcow จนกว่าจะได้รับผลตอบรับว่า "succeeded" โปรดทราบว่าพอร์ต 25 ขาเข้า (เซิร์ฟเวอร์อื่นติดต่อมาหาคุณ) เป็นคนละส่วนกันและมักจะเปิดอยู่ โดยปกติแล้วผู้ให้บริการจะจำกัดเฉพาะฝั่งขาออกเท่านั้น
ขั้นตอนที่ 2 กำหนดค่า DNS records ในขณะนี้
การเปลี่ยนแปลงค่า DNS ต้องใช้เวลาในการเผยแพร่ ดังนั้นควรประกาศค่าทั้งหมดที่ทำได้ก่อนเริ่มการติดตั้ง สมมติว่าโดเมนของคุณคือ example.com, เมลโฮสต์ของคุณคือ mail.example.com และ IP คือ 10.0.0.10 ให้สร้างรายการต่อไปนี้ในโซนของคุณ:
mail.example.com. A 10.0.0.10
mail.example.com. AAAA 2001:db8::10 ; only if you have IPv6
example.com. MX 10 mail.example.com.
example.com. TXT "v=spf1 mx -all"
_dmarc.example.com. TXT "v=DMARC1; p=none; rua=mailto:postmaster@example.com"SPF record ระบุว่า "อนุญาตให้เฉพาะ MX ของฉันเท่านั้นที่ส่งเมลแทนโดเมนนี้ได้ และให้ปฏิเสธที่เหลือทั้งหมด" ให้เริ่มใช้งาน DMARC ที่ p=none เพื่อให้คุณสามารถตรวจสอบรายงานได้โดยที่เมลของคุณจะไม่ถูกตีกลับ จากนั้นให้ปรับความเข้มงวดเป็น p=quarantine และ p=reject ตามลำดับเมื่อยืนยันความถูกต้องของ alignment แล้ว ยังมีอีกสอง records ที่จงใจเว้นไว้คือ DKIM ซึ่ง mailcow จะสร้างให้คุณในขั้นตอนที่ 6 และ PTR ซึ่งคุณต้องกำหนดค่าในแผงควบคุมของผู้ให้บริการของคุณในขณะนี้
กำหนดค่า PTR (reverse DNS) สำหรับ 10.0.0.10 ให้เป็น mail.example.com ซึ่งเป็นค่าที่ตรงกับ MAILCOW_HOSTNAME นี่คือ record เพียงรายการเดียวที่คนส่วนใหญ่มักลืม และผู้ให้บริการรายใหญ่จะปฏิเสธการรับเมลหากไม่มีค่านี้ หากแผงควบคุมของคุณไม่มีช่องสำหรับตั้งค่า rDNS ให้เปิด ticket แจ้งผู้ให้บริการ
ขั้นตอนที่ 3 ติดตั้ง Docker
mailcow ต้องการ Docker Engine พร้อมปลั๊กอิน Compose v2 ให้ใช้สคริปต์ติดตั้งแบบสะดวก (convenience script) ของ Docker แทนแพ็กเกจ docker.io ของ Ubuntu เนื่องจากไม่มีปลั๊กอิน Compose มาให้เลย:
curl -fsSL https://get.docker.com | sudo sh
sudo docker compose versionคุณควรจะเห็นบรรทัด Docker Compose version v2.x หาก docker compose version แสดงผลเป็น docker: 'compose' is not a docker command แสดงว่ามีการติดตั้ง Docker Engine แล้วแต่ยังขาดปลั๊กอิน Compose ให้ติดตั้งปลั๊กอินจาก repository ของ Docker, รันสคริปต์ด้านบนใหม่อีกครั้ง หรือทำตาม คู่มือพื้นฐาน Docker Compose ของเรา ซึ่งจะติดตั้งทั้งสองส่วนจาก apt repository ของ Docker โดยตรง
ขั้นตอนที่ 4, โคลน mailcow และสร้างไฟล์คอนฟิก
cd /opt
sudo git clone https://github.com/mailcow/mailcow-dockerized
cd mailcow-dockerized
umask
sudo ./generate_config.shตรวจสอบให้แน่ใจว่า umask แสดงผลเป็น 0022 ก่อน เพราะ mailcow จะปฏิเสธการติดตั้งหากไฟล์มีสิทธิ์การเข้าถึง (file mask) ที่ไม่เหมาะสม ซึ่งโดยปกติแล้ว root shell ของ Ubuntu 24.04 ที่ติดตั้งใหม่จะให้ค่าเป็น 0022 อยู่แล้ว จากนั้นสคริปต์จะถามข้อมูลที่สำคัญที่สุดเพียงอย่างเดียวคือ fully qualified hostname ให้ระบุเป็น mail.example.com โดยค่านี้ต้องตรงกับ A record และ PTR ของคุณทุกประการ สคริปต์จะเขียนไฟล์ mailcow.conf ซึ่งเป็นไฟล์ environment เพียงไฟล์เดียวที่ทั้ง stack จะอ่านค่าไปใช้งาน ให้เปิดไฟล์นี้หากคุณต้องการเปลี่ยนพอร์ตเว็บ (HTTP_PORT, HTTPS_PORT) หรือต้องการปิดการทำงานของ ClamAV ในกรณีที่ใช้เซิร์ฟเวอร์ขนาดเล็ก:
MAILCOW_HOSTNAME=mail.example.com
HTTP_PORT=80
HTTPS_PORT=443
SKIP_CLAMD=n # set to y to drop the virus scanner on a <2.5 GiB boxSKIP_FTS=y เป็นอีกหนึ่งตัวเลือกสำหรับเซิร์ฟเวอร์ที่มี RAM จำกัด เนื่องจากระบบค้นหาข้อความแบบเต็ม (full-text search) เป็นตัวกินทรัพยากรหน่วยความจำอันดับสองตามที่เอกสารของ mailcow ระบุไว้ การปิดใช้งานฟีเจอร์นี้จะส่งผลเพียงแค่คุณไม่สามารถค้นหาเนื้อหาภายในตัวอีเมลผ่าน webmail ได้เท่านั้น
ให้คงค่า HTTP_PORT=80 และ HTTPS_PORT=443 ไว้ตามเดิม เว้นแต่ว่าจะมีบริการอื่นบนโฮสต์ใช้งานพอร์ตเหล่านี้อยู่แล้ว เนื่องจาก ACME client ที่มาพร้อมกับ mailcow จำเป็นต้องเข้าถึงพอร์ต 80 จากอินเทอร์เน็ตเพื่อขอรับใบรับรอง TLS นี่คือเหตุผลที่คุณไม่ควรติดตั้ง nginx-plus-Certbot แยกต่างหาก บนเครื่องเดียวกัน เพราะ mailcow จะออกและต่ออายุใบรับรอง TLS ของตนเองภายในระบบ หากมีบริการอื่นมาแย่งใช้งานพอร์ต 80/443 จะทำให้กระบวนการนี้ล้มเหลว กฎเดียวกันนี้ใช้กับบริการอื่นใดก็ตามที่ต้องการหน้าเว็บสาธารณะ ดังนั้นโปรเจกต์อย่าง Halcyon ที่ปรับแต่งหน้าตา Jellyfin ให้เหมือนร้านเช่าวิดีโอในยุค 90 ซึ่งต้องการ reverse proxy ของตัวเองบนพอร์ต 443 จึงควรติดตั้งบนโฮสต์อื่น ข้อยกเว้นคือบริการที่ไม่จำเป็นต้องใช้พอร์ตเว็บสาธารณะเลย เช่น RustDesk relay ที่โฮสต์เอง ซึ่งจะฟังเฉพาะพอร์ตในช่วง 21115 ถึง 21119 เท่านั้น จึงสามารถใช้งานร่วมกับเครื่องนี้ได้หากคุณมีแบนด์วิดท์เหลือเพียงพอ
ขั้นตอนที่ 5 เริ่มการทำงานของ stack และเข้าสู่ระบบ
sudo docker compose pull
sudo docker compose up -d
sudo docker compose psการ pull จะดึง image ประมาณสองโหล โปรดรอสักครู่ เมื่อ docker compose ps แสดงสถานะของ container ทุกตัวเป็น running (หรือ healthy) ให้เปิด https://mail.example.com ในเว็บเบราว์เซอร์ ชื่อผู้ใช้เริ่มต้นสำหรับผู้ดูแลระบบคือ admin และรหัสผ่านคือ moohoo ให้เปลี่ยนรหัสผ่านทันทีในหน้า UI ของผู้ดูแลระบบที่เมนู Access → Administrators หากเบราว์เซอร์แจ้งเตือน NET::ERR_CERT_AUTHORITY_INVALID แสดงว่า certificate จาก ACME ยังไม่ออกให้ โปรดดูหัวข้อความล้มเหลวของ ACME ด้านล่างก่อนที่จะสรุปว่าระบบมีปัญหา การแสดง certificate แบบ self-signed เป็นเรื่องปกติในช่วง 1 ถึง 2 นาทีแรก
ขั้นตอนที่ 6 เพิ่มโดเมน, กล่องจดหมาย และเผยแพร่ DKIM
ในหน้า UI สำหรับผู้ดูแลระบบ ให้เปิดหน้า Mail Setup (Configuration → Mail Setup) จากนั้นภายใต้แท็บ Domains ให้คลิก Add domain แล้วระบุ example.com ต่อมาภายใต้หัวข้อ Mailboxes ให้เลือก Add mailbox เพื่อสร้าง you@example.com พร้อมกำหนดรหัสผ่าน กล่องจดหมายนี้จะใช้งานได้ทันทีและสามารถเข้าถึงผ่าน IMAP ได้แล้ว
สำหรับกุญแจ DKIM ให้ไปที่ Configuration → ARC/DKIM keys โดย mailcow อาจสร้างกุญแจให้โดยอัตโนมัติเมื่อคุณเพิ่มโดเมน หากยังไม่มีให้สร้างขึ้นใหม่โดยเลือกโดเมนที่ต้องการ ใช้ selector เป็น dkim เลือกความยาว 2048-bit แล้วคลิก Add จากนั้นคัดลอกค่า TXT ยาวๆ ที่ปรากฏขึ้นมาเพื่อนำไปเผยแพร่ดังนี้:
dkim._domainkey.example.com. TXT "v=DKIM1;k=rsa;t=s;s=email;p=MIIBIjANBgkqh...long-key...QAB"หน้า Domains ของ mailcow จะมีปุ่ม DNS ซึ่งแสดงรายการ record ทั้งหมดที่ระบบต้องการ พร้อมเครื่องหมายถูกสีเขียวหรือกากบาทสีแดงเพื่อระบุสถานะของ record ที่เผยแพร่อยู่จริง ให้ใช้หน้านี้เป็นรายการตรวจสอบและทำให้ทุกแถวแสดงสถานะเป็นสีเขียวทั้งหมดก่อนเริ่มทดสอบการส่งอีเมล หากแถว DKIM ยังเป็นสีแดงหลังจากเผยแพร่แล้ว มักเกิดจากการแบ่งส่วนข้อมูล TXT ไม่ถูกต้อง เนื่องจากกุญแจขนาด 2048-bit มีความยาวเกินขีดจำกัด 255 ตัวอักษรสำหรับ string TXT หนึ่งชุด ให้คุณวางค่าดังกล่าวเป็นค่าเดียวในเชิงตรรกะ แล้วปล่อยให้ผู้ให้บริการ DNS ของคุณเป็นผู้จัดการแบ่งส่วนข้อมูลให้โดยอัตโนมัติ
ขั้นตอนที่ 7 ทดสอบการส่งอีเมลและทำคะแนนให้ได้ 10/10
ไปที่เว็บไซต์ mail-tester.com คัดลอกที่อยู่อีเมลสุ่มที่ปรากฏขึ้นมา แล้วส่งข้อความจากกล่องจดหมายใหม่ของคุณไปยังที่อยู่นั้น โดยให้ล็อกอินเข้าใช้งาน SOGo webmail ที่ https://mail.example.com/SOGo แล้วส่งอีเมลจากที่นั่น จากนั้นคลิกปุ่ม "Then check your score"
ตั้งเป้าหมายให้ได้คะแนน 10/10 โดยสาเหตุที่มักถูกหักคะแนนมีดังนี้:
- SPF ไม่ตรงกัน (SPF not aligned): ระเบียน
MX/SPF ของคุณหายไป หรือ IP ที่ใช้ส่งอีเมลไม่อยู่ในรายการที่อนุญาต ให้ตรวจสอบระเบียน TXT ของ SPF อีกครั้ง - ลายเซ็น DKIM ตรวจสอบไม่ผ่าน (DKIM signature does not verify): ระเบียน TXT ของ
dkim._domainkeyหายไป, กำลังอยู่ในระหว่างการเผยแพร่ข้อมูล (propagation) หรือข้อมูลผิดเพี้ยน นี่เป็นสาเหตุที่พบบ่อยที่สุด - ไม่มี PTR / PTR ไม่ตรงกัน (No PTR / PTR mismatch): reverse DNS ไม่ชี้กลับมาที่
mail.example.comให้แก้ไขการตั้งค่านี้ที่ผู้ให้บริการโฮสติ้งของคุณ - ติดอยู่ในรายการบล็อก (Listed on a blocklist): เกิดจากชื่อเสียงเดิมของ IP ของคุณ ให้ทำเรื่องขอถอดชื่อออกจากรายการบล็อกหรือขอเปลี่ยน IP ใหม่ที่สะอาดกว่า
อย่าเพิ่งส่งอีเมลจริงไปยัง Gmail หรือ Outlook จนกว่าคะแนนจะถึง 10/10 การที่คะแนนต่ำร่วมกับการใช้ IP ใหม่เป็นสาเหตุที่ทำให้โดเมนของคุณถูกขึ้นบัญชีดำตั้งแต่วันแรกที่ใช้งาน
ขั้นตอนที่ 8, เชื่อมต่อกับโปรแกรมรับส่งอีเมลจริง
ตั้งค่า Thunderbird, Apple Mail หรือโทรศัพท์ของคุณให้เชื่อมต่อกับเซิร์ฟเวอร์โดยใช้ค่าต่อไปนี้ โดยใช้ mail.example.com เป็นโฮสต์ของเซิร์ฟเวอร์สำหรับทุกรายการ:
- IMAP: พอร์ต 993, SSL/TLS (หรือ 143 หากใช้ STARTTLS)
- SMTP submission: พอร์ต 465, SSL/TLS (หรือ 587 หากใช้ STARTTLS)
- Username: ที่อยู่อีเมลเต็ม,
you@example.com - Password: รหัสผ่านของกล่องจดหมายที่คุณตั้งไว้
ห้ามส่งอีเมลจากไคลเอนต์ผ่านพอร์ต 25 โดยเด็ดขาด เนื่องจากพอร์ตดังกล่าวมีไว้สำหรับการสื่อสารระหว่างเซิร์ฟเวอร์ต่อเซิร์ฟเวอร์เท่านั้น mailcow ไม่รองรับการส่งอีเมลแบบยืนยันตัวตนผ่านพอร์ตนี้ และการเชื่อมต่อจากไคลเอนต์จะถูกปฏิเสธ หากไคลเอนต์แจ้งข้อผิดพลาด Relay access denied แสดงว่าไคลเอนต์กำลังพยายามส่งอีเมลผ่านพอร์ต 25 หรือไม่ได้ทำการยืนยันตัวตน ให้เปลี่ยนไปใช้พอร์ต 465 หรือ 587 พร้อมระบุข้อมูลประจำตัวของกล่องจดหมายของคุณแทน
ขั้นตอนที่ 9 สำรองข้อมูลที่สำคัญจริง ๆ
mailcow มีสคริปต์สำรองข้อมูลที่ทำ snapshot ของทุก volume ที่มีการเก็บสถานะ ให้รันสคริปต์นี้ไปยังดิสก์ภายนอกหรือพื้นที่จัดเก็บระยะไกลที่ mount ไว้:
sudo MAILCOW_BACKUP_LOCATION=/opt/mailcow-backups \
./helper-scripts/backup_and_restore.sh backup allall จะเก็บข้อมูล 6 ส่วน ซึ่งหากสูญเสียส่วนใดส่วนหนึ่งไปจะทำให้ข้อมูลสูญหาย: vmail (กล่องจดหมายจริง), crypt (คีย์สำหรับถอดรหัส vmail ซึ่งจะไม่มีประโยชน์หากไม่มี vmail), mysql (MariaDB ที่เก็บโดเมน, ผู้ใช้, นามแฝง และการตั้งค่า), redis (สถานะคิวและแคช), rspamd (ข้อมูล spam/ham ที่เรียนรู้ไว้) และ postfix (คิวของอีเมล) สคริปต์นี้ทำงานภายในคอนเทนเนอร์เสริมเพื่อเขียนไฟล์บีบอัด ทำให้การสำรองข้อมูลมีความสอดคล้องกันแม้ในขณะที่ stack กำลังทำงานอยู่ ให้ทำระบบอัตโนมัติด้วย cron job รายคืน และเพิ่ม --delete-days 14 เพื่อลบชุดข้อมูลเก่าทิ้ง งาน cron ที่หยุดทำงานมักจะล้มเหลวโดยไม่มีการแจ้งเตือน ดังนั้นควรส่งสถานะการทำงานของสคริปต์ไปยังช่องทางที่คุณจะสังเกตเห็นได้จริง เซิร์ฟเวอร์ ntfy ที่คุณโฮสต์เอง สามารถรับคำสั่ง curl บรรทัดเดียวจาก cron entry เดียวกันเพื่อแจ้งเตือนความล้มเหลวไปยังโทรศัพท์ของคุณในคืนที่เกิดปัญหา การกู้คืนข้อมูลใช้สคริปต์เดียวกันกับ restore ซึ่งจะแสดงรายการ snapshot และให้คุณเลือกสิ่งที่ต้องการกู้คืน การสำรองข้อมูลที่คุณไม่เคยทดสอบกู้คืนถือเป็นเพียงความหวัง ไม่ใช่การสำรองข้อมูลจริง ให้ลองทำ dry run บน VPS สำรองดูสักครั้ง
ขั้นตอนที่ 10, การอัปเดตตามกำหนดเวลา
mailcow อัปเดตผ่านสคริปต์ของตนเอง ซึ่งจะดึงโค้ดใหม่ ทำการย้ายข้อมูล mailcow.conf, ดึงอิมเมจล่วงหน้า และรีสตาร์ทคอนเทนเนอร์ตามลำดับ:
cd /opt/mailcow-dockerized
sudo ./update.sh --check # reports whether an update exists, changes nothing
sudo ./update.sh # applies itให้สำรองข้อมูลก่อน (ขั้นตอนที่ 9) เนื่องจากการย้าย schema ข้อมูลกลับคืนได้ยาก การอัปเดตมักเกิดขึ้นบ่อยและรวมถึงการแก้ไขความปลอดภัยสำหรับ daemon ที่เชื่อมต่อกับอินเทอร์เน็ต ดังนั้นอย่าปล่อยให้เมลเซิร์ฟเวอร์ล้าสมัยเป็นเวลาหลายเดือน หากการอัปเดตทำให้คอนเทนเนอร์อยู่ในสถานะไม่สมบูรณ์ sudo docker compose logs --tail=50 <service>-mailcow จะระบุชื่อ daemon ที่ไม่สามารถกลับมาทำงานได้ตามปกติ
หมายเหตุเกี่ยวกับการเสริมความปลอดภัย
mailcow มีบริการ netfilter ของตนเอง (netfilter-mailcow) ซึ่งจะทำการแบน IP ที่พยายามโจมตีพอร์ตของ mail และ webmail อย่างต่อเนื่อง ดังนั้นระบบอีเมลจึงได้รับการป้องกันตั้งแต่เริ่มต้น อย่างไรก็ตาม การป้องกันนี้ไม่ครอบคลุมถึง SSH บนโฮสต์ ซึ่งยังคงเปิดเผยอยู่และเสี่ยงต่อการถูก brute-force ดังนั้นควรใช้งานร่วมกับ Fail2ban สำหรับตรวจสอบ log การยืนยันตัวตนของ SSH และใช้การล็อกอินด้วย key เท่านั้น ควรตั้งรหัสผ่านที่คาดเดายากสำหรับหน้า admin UI ของ mailcow และหากเป็นไปได้ ควรจำกัดการเข้าถึงไม่ให้ผ่านอินเทอร์เน็ตสาธารณะหรือใช้งานผ่าน VPN เท่านั้น
รูปแบบความล้มเหลวและข้อความแจ้งเตือนที่เกี่ยวข้อง
คิวอีเมลค้างและไม่ส่งออก ให้รันคำสั่ง sudo docker compose exec postfix-mailcow postqueue -p หรือตรวจสอบคิวอีเมลผ่านหน้า admin UI หากรายการสถานะเป็น deferred พร้อมข้อความ:
status=deferred (connect to gmail-smtp-in.l.google.com[142.250.x.x]:25: Connection timed out)กรณีนี้หมายความว่าพอร์ต 25 ขาออกถูกผู้ให้บริการบล็อกไว้ (ขั้นตอนที่ 1) การแก้ไขค่าคอนฟิกไม่สามารถช่วยได้ ให้เปิด ticket แจ้งผู้ให้บริการ ปัญหานี้ไม่ใช่เรื่องของ DNS หรือ TLS โดยจุดสังเกตคือคำว่า timed out ที่ปรากฏขึ้นเมื่อเชื่อมต่อกับ MX ปลายทางบนพอร์ต 25
Gmail ทำเครื่องหมายอีเมลว่าเป็นสแปมหรือตีกลับ ให้เปิดข้อความใน Gmail เลือก "Show original" แล้วอ่านผลการตรวจสอบสิทธิ์ หากพบ dkim=fail หรือ dkim=none แสดงว่าระเบียน dkim._domainkey TXT ของคุณหายไป, ผิดพลาด หรือยังไม่ถูกเผยแพร่ ให้เผยแพร่ค่าที่แสดงในหน้า ARC/DKIM ใหม่อีกครั้งให้ถูกต้องและรอตามระยะเวลา TTL หากพบ spf=fail แสดงว่าระเบียน SPF/MX ไม่ครอบคลุม IP ของคุณ การทำ Alignment เป็นสิ่งสำคัญที่สุด การตรวจสอบเพียงรายการเดียวที่ไม่ผ่านก็เพียงพอที่จะทำให้อีเมลของคุณถูกจัดเป็นสแปม
ถูกผู้ให้บริการรายใหญ่ปฏิเสธการเชื่อมต่อ ข้อความตีกลับหรือ log ของ Postfix จะแสดงการปฏิเสธ PTR จาก Gmail ดังนี้:
550-5.7.25 [10.0.0.10] The IP address sending this message does not have a PTR
550-5.7.25 record setup, or the corresponding forward DNS entry does not match
550 5.7.25 the sending IP. As a policy, Gmail does not accept messages from IPs
550 5.7.25 with missing PTR records.รหัส 550 5.7.25 หมายถึงไม่มีการตั้งค่า reverse DNS หรือค่าไม่ตรงกัน ให้ตั้งค่า PTR สำหรับ IP ของคุณให้เป็น mail.example.com ที่แผงควบคุมของผู้ให้บริการ (ขั้นตอนที่ 2) ระเบียน Forward (A) และ Reverse (PTR) ต้องตรงกัน และทั้งคู่ต้องระบุชื่อโฮสต์เดียวกับที่ mailcow ใช้แนะนำตัวกับเซิร์ฟเวอร์อื่น
เบราว์เซอร์แสดงคำเตือนเรื่องใบรับรองที่ไม่หายไป คอนเทนเนอร์ acme-mailcow ไม่สามารถรับใบรับรองจริงได้ ให้ตรวจสอบ log ของคอนเทนเนอร์:
sudo docker compose logs acme-mailcow | tail -n 40หากพบข้อความเช่น Cannot validate any hostnames, skipping Let's Encrypt for 1 hour. หรือความล้มเหลวในการทำ challenge แสดงว่าพอร์ต 80 ไม่สามารถเข้าถึงได้จากอินเทอร์เน็ต หรือระเบียน A ไม่ได้ชี้มาที่เซิร์ฟเวอร์นี้ ให้ยืนยันว่า mail.example.com ชี้มาที่เครื่องนี้จริง, เปิดพอร์ต 80 และ 443 ผ่าน firewall ของโฮสต์ และตรวจสอบให้แน่ใจว่าไม่มีบริการอื่นใช้งานพอร์ตเหล่านี้อยู่ หลังจากแก้ไขสาเหตุแล้ว ให้รีสตาร์ทไคลเอนต์ด้วย sudo docker compose restart acme-mailcow แทนการรอระยะเวลา back-off นานหนึ่งชั่วโมง
FAQ
การโฮสต์อีเมลด้วยตนเองคุ้มค่าหรือไม่?
หากคุณต้องการความเป็นเจ้าของข้อมูล, การสร้าง alias ได้ไม่จำกัด และการควบคุมระบบอย่างเต็มรูปแบบ คำตอบคือใช่ mailcow มอบชุดซอฟต์แวร์ระดับมืออาชีพให้คุณในราคาของ VPS หนึ่งเครื่อง แต่การทำให้ส่งอีเมลถึงผู้รับ (deliverability) เป็นภาระที่ต้องดูแลอย่างต่อเนื่อง ทั้งเรื่องชื่อเสียงของ IP, การตั้งค่า DNS และการเฝ้าระวัง blocklist สำหรับอีเมลธุรกิจที่สำคัญมาก ซึ่งการที่อีเมลตกไปอยู่ในโฟลเดอร์สแปมเพียงวันเดียวอาจสร้างความเสียหายได้ การใช้บริการจากผู้ให้บริการ (managed provider) เป็นทางเลือกที่สมเหตุสมผลกว่า ให้เลือกโฮสต์เองเมื่อคุณให้ความสำคัญกับการควบคุมมากกว่าความสะดวกสบาย และพร้อมที่จะดูแลระบบจริง ๆ หากสิ่งที่คุณต้องการคือการย้ายข้อมูลออกจากเซิร์ฟเวอร์ของผู้อื่นโดยไม่ได้เจาะจงว่าเป็นอีเมล ให้เริ่มจากบริการที่ไม่มีปัจจัยเรื่องการส่งถึงผู้รับมาเกี่ยวข้อง เช่น คลังรูปภาพ ซึ่งไม่มีปัญหาเรื่อง deliverability เลย และ การเปรียบเทียบ PhotoPrism กับ Immich ของเรา ได้ครอบคลุมถึงความต้องการ RAM ขั้นต่ำและคำสั่งสำรองข้อมูลสำหรับการติดตั้งบน VPS ประเภทเดียวกัน
ฉันจะทราบได้อย่างไรว่าพอร์ต 25 ขาออกถูกบล็อก?
ให้รันคำสั่ง nc -vz -w 5 gmail-smtp-in.l.google.com 25 จากเซิร์ฟเวอร์ หากผลลัพธ์แสดง "succeeded!" หมายความว่าพอร์ตเปิดอยู่ แต่ถ้าขึ้น timed out หลังจากหยุดรอไปสักพัก แสดงว่าผู้ให้บริการของคุณบล็อกพอร์ตนี้ไว้ นี่เป็นสาเหตุที่พบบ่อยที่สุดที่ทำให้เซิร์ฟเวอร์ที่โฮสต์เองรับอีเมลได้แต่ส่งออกไม่ได้ และวิธีแก้ไขเพียงวิธีเดียวคือการขอให้ผู้ให้บริการเปิดพอร์ตให้ ไม่มีการตั้งค่าใดในเครื่องที่จะแก้ไขปัญหานี้ได้
ทำไมอีเมลของฉันยังคงไปอยู่ในโฟลเดอร์สแปมของ Gmail?
เกือบทั้งหมดเกิดจากห่วงโซ่การยืนยันตัวตนที่ผิดพลาด ให้ใช้ฟังก์ชัน "Show original" ใน Gmail แล้วตรวจสอบค่า spf=pass, dkim=pass และ dmarc=pass หากค่า dkim=fail แสดงสถานะผิดพลาด มักหมายถึงระเบียน TXT ของ dkim._domainkey หายไปหรือผิดรูปแบบ นอกจากนี้การที่ PTR ไม่ตรงกันหรือการใช้ IP ใหม่ที่ไม่มีประวัติการส่งอีเมลก็ส่งผลเสียเช่นกัน ให้ทดสอบผ่าน mail-tester.com จนได้คะแนน 10/10 ก่อน จากนั้นค่อย ๆ สร้างความน่าเชื่อถือให้ IP โดยเริ่มจากส่งอีเมลเพียงไม่กี่ฉบับต่อวันแล้วค่อยเพิ่มจำนวนขึ้น แทนการส่งอีเมลจำนวนมากตั้งแต่วันแรก
ฉันจำเป็นต้องสำรองข้อมูลส่วนใดบ้าง?
ให้รันคำสั่ง backup_and_restore.sh backup all และเก็บข้อมูลทั้งหมดไว้ภายนอกเซิร์ฟเวอร์ ข้อมูลนี้จะครอบคลุม vmail (กล่องจดหมาย), crypt (คีย์สำหรับถอดรหัส), ฐานข้อมูล MariaDB (โดเมน, ผู้ใช้, alias, การตั้งค่า), Redis, ข้อมูลที่ Rspamd เรียนรู้ และคิวของ Postfix ข้อมูลในส่วน crypt คือสิ่งที่คนมักมองข้าม หากไม่มีส่วนนี้ ข้อมูลสำรองของ vmail จะเป็นเพียงข้อความเข้ารหัสที่อ่านไม่ได้ ให้ทดสอบการกู้คืนข้อมูลบนเซิร์ฟเวอร์สำรองอย่างน้อยหนึ่งครั้ง
ฉันสามารถรัน mailcow บน VPS ขนาด 2 GB ได้หรือไม่?
ไม่แนะนำให้ทำอย่างยิ่ง generate_config.sh จะเสนอให้ปิดการทำงานของ ClamAV หากหน่วยความจำมีน้อยกว่าประมาณ 2.5 GiB แต่ถึงอย่างนั้น Rspamd, ClamAV, Dovecot และ MariaDB ก็ยังคงแย่งทรัพยากรหน่วยความจำกันอยู่ดี ซึ่งจะทำให้ระบบต้องใช้ swap และเกิดปัญหา OOM kill เมื่อมีโหลดการใช้งานจริง ควรใช้ RAM ขนาด 6 GiB พร้อม swap 1 GiB เป็นขั้นต่ำสำหรับการติดตั้งใช้งานคนเดียว และขยับไปที่ 8 GiB ทันทีที่มีผู้ใช้งานมากกว่าสองคนขึ้นไป