วิธีติดตั้ง Mailcow บน VPS ให้ส่งอีเมลถึง Gmail ได้จริง
ตรวจสอบพอร์ต 25 บน VPS ก่อนติดตั้ง Mailcow เพราะหากถูกบล็อกอีเมลจะค้างในคิว เรียนรู้วิธีตั้งค่า DNS และ PTR record เพื่อป้องกันข้อผิดพลาด 550 5.7.25 จาก 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-host ในปี 2026 ของเรา ได้จัดหมวดหมู่อีเมลไว้ในกลุ่ม "เฉพาะเมื่อคุณตั้งใจจริงเท่านั้น" ด้วยเหตุผลเหล่านี้โดยเฉพาะ
ข้อกำหนดเบื้องต้นคือหัวใจสำคัญของโปรเจกต์
หากพลาดข้อใดข้อหนึ่งไป อีเมลที่คุณส่งจะไม่มีวันถึงผู้รับ ต่อไปนี้คือรายการตามลำดับความถี่ที่มักทำให้ผู้ใช้งานประสบปัญหา:
ต้องเปิดพอร์ต 25 สำหรับขาออก เซิร์ฟเวอร์ของคุณต้องส่งอีเมลไปยัง Gmail และ Microsoft ผ่าน TCP พอร์ต 25 ผู้ให้บริการ VPS และ Cloud จำนวนมากบล็อกพอร์ต 25 ขาออกไว้เป็นค่าเริ่มต้นเพื่อป้องกันสแปม การบล็อกนี้จะไม่มีการแจ้งเตือน ไม่มีข้อผิดพลาดขณะบูต ทุกอย่างดูปกติ แต่เมลจะค้างอยู่ในคิวจนกว่า Postfix จะยอมแพ้และตีกลับ (mailcow กำหนดอายุสูงสุดของคิวไว้ที่ 5 วัน) ให้ทดสอบพอร์ตนี้ก่อนติดตั้งซอฟต์แวร์ใดๆ หากถูกบล็อก วิธีแก้ไขเดียวคือการเปิดตั๋วสนับสนุน (support ticket) เพื่อขอให้ผู้ให้บริการเปิดพอร์ตให้ ผู้ให้บริการบางรายอาจเปิดให้สำหรับบัญชีที่ใช้งานมานาน แต่บางรายอาจไม่เปิดให้เลย
IP ต้องสะอาดและมีชื่อเสียงที่ใช้งานได้ IP ของ VPS ที่นำกลับมาใช้ใหม่มักติดอยู่ในบัญชีดำ (blocklist) จากการใช้งานสแปมของผู้เช่ารายก่อนหน้า ให้ตรวจสอบ IP ของคุณผ่านบริการอย่าง Spamhaus lookup หรือ mxtoolbox ก่อนเริ่มดำเนินการ หาก IP ติดบัญชีดำ คุณจะถูกปฏิเสธการส่งเมลโดยไม่สามารถแก้ไขได้ด้วยการเขียนโค้ด
การควบคุม DNS และระเบียน PTR ที่ถูกต้อง คุณต้องเพิ่มระเบียนลงในโซนของโดเมน และต้องตั้งค่า reverse DNS (PTR) สำหรับ IP ของเซิร์ฟเวอร์ให้ชี้กลับมายัง hostname ของเมลคุณ โดยปกติแล้ว PTR จะไม่สามารถตั้งค่าในแผงควบคุม DNS ของคุณได้ แต่จะอยู่ในแผงควบคุมของผู้ให้บริการ 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 คอนเทนเนอร์ พื้นที่ดิสก์ขั้นต่ำที่ mailcow ระบุไว้คือ 20 GiB ก่อนที่จะมีการจัดเก็บอีเมลใดๆ ดังนั้นควรเตรียมพื้นที่ให้มากกว่านี้ตั้งแต่เริ่มต้นเพื่อให้มีที่ว่างสำหรับกล่องจดหมายที่ขยายตัวในอนาคต
ต้องเป็นชื่อ 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บน VPS เครื่องใหม่ที่ไม่มีการตั้งค่า firewall ขาออกด้วยตนเอง การหมดเวลา (timeout) ดังกล่าวเกิดจากการบล็อกของผู้ให้บริการ นี่เป็นตัวกรองเครือข่ายฝั่งผู้ให้บริการ ไม่ใช่ firewall ของคุณ ดังนั้นการแก้ไขในเครื่องจึงไม่ช่วยอะไร ให้เปิด 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 เวอร์ชัน 24.0 หรือใหม่กว่า และ Docker Compose เวอร์ชัน 2.0 หรือใหม่กว่า การใช้ Compose plugin (docker compose) เป็นวิธีที่ง่ายที่สุด แม้ว่า mailcow จะรองรับไฟล์ไบนารี docker-compose แบบ standalone ด้วยก็ตาม ให้ใช้สคริปต์อำนวยความสะดวกอย่างเป็นทางการของ Docker แทนแพ็กเกจ docker.io ของ Ubuntu ซึ่งไม่มี Compose plugin มาให้เลย:
curl -fsSL https://get.docker.com | sudo sh
sudo docker compose versionคุณควรเห็นบรรทัด Docker Compose version ที่รายงานเวอร์ชัน v2.x หรือ v5.x โดย Compose v5 ซึ่งเปิดตัวในปี 2025 นั้นมีฟังก์ชันการทำงานเหมือนกับ v2 ทุกประการ และทั้งสองเวอร์ชันสามารถใช้งานกับ mailcow ได้ หาก docker compose version แสดงผลเป็น docker: 'compose' is not a docker command หมายความว่ามีการติดตั้ง Docker Engine แล้วแต่ยังไม่มี Compose plugin ให้ติดตั้งปลั๊กอินจาก 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 ซึ่งกำหนดค่า umask 0022 ก่อนทำการโคลน ไม่มีส่วนใดใน mailcow ที่ทดสอบค่านี้ และ 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 จะใช้ HTTP-01 challenge ซึ่งจำเป็นต้องเข้าถึงพอร์ต 80 จากอินเทอร์เน็ตได้เพื่อขอรับ certificate (mailcow เวอร์ชัน 2026-03 เป็นต้นไปสามารถใช้ DNS-01 challenge แทนได้ด้วย ACME_DNS_CHALLENGE=y ซึ่งไม่จำเป็นต้องใช้พอร์ต 80 แต่ต้องมีการเข้าถึง API ของผู้ให้บริการ DNS ของคุณ) นี่คือเหตุผลที่การตั้งค่าแบบเรียบง่ายไม่ใช้ การตั้งค่า nginx-plus-Certbot แยกต่างหาก บนเครื่องเดียวกัน เพราะ mailcow จะออกและต่ออายุ TLS ของตนเองภายใน หากมีบริการที่สองมาแย่งใช้พอร์ต 80/443 จะทำให้ระบบทำงานผิดพลาด mailcow มีเอกสารระบุทางเลือกอื่นไว้ คือการผูก web listener ไว้กับ localhost ด้วย HTTP_BIND=127.0.0.1 HTTP_PORT=8080 HTTPS_BIND=127.0.0.1 HTTPS_PORT=8443 แล้วใช้ reverse proxy บนพอร์ต 80 และ 443 แทน หากคุณต้องการให้ Certbot ในเครื่องเป็นผู้จัดการ certificate ก็สามารถชี้ mailcow ไปยังไฟล์เหล่านั้นและเพิ่ม renewal hook ได้ วิธีนี้จะเพิ่มความซับซ้อนให้กับเมลเซิร์ฟเวอร์ ดังนั้นข้อควรพิจารณานี้จึงใช้กับบริการอื่นที่ต้องการหน้าเว็บสาธารณะเช่นกัน เช่น การสร้าง Halcyon ที่ปรับโฉม Jellyfin ให้เป็นร้านวิดีโอในยุค 90 ซึ่งต้องการ reverse proxy ของตนเองบนพอร์ต 443 บริการเหล่านี้ควรอยู่บนโฮสต์อื่น เว้นแต่คุณจะย้าย mailcow ไปไว้หลัง proxy นั้น ข้อยกเว้นคือบริการที่ไม่ต้องการพอร์ตเว็บสาธารณะเลย เช่น RustDesk relay ที่โฮสต์เอง ซึ่งจะฟังเฉพาะช่วงพอร์ต 21115 ถึง 21119 ของตนเองเท่านั้น จึงสามารถใช้เครื่องร่วมกับบริการอื่นได้หากคุณมีแบนด์วิดท์เหลือเพียงพอ
ขั้นตอนที่ 5 เริ่มการทำงานของ stack และเข้าสู่ระบบ
sudo docker compose pull
sudo docker compose up -d
sudo docker compose psคำสั่ง pull จะดึง image ประมาณสองโหล โปรดรอสักครู่ เมื่อ docker compose ps แสดงสถานะคอนเทนเนอร์ทุกตัวเป็น running (หรือ healthy) ให้เปิด https://mail.example.com/admin ในเบราว์เซอร์ ชื่อผู้ใช้เริ่มต้นสำหรับผู้ดูแลระบบคือ admin และรหัสผ่านคือ moohoo ให้เปลี่ยนรหัสผ่านทันทีในหน้า UI ผู้ดูแลระบบที่เมนู System → Configuration จากนั้นไปที่ Access → Administrators หากเบราว์เซอร์แจ้งเตือน NET::ERR_CERT_AUTHORITY_INVALID แสดงว่า ACME certificate ยังไม่ออก ให้ดูหัวข้อความล้มเหลวของ ACME ด้านล่างก่อนที่จะสรุปว่าระบบมีปัญหา การใช้ certificate แบบ self-signed ชั่วคราวเป็นเรื่องปกติในช่วง 1-2 นาทีแรก
ขั้นตอนที่ 6 เพิ่มโดเมน, กล่องจดหมาย และเผยแพร่ DKIM
ในหน้า UI ผู้ดูแลระบบ ให้เปิด E-Mail → Configuration และในแท็บ Domains ให้คลิก Add domain แล้วใส่ example.com จากนั้นในส่วน Mailboxes ให้เลือก Add mailbox เพื่อสร้าง you@example.com พร้อมรหัสผ่าน ซึ่งจะเป็นกล่องจดหมายที่พร้อมใช้งานผ่าน IMAP ทันที
สำหรับคีย์ DKIM ให้ไปที่ System → Configuration จากนั้นไปที่ Options → 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 ทั้งหมดที่ระบบต้องการ พร้อมเครื่องหมายถูกสีเขียวหรือกากบาทสีแดงตามสถานะที่เผยแพร่จริง ให้ใช้หน้านี้เป็นรายการตรวจสอบ และทำให้ทุกแถวเป็นสีเขียวทั้งหมดก่อนเริ่มทดสอบการส่งอีเมล หากแถว DKIM เป็นสีแดงหลังจากเผยแพร่แล้ว มักหมายความว่าคีย์ถูกแบ่งส่วนใน TXT ไม่ถูกต้อง เนื่องจากคีย์ขนาด 2048-bit มีความยาวเกินขีดจำกัด 255 ตัวอักษรสำหรับสตริง 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 เป็นเวลาสูงสุด 5 วันก่อนที่ Postfix จะตีกลับ (bounce) พร้อมข้อความ:
status=deferred (connect to gmail-smtp-in.l.google.com[142.250.x.x]:25: Connection timed out)ปัญหานี้มักเกิดจากการที่ผู้ให้บริการบล็อกพอร์ต 25 ขาออก (ขั้นตอนที่ 1) กฎ firewall บนโฮสต์ของคุณเองก็อาจทำให้เกิด timeout ในลักษณะเดียวกันได้ ดังนั้นให้ตรวจสอบกฎ firewall ก่อน หากโฮสต์ไม่มีปัญหา การแก้ไข config ก็ไม่ช่วยอะไร ให้เปิด 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 ไม่ได้ชี้มาที่เซิร์ฟเวอร์นี้ หากคุณเผยแพร่ระเบียน AAAA ให้ตรวจสอบด้วยเช่นกัน เนื่องจาก mailcow จะตรวจสอบเทียบกับระเบียน AAAA ก่อนและข้ามการตรวจสอบ A หากมีระเบียน AAAA อยู่ ดังนั้นหากระเบียน AAAA ผิดพลาดหรือเส้นทาง IPv6 ไม่สามารถเข้าถึงพอร์ต 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 หลังจากหยุดรอไปสักพัก แสดงว่าพอร์ตถูกบล็อก และหากคุณไม่ได้ตั้งค่า firewall ขาออกไว้เอง แสดงว่าเป็นที่ผู้ให้บริการของคุณ นี่คือสาเหตุที่พบบ่อยที่สุดที่ทำให้เซิร์ฟเวอร์ที่โฮสต์เองรับเมลได้แต่ส่งออกไม่ได้ และวิธีแก้ไขเดียวสำหรับกรณีที่ผู้ให้บริการบล็อกคือการขอให้ผู้ให้บริการเปิดพอร์ตให้ ไม่มีการตั้งค่าในเครื่องใดที่จะแก้ไขปัญหานี้ได้
ทำไมเมลของฉันยังไปอยู่ในโฟลเดอร์สแปมของ Gmail?
เกือบทั้งหมดเกิดจากห่วงโซ่การยืนยันตัวตนที่ผิดพลาด ให้ใช้ฟีเจอร์ "Show original" ใน Gmail แล้วตรวจสอบ spf=pass, dkim=pass และ dmarc=pass หากขึ้น dkim=fail แสดงว่า record TXT ของ dkim._domainkey หายไปหรือผิดพลาด นอกจากนี้ การที่ PTR ไม่ตรงกันหรือ IP ใหม่ที่ไม่มีประวัติการส่งเมลก็ส่งผลเสียเช่นกัน ให้ใช้บริการ mail-tester.com เพื่อปรับแต่งจนได้คะแนน 10/10 ก่อน จากนั้นค่อย ๆ สร้างความน่าเชื่อถือของ IP โดยเริ่มจากส่งเมลเพียงไม่กี่ฉบับต่อวันแล้วค่อย ๆ เพิ่มปริมาณขึ้น แทนที่จะส่งเมลจำนวนมากตั้งแต่วันแรก
ฉันจำเป็นต้องสำรองข้อมูลส่วนใดบ้าง?
ให้รัน backup_and_restore.sh backup all และเก็บข้อมูลทั้งหมดไว้นอกเซิร์ฟเวอร์ ข้อมูลนี้จะครอบคลุม vmail (กล่องจดหมาย), crypt (กุญแจสำหรับถอดรหัส), ฐานข้อมูล MariaDB (โดเมน, ผู้ใช้, alias, การตั้งค่า), Redis, ข้อมูลที่ Rspamd เรียนรู้ และคิวของ Postfix โดย volume ของ crypt คือส่วนที่คนมักมองข้าม หากไม่มีส่วนนี้ ข้อมูลสำรองของ vmail จะเป็นเพียง ciphertext ที่อ่านไม่ออก ให้ทดสอบการกู้คืนข้อมูลบนเซิร์ฟเวอร์สำรองอย่างน้อยหนึ่งครั้ง
ฉันสามารถรัน mailcow บน VPS ขนาด 2 GB ได้หรือไม่?
ไม่แนะนำให้ทำอย่างยิ่ง generate_config.sh มีตัวเลือกให้ปิดการทำงานของ ClamAV หาก RAM ต่ำกว่าประมาณ 2.5 GiB แต่ถึงแม้จะปิด ClamAV ไปแล้ว Rspamd, Dovecot, MariaDB และส่วนประกอบอื่น ๆ ก็ยังคงแย่งชิงหน่วยความจำกันอยู่ดี ซึ่งจะทำให้ระบบต้องใช้ swap และเกิดปัญหา OOM kill เมื่อมีโหลดการใช้งานจริง ให้ถือว่า 6 GiB พร้อม swap 1 GiB เป็นค่ามาตรฐานขั้นต่ำสำหรับการติดตั้งใช้งานคนเดียว และควรขยับไปใช้ 8 GiB ทันทีที่มีผู้ใช้งานมากกว่าสองคนขึ้นไป