วิธีติดตั้งและดูแล Matrix Synapse บน VPS ให้เสถียร
เรียนรู้วิธีดูแล Matrix Synapse บน Ubuntu 24.04 ให้ทำงานได้ต่อเนื่อง ทั้งการตั้งค่า Postgres, การจัดการ Media Store, การป้องกัน Registration และการสำรองข้อมูลที่จำเป็น
สิ่งที่จำเป็นในการดูแลรักษา Matrix Synapse homeserver ให้ทำงานได้อย่างต่อเนื่อง
การติดตั้ง Matrix Synapse นั้นทำได้ง่าย แต่ก็มักถูกละเลยได้ง่ายเช่นกัน การติดตั้งประกอบด้วย apt repository หนึ่งรายการ, ไฟล์ config หนึ่งไฟล์, reverse proxy block หนึ่งรายการ และ DNS record หนึ่งรายการ แต่การดูแลรักษา homeserver ให้มีสถานะสมบูรณ์ตลอดระยะเวลาหนึ่งปีนั้นเป็นงานที่แตกต่างออกไป ซึ่งต้องอาศัยฐานข้อมูลจริง, การจัดการ media store ที่มีการลบข้อมูลเก่าออก, การตั้งค่าการลงทะเบียนที่ป้องกันไม่ให้บุคคลภายนอกเข้ามาใช้งานได้ รวมถึงการสำรองข้อมูลที่ครอบคลุมทั้งสองส่วนของเซิร์ฟเวอร์
คู่มือนี้มุ่งเน้นไปที่ Ubuntu 24.04 LTS และติดตั้ง Synapse จาก apt repository ของ matrix.org ซึ่งเป็นแหล่งแพ็กเกจที่โครงการ Synapse ดูแลรักษาสำหรับ Debian และ Ubuntu เวอร์ชันของแพ็กเกจมีการเปลี่ยนแปลงทุกสองสามสัปดาห์ จึงไม่มีการระบุเลขเวอร์ชันไว้ในที่นี้ เส้นทาง (path) และตัวเลือกทั้งหมดที่ระบุด้านล่างอ้างอิงมาจากเอกสารประกอบปัจจุบันของ Synapse
การประเมินขนาด: สิ่งที่คุณได้รับจริงจาก 1 vCPU และ 2 GB RAM
หน้าเพจแนะนำขนาดที่เผยแพร่ ณ เดือนสิงหาคม 2026 มักระบุว่า Synapse homeserver สามารถทำงานได้บน 1 vCPU และ 2 GB RAM ซึ่งเป็นข้อมูลที่ถูกต้องสำหรับกรณีเดียวคือ: เซิร์ฟเวอร์ส่วนตัวที่มีผู้ใช้จำนวนน้อย ห้องแชทขนาดเล็ก และไม่มีการเข้าร่วมห้องสาธารณะที่มีกิจกรรมหนาแน่น เอกสารของ Synapse ระบุไว้อย่างชัดเจนสำหรับกรณีอื่น โดยระบุว่า "ต้องการ RAM ว่างอย่างน้อย 1GB หากคุณต้องการเข้าร่วมห้องสาธารณะขนาดใหญ่ เช่น #matrix:matrix.org" ซึ่งเป็น RAM ว่างที่ต้องมีนอกเหนือจากที่ Python, Postgres และ kernel ใช้งานอยู่
ห้องแชทเพียงห้องเดียวสามารถเปลี่ยนความต้องการด้านขนาดของคุณได้ เนื่องจากวิธีการทำงานของการเข้าร่วมห้อง เมื่อผู้ใช้ในเครื่องเข้าร่วมห้อง homeserver ของคุณจะกลายเป็นผู้เข้าร่วมเต็มตัวในห้องนั้น มันจะได้รับทุกเหตุการณ์ (event) จากทุกเซิร์ฟเวอร์ในห้องนั้น ตรวจสอบลายเซ็นของแต่ละเหตุการณ์ และจัดเก็บสถานะของห้องไว้ในเครื่อง ห้องสาธารณะขนาดใหญ่มีสมาชิกหลายพันคนกระจายอยู่บนเซิร์ฟเวอร์หลายร้อยแห่ง ดังนั้นเซิร์ฟเวอร์ของคุณจึงต้องทำงานเหล่านี้อย่างต่อเนื่องไม่ว่าผู้ใช้ของคุณจะเปิดห้องนั้นอีกหรือไม่ก็ตาม การออกจากห้องในภายหลังจะไม่ลบประวัติที่คุณจัดเก็บไว้แล้ว
RAM ส่วนใหญ่ของ Synapse ถูกใช้ไปกับแคช ส่วน caches มี global_factor ที่ช่วยปรับขนาดแคชทั้งหมดพร้อมกัน และตัวแปรสภาพแวดล้อม SYNAPSE_CACHE_FACTOR ก็ทำหน้าที่เดียวกัน การเพิ่มค่านี้เป็นการใช้ RAM เพื่อลดการสืบค้นฐานข้อมูล การลดค่านี้เป็นการใช้ CPU และเวลาของ Postgres เพื่อประหยัด RAM ในขณะที่ Postgres เองก็ต้องการหน่วยความจำเช่นกัน ดังนั้นบนเครื่องขนาด 2 GB ทั้งสองส่วนนี้จึงต้องแย่งชิงหน่วยความจำชุดเดียวกัน
กฎปฏิบัติสองข้อสำหรับแผนการใช้งานขนาดเล็ก: ให้เพิ่ม swap แม้ว่า swap จะไม่ทำให้ Synapse ทำงานเร็วขึ้น แต่มันช่วยป้องกันไม่ให้ kernel สั่งยุติกระบวนการทำงาน (kill) ในระหว่างการเข้าร่วมห้องขนาดใหญ่ จากนั้นให้เฝ้าดูพื้นที่ดิสก์ตั้งแต่สัปดาห์แรก เพราะสิ่งที่เติบโตโดยไม่มีขีดจำกัดคือ media store และตารางสถานะของห้อง ซึ่งทั้งสองอย่างนี้จัดเก็บอยู่บนดิสก์
เหตุผลที่ต้องใช้ Postgres และทำไม SQLite ถึงไม่ใช่ตัวเลือกอีกต่อไป
แพ็กเกจ Debian เริ่มต้นด้วย SQLite ซึ่งเพียงพอสำหรับการบูตครั้งแรก แต่ไม่เหมาะสมสำหรับเซิร์ฟเวอร์ที่มีผู้ใช้งานหลายคน SQLite อนุญาตให้เขียนข้อมูลได้ทีละหนึ่งรายการเท่านั้น ในขณะที่ทราฟฟิกจาก Federation และคำขอจากไคลเอนต์มักจะเขียนข้อมูลพร้อมกัน ส่งผลให้คำขอที่ใช้ทรัพยากรน้อยต้องรอคำขอที่ทำงานช้ากว่า อาการที่ผู้ใช้ของคุณจะพบคือแอปพลิเคชันค้างเป็นระยะเวลาสั้นๆ โดยไม่ทราบสาเหตุ
เหตุผลประการที่สองคือเรื่องโครงสร้าง กระบวนการทำงานแบบ worker ของ Synapse เป็นวิธีที่รองรับการใช้งาน CPU มากกว่าหนึ่งคอร์ และ worker เหล่านี้จำเป็นต้องใช้ Postgres การคงไว้ที่ SQLite จะทำให้คุณเสียโอกาสในการอัปเกรดระบบและประสิทธิภาพการทำงานไป
การย้ายฐานข้อมูลในภายหลังสามารถทำได้แต่ต้องมีการหยุดให้บริการ (downtime) ดังนั้นควรดำเนินการก่อนที่จะมีผู้ใช้งานจริง Synapse มาพร้อมกับ synapse_port_db ซึ่งทำหน้าที่คัดลอกฐานข้อมูลจาก SQLite ไปยังฐานข้อมูล Postgres ที่เตรียมไว้:
synapse_port_db --sqlite-database homeserver.db --postgres-config homeserver-postgres.yamlหากคุณต้องการรันฐานข้อมูลในคอนเทนเนอร์ควบคู่ไปกับ Synapse คุณสามารถพิจารณาข้อดีข้อเสียได้ที่ การรันฐานข้อมูลใน Docker หรือบนโฮสต์
การติดตั้ง Synapse บน Ubuntu 24.04
sudo apt install -y lsb-release wget apt-transport-https
sudo wget -O /usr/share/keyrings/matrix-org-archive-keyring.gpg https://packages.matrix.org/debian/matrix-org-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/matrix-org-archive-keyring.gpg] https://packages.matrix.org/debian/ $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/matrix-org.list
sudo apt update
sudo apt install matrix-synapse-py3บน Ubuntu 24.04 lsb_release -cs จะแสดงผลเป็น noble และ repository ของ matrix.org ก็ได้เผยแพร่ชุด noble ออกมา ห้ามใช้แพ็กเกจ matrix-synapse จากคลังซอฟต์แวร์หลักของ Ubuntu โดยเด็ดขาด เนื่องจากโครงการ Synapse ขอความร่วมมือไม่ให้ใช้งาน เพราะเวอร์ชันดังกล่าวล้าหลังกว่า releases ปัจจุบันและมีช่องโหว่ด้านความปลอดภัยที่ทราบกันดี
ตัวติดตั้งจะสอบถามชื่อเซิร์ฟเวอร์และบันทึกคำตอบลงใน /etc/matrix-synapse/conf.d/server_name.yaml โปรดตอบคำถามนี้อย่างระมัดระวัง server_name คือส่วนที่อยู่หลังเครื่องหมายโคลอนในทุก User ID (@alice:example.com) และจะถูกฝังอยู่ในทุกห้องที่เซิร์ฟเวอร์ของคุณสร้างขึ้น การเปลี่ยนชื่อในภายหลังจะไม่ย้ายข้อมูลใดๆ แต่จะเป็นการสร้าง homeserver ใหม่ขึ้นมาแทน ให้ใช้ชื่อโดเมนหลักของคุณคือ example.com แม้ว่าตัว Synapse เองจะรันอยู่บน matrix.example.com ก็ตาม การทำ Delegation จะเชื่อมโยงทั้งสองส่วนเข้าด้วยกัน ซึ่งเป็นเนื้อหาในส่วนถัดไป
แพ็กเกจนี้จะรัน Synapse ในฐานะผู้ใช้ matrix-synapse โดยเก็บข้อมูลไว้ภายใต้ /var/lib/matrix-synapse และอ่านค่าจาก /etc/matrix-synapse/homeserver.yaml ตามด้วยไฟล์ทั้งหมดใน /etc/matrix-synapse/conf.d/ ให้คุณใส่การตั้งค่าของคุณเองลงในไฟล์ขนาดเล็กภายใน conf.d ซึ่งการอัปเกรดแพ็กเกจจะไม่ส่งผลกระทบต่อไฟล์เหล่านี้
sudo systemctl restart matrix-synapse
systemctl status matrix-synapse
sudo journalctl -u matrix-synapse -n 100 --no-pagerการเริ่มต้นที่สมบูรณ์จะทำให้ listener ทำงานขึ้นมาแล้วเข้าสู่สถานะปกติ หน่วยของ systemd จะรีสตาร์ทบริการใหม่หลังจากหยุดทำงานไปไม่กี่วินาที ดังนั้นหาก Synapse ปฏิเสธการตั้งค่าใดๆ จะเห็นว่า unit เริ่มทำงานแล้วดับวนไปเรื่อยๆ บรรทัดสุดท้ายของ journal จะระบุชื่อคีย์ที่ถูกปฏิเสธ
การตั้งค่า Synapse ให้เชื่อมต่อกับ Postgres
sudo apt install -y postgresql
sudo -u postgres createuser --pwprompt synapse_user
sudo -u postgres createdb --encoding=UTF8 --locale=C --template=template0 --owner=synapse_user synapseค่า locale ไม่ใช่เรื่องของความสวยงาม Synapse จะปฏิเสธการทำงานหากฐานข้อมูลถูกสร้างด้วยค่า COLLATE และ CTYPE ที่ไม่ตรงกัน เว้นแต่คุณจะตั้งค่า allow_unsafe_locale ไว้ในไฟล์คอนฟิกของฐานข้อมูล ซึ่งวิธีการแก้ไขที่ระบุไว้ในเอกสารหลังจากนั้นคือการ dump ข้อมูลออกมาแล้วโหลดเข้าไปใหม่ในฐานข้อมูลที่สร้างขึ้นอย่างถูกต้อง ดังนั้นควรสร้างฐานข้อมูลให้ถูกต้องตั้งแต่แรก
database:
name: psycopg2
txn_limit: 10000
args:
user: synapse_user
password: secretpassword
dbname: synapse
host: localhost
port: 5432
cp_min: 5
cp_max: 10ให้ใช้คีย์ database: เพียงชุดเดียวในไฟล์คอนฟิกทั้งหมดของคุณ ให้แทนที่บล็อก SQLite ภายใน homeserver.yaml แทนการเพิ่มสำเนาชุดที่สองไว้ใต้ conf.d เพื่อไม่ให้เกิดความสับสนว่าบล็อกใดที่กำลังใช้งานอยู่ จากนั้นให้รีสตาร์ทบริการแล้วตรวจสอบว่า Synapse เชื่อมต่อกับ Postgres จริงหรือไม่:
sudo -u postgres psql synapse -c "SELECT count(*) FROM users;"หากปรากฏตัวเลข แสดงว่า Synapse ได้สร้าง schema ในฐานข้อมูลนี้แล้ว หากพบข้อผิดพลาดเกี่ยวกับ missing relation แสดงว่าระบบยังคงเขียนข้อมูลลงในไฟล์ SQLite อยู่ ซึ่งหมายความว่าไฟล์คอนฟิกที่คุณแก้ไขไม่ใช่ไฟล์ที่ระบบกำลังอ่านอยู่
Reverse proxy, TLS และความต้องการไฟล์ .well-known สำหรับ federation
Synapse จะรับฟังการเชื่อมต่อผ่าน HTTP ปกติที่พอร์ต 8008 โดยผูกไว้กับ localhost ส่วนการจัดการ TLS และพอร์ตสาธารณะจะเป็นหน้าที่ของ reverse proxy ที่อยู่ด้านหน้า
listeners:
- port: 8008
tls: false
type: http
x_forwarded: true
bind_addresses:
- '::1'
- '127.0.0.1'
resources:
- names:
- client
- federation
compress: falsex_forwarded: true จะสั่งให้ Synapse เชื่อถือ header X-Forwarded-For ที่ proxy กำหนด หากไม่มีการตั้งค่านี้ ไคลเอนต์ทุกรายจะถูกมองว่ามาจาก 127.0.0.1 ส่งผลให้ระบบ rate limiting มองเห็นผู้ใช้ในเครื่องรายเดียวที่ใช้งานหนักมาก และจำกัดการใช้งานของผู้ใช้ทุกคนพร้อมกัน
location ~ ^(/_matrix|/_synapse/client) {
proxy_pass http://localhost:8008;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host:$server_port;
client_max_body_size 50M;
proxy_http_version 1.1;
}เอกสารของ Synapse มีคำเตือนเกี่ยวกับบล็อกนี้ซึ่งมักทำให้ผู้ใช้เสียเวลาแก้ไขปัญหาหลายวัน ห้ามเพิ่ม path ใดๆ แม้แต่ / ตัวเดียว ต่อท้ายพอร์ตใน proxy_pass เพราะ nginx จะทำการ canonicalize URI ซึ่งจะเปลี่ยนชุดไบต์ที่เซิร์ฟเวอร์ต้นทางได้ลงลายเซ็นไว้ ทำให้คำขอ federation ล้มเหลวในการตรวจสอบลายเซ็น ในขณะที่คำขอจากไคลเอนต์ทั่วไปยังคงทำงานได้ตามปกติ
client_max_body_size ต้องมีขนาดอย่างน้อยเท่ากับ max_upload_size ของ Synapse หาก nginx กำหนดค่าไว้ต่ำกว่านั้น nginx จะปฏิเสธการอัปโหลดที่เกินขนาดด้วย 413 Request Entity Too Large ก่อนที่ Synapse จะได้รับคำขอ ทำให้ไม่มีบรรทัด log ใน Synapse เพื่ออธิบายสาเหตุของความผิดพลาด
สำหรับตัว certificate ให้ปฏิบัติตาม Certbot และ Let's Encrypt บน Ubuntu 24.04 หากยังไม่แน่ใจว่าจะเลือกใช้ proxy ตัวใด การเปรียบเทียบ reverse proxy จะช่วยสรุปว่าตัวใดจัดการงาน TLS ให้คุณได้บ้าง
Delegation คือสิ่งที่ทำให้ server_name ยังคงเป็น example.com ในขณะที่ Synapse ทำงานอยู่บน matrix.example.com คุณต้องให้บริการไฟล์สองไฟล์จากโดเมนหลักดังนี้:
location /.well-known/matrix/server {
default_type application/json;
return 200 '{"m.server": "matrix.example.com:443"}';
}
location /.well-known/matrix/client {
default_type application/json;
add_header Access-Control-Allow-Origin '*';
return 200 '{"m.homeserver": {"base_url": "https://matrix.example.com"}}';
}ไฟล์ server จะแจ้งให้ homeserver อื่นทราบว่าจะต้องส่ง traffic ของ federation ไปที่ใด ซึ่งเป็นวิธีที่ทำให้ federation ทำงานผ่านพอร์ต 443 แทนพอร์ตมาตรฐาน 8448 ส่วนไฟล์ client จะแจ้งให้ Matrix client ทราบว่า URL ใดที่รองรับ @alice:example.com โดย header Access-Control-Allow-Origin มีความสำคัญอย่างยิ่งสำหรับไฟล์ client เนื่องจากไคลเอนต์ที่ทำงานบนเบราว์เซอร์จะดึงข้อมูลแบบ cross-origin หากไม่มี header นี้ เบราว์เซอร์จะบล็อกการตอบกลับและไคลเอนต์จะแจ้งว่าไม่พบ homeserver ของคุณ
ไฟล์ทั้งสองต้องถูกให้บริการผ่าน TLS ที่ถูกต้องจาก example.com โดยตรง ให้ตรวจสอบไฟล์เหล่านั้น แล้วจึงตรวจสอบสิ่งที่โลกภายนอกมองเห็น:
curl -s https://example.com/.well-known/matrix/server
curl -s https://matrix.example.com/_matrix/federation/v1/versionคำสั่งแรกจะส่งคืน JSON ที่คุณเขียนไว้ ส่วนคำสั่งที่สองจะส่งคืนออบเจกต์ JSON ที่ระบุชื่อและเวอร์ชันของซอฟต์แวร์เซิร์ฟเวอร์ ซึ่งเป็นการพิสูจน์ว่า proxy สามารถเข้าถึง Synapse ผ่านเส้นทาง federation ได้ จากนั้นให้ทดสอบโดเมนของคุณผ่าน Matrix federation tester ที่ https://federationtester.matrix.org ซึ่งจะจำลองเส้นทางเดียวกับที่เซิร์ฟเวอร์ระยะไกลใช้งานจริง
จะทำ Federation หรือไม่: ตัดสินใจให้ชัดเจน
Federation คือหัวใจสำคัญของ Matrix และเป็นส่วนที่สร้างภาระงานมากที่สุด Homeserver ที่ทำ Federation จะยอมรับการเชื่อมต่อจากเซิร์ฟเวอร์ที่คุณไม่เคยรู้จัก รับเหตุการณ์ (events) จากเซิร์ฟเวอร์เหล่านั้น แคชสื่อ (media) และจัดเก็บสถานะ (state) สำหรับทุกห้องที่ผู้ใช้ของคุณเข้าไปมีส่วนร่วม นี่คือการตัดสินใจเชิงรูปแบบภัยคุกคาม (threat model) ไม่ใช่ค่าเริ่มต้นที่ควรปล่อยไว้
จงทำ Federation เมื่อผู้ใช้ของคุณจำเป็นต้องติดต่อกับผู้คนบน Homeserver อื่น หรือเมื่อตัวตนที่พกพาได้ (portable identity) คือเหตุผลที่คุณเลือกใช้ Matrix อย่าทำ Federation หากเซิร์ฟเวอร์นั้นมีไว้สำหรับทีมเดียวและทุกบัญชีเป็นของคุณ เซิร์ฟเวอร์แบบปิดจะจัดเก็บข้อมูลน้อยกว่า ได้รับข้อมูลน้อยกว่า และตกเป็นเป้าหมายในการโจมตีได้ยากกว่ามาก
หากต้องการจำกัดการเข้าถึงแทนที่จะปิดการใช้งาน Synapse รองรับการใช้รายการอนุญาต (allow list):
federation_domain_whitelist:
- lon.example.com
- nyc.example.comเอกสารแนะนำให้ตั้งค่า Firewall ปิดกั้น listener สำหรับ Federation ไว้ด้วย เพื่อให้ทราฟฟิกที่ไม่ต้องการถูกหยุดที่ระดับเครือข่ายแทนที่จะเข้ามาถึงภายใน Python หากต้องการปิด Federation โดยสมบูรณ์ ให้ลบ federation ออกจากรายการ resources ของ listener, ไม่ต้องประกาศ /.well-known/matrix/server และปิดพอร์ต 8448 ไว้
หากเหตุผลในการรัน Matrix คือการแชทภายในทีมและ Federation ไม่เคยเป็นส่วนหนึ่งของความต้องการ ให้เปรียบเทียบต้นทุนการรันระบบกับ ทางเลือกอื่นแทน Slack ที่โฮสต์เองได้ ก่อนที่คุณจะตัดสินใจใช้ Synapse เพราะ Rocket.Chat บน Docker Compose สามารถรองรับการแชทภายในทีมได้บนเครื่องที่มีสเปกต่ำกว่า เนื่องจากไม่ต้องจัดเก็บสถานะห้องขององค์กรอื่นเลย
ที่เก็บสื่อคือสิ่งที่ทำให้ดิสก์เต็มอย่างเงียบเชียบ
ไฟล์ที่ผู้ใช้ของคุณอัปโหลดจะถูกเก็บไว้ในดิสก์ของคุณอย่างถาวร ส่วนไฟล์ที่ผู้ใช้บน homeserver อื่นโพสต์จะถูกดึงมาและแคชไว้ในดิสก์ของคุณทันทีที่ไคลเอนต์ของคุณแสดงผลไฟล์เหล่านั้น นอกจากนี้ Synapse ยังสร้างภาพตัวอย่าง (thumbnail) สำหรับรูปภาพ ทำให้รูปภาพหนึ่งรูปกลายเป็นไฟล์หลายไฟล์ โดยปกติแล้วไม่มีกระบวนการใดที่ลบไฟล์เหล่านี้โดยอัตโนมัติ
ค้นหาที่เก็บข้อมูลและตรวจสอบขนาด:
grep media_store_path /etc/matrix-synapse/homeserver.yaml
sudo du -sh /var/lib/matrix-synapse/media_storeตรวจสอบ path ที่ config ของคุณระบุไว้ แพ็กเกจ Debian จะเก็บข้อมูลของ Synapse ไว้ภายใต้ /var/lib/matrix-synapse ดังนั้นที่เก็บข้อมูลจึงมักจะอยู่ที่นั่น จากนั้นให้กำหนดนโยบายการเก็บรักษา (retention policy) ใน conf.d:
media_retention:
local_media_lifetime: 90d
remote_media_lifetime: 14dโปรดอ่านสองบรรทัดนั้นอย่างละเอียด เนื่องจากเป็นการตั้งค่าคนละประเภทกัน remote_media_lifetime จะลบแคชที่หมดอายุ ซึ่งไฟล์ที่ถูกลบไปสามารถดึงกลับมาจากเซิร์ฟเวอร์เจ้าของไฟล์ได้อีกครั้ง ส่วน local_media_lifetime จะลบไฟล์ที่ผู้ใช้ของคุณอัปโหลดทิ้งอย่างถาวรเมื่อไฟล์มีอายุถึงกำหนด ทีมที่แชร์เอกสารในแชทและคาดหวังว่าจะยังคงเปิดดูได้ในปีหน้าจะสูญเสียไฟล์เหล่านั้นไป เซิร์ฟเวอร์จำนวนมากจึงตั้งค่าเฉพาะค่าสำหรับสื่อจากระยะไกลเท่านั้น
สำหรับการล้างข้อมูลแบบครั้งเดียว ผู้ดูแลระบบสามารถใช้ Admin API โดยระบุ Unix timestamp ในหน่วยมิลลิวินาที:
BEFORE_TS=$(date -d '30 days ago' +%s%3N)
curl -X POST -H "Authorization: Bearer $ADMIN_TOKEN" \
"https://matrix.example.com/_synapse/admin/v1/purge_media_cache?before_ts=$BEFORE_TS"POST /_synapse/admin/v1/purge_media_cache จะลบสื่อจากระยะไกลที่ถูกแคชไว้ซึ่งมีการเข้าถึงครั้งล่าสุดก่อน timestamp นั้น ส่วน POST /_synapse/admin/v1/media/delete?before_ts=<ms> จะลบสื่อในเครื่องตามกฎเดียวกัน ให้รันคำสั่งล้างข้อมูลสื่อจากระยะไกลก่อนแล้วจึงวัดขนาดดิสก์อีกครั้ง เนื่องจากบนเซิร์ฟเวอร์ที่มีการทำ federation แคชของสื่อจากระยะไกลมักจะมีขนาดใหญ่กว่าครึ่งหนึ่งของพื้นที่ทั้งหมด
การตั้งค่าสองรายการนี้ส่งผลต่อดิสก์ในลักษณะเดียวกัน max_upload_size จะจำกัดขนาดการอัปโหลดต่อหนึ่งไฟล์และต้องตั้งค่าให้สอดคล้องกับ client_max_body_size ใน nginx ส่วน url_preview_enabled: true จะทำให้เซิร์ฟเวอร์ของคุณดึงหน้าเว็บจากระยะไกลเพื่อให้ไคลเอนต์แสดงตัวอย่างลิงก์ได้ ซึ่งจะใช้แบนด์วิดท์และจัดเก็บภาพตัวอย่างของเนื้อหาที่ไม่มีใครอัปโหลดให้คุณโดยตรง
ปิดการลงทะเบียนก่อนที่จะมีคนพบ homeserver ของคุณ
เครื่องมือสแกนจะพบ homeserver ที่เปิดใช้งานอยู่ภายในเวลาไม่กี่วัน หากปล่อยให้สร้างบัญชีได้อย่างอิสระ เซิร์ฟเวอร์ของคุณจะกลายเป็นแหล่งกระจายสแปมในทุกห้องที่เชื่อมต่อ (federate) และผู้ดูแลระบบของเซิร์ฟเวอร์อื่นจะบล็อกโดเมนของคุณทั้งหมด ความเสียหายต่อชื่อเสียงนี้จะคงอยู่ยาวนานกว่าการล้างข้อมูล เพราะรายการบล็อกส่วนใหญ่ถูกจัดการด้วยมือ
Synapse ถูกตั้งค่ามาให้ปิดการลงทะเบียนไว้ตั้งแต่ต้น enable_registration มีค่าเริ่มต้นเป็น false และ registration_requires_token มีค่าเริ่มต้นเป็น false นอกจากนี้ Synapse จะปฏิเสธการเริ่มทำงานหากเปิดใช้งานการลงทะเบียนโดยไม่มีขั้นตอนการยืนยันตัวตน เว้นแต่คุณจะตั้งค่า enable_registration_without_verification: true เพิ่มเติม การปฏิเสธนี้เป็นความตั้งใจของผู้พัฒนา ดังนั้นอย่าเปิดใช้งานเพียงเพื่อแก้ไขข้อผิดพลาดขณะเริ่มทำงาน
ให้สร้างบัญชีที่ต้องการด้วยตนเอง:
sudo register_new_matrix_user -c /etc/matrix-synapse/homeserver.yaml http://localhost:8008ระบบจะถามชื่อผู้ใช้ รหัสผ่าน และสิทธิ์การเป็นผู้ดูแลระบบเซิร์ฟเวอร์ คำสั่งนี้จะอ่านค่า registration_shared_secret จากไฟล์คอนฟิกที่คุณระบุผ่าน -c ดังนั้นหากระบบแจ้งว่าไม่พบ shared secret ให้ชี้ -c ไปยังไฟล์ที่เก็บค่าดังกล่าว
เมื่อการสร้างบัญชีด้วยตนเองไม่สามารถรองรับการใช้งานได้อีกต่อไป การใช้ registration token คือทางเลือกที่เหมาะสม token คือสตริงที่ผู้ใช้ใหม่ต้องระบุระหว่างการสมัคร และ token แต่ละรายการสามารถกำหนดขีดจำกัดจำนวนครั้งที่ใช้งานได้:
enable_registration: true
registration_requires_token: truecurl -X POST -H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"uses_allowed": 1}' \
https://matrix.example.com/_synapse/admin/v1/registration_tokens/newหากเว้น token ไว้ในส่วน body ของคำขอ Synapse จะสร้าง token ขึ้นมาให้และส่งกลับมา ส่วน GET /_synapse/admin/v1/registration_tokens จะแสดงรายการ token ที่ยังใช้งานได้อยู่ ทั้งสองคำสั่งจำเป็นต้องใช้ access token ของบัญชีผู้ดูแลระบบ ซึ่งคุณสามารถรับได้จากการล็อกอินด้วยบัญชีผู้ดูแลระบบที่คุณสร้างไว้ก่อนหน้านี้
องค์กรที่มีการจัดการบัญชีผู้ใช้อยู่ที่อื่นแล้วสามารถข้ามการใช้รหัสผ่านภายในไปได้เลย เนื่องจาก Synapse สามารถมอบหมายการล็อกอินให้กับผู้ให้บริการ OIDC (OpenID Connect) ได้ เช่น Authentik ในฐานะผู้ให้บริการ SSO แบบ self-hosted ซึ่งจะช่วยให้การจัดการผู้ใช้ที่เข้าและออกจากระบบทำได้จากจุดเดียว
การสำรองข้อมูลที่สามารถกู้คืนเซิร์ฟเวอร์ได้จริง
การสำรองข้อมูล Synapse ประกอบด้วย 3 ส่วน หากขาดส่วนใดส่วนหนึ่งไป คุณจะไม่สามารถกู้คืนเซิร์ฟเวอร์ให้ใช้งานได้
- ฐานข้อมูล Postgres ซึ่งเก็บเหตุการณ์ บัญชี และห้องทั้งหมด
- ไดเรกทอรี media store ซึ่งเก็บไฟล์ที่อัปโหลดทั้งหมด
/etc/matrix-synapseซึ่งเก็บไฟล์การตั้งค่าและ signing key ของเซิร์ฟเวอร์
Signing key คือส่วนที่ผู้คนมักลืม มันคือ private key ที่ homeserver ของคุณใช้ลงนามในเหตุการณ์ต่างๆ และเซิร์ฟเวอร์ปลายทางจะใช้ public key ที่ตรงกันในการตรวจสอบเหตุการณ์เหล่านั้น ให้รันคำสั่ง grep signing_key_path /etc/matrix-synapse/homeserver.yaml เพื่อดูว่าไฟล์ของคุณอยู่ที่ใด หากทำหาย คุณจะกู้คืนเซิร์ฟเวอร์ที่ไม่มีหลักฐานยืนยันตัวตนว่าเป็นเซิร์ฟเวอร์เดิมที่ห้องต่างๆ รู้จัก
sudo -u postgres pg_dump --format=custom --file=/var/backups/synapse-$(date +%F).dump synapse
sudo tar czf /var/backups/synapse-etc-$(date +%F).tgz -C /etc matrix-synapseให้เริ่มจากการ dump ฐานข้อมูลก่อน แล้วจึงคัดลอก media store เนื่องจากไฟล์สื่อจะถูกเขียนเพียงครั้งเดียวและอ้างอิงด้วย ID ดังนั้นการคัดลอก media store หลังจาก dump ฐานข้อมูลจะมีแต่ไฟล์ที่เพิ่มเข้ามาใหม่โดยไม่มีไฟล์ที่ขาดหายไป หากทำสลับลำดับกัน ฐานข้อมูลที่กู้คืนอาจอ้างอิงไปยังไฟล์ที่การสำรองข้อมูลของคุณไม่ได้จัดเก็บไว้
ส่งข้อมูลทั้ง 3 ส่วนออกจาก VPS restic พร้อม off-site snapshots เหมาะสมกับรูปแบบนี้มาก เนื่องจาก media store เป็นส่วนที่มีขนาดใหญ่และมีการเปลี่ยนแปลงน้อยมากในแต่ละรอบ การทำ deduplication จึงช่วยให้แต่ละ snapshot มีขนาดเล็ก
จากนั้นให้ซ้อมการกู้คืน เพราะการสำรองข้อมูลที่คุณไม่เคยทดสอบกู้คืนถือเป็นเพียงสมมติฐานเท่านั้น ให้สร้าง VPS เครื่องที่สอง ติดตั้งแพ็กเกจเดียวกัน กู้คืนไฟล์การตั้งค่า สร้างฐานข้อมูลด้วย encoding และ locale เดียวกัน ใช้ pg_restore เพื่อนำข้อมูลที่ dump ไว้เข้าสู่ฐานข้อมูล คัดลอก media store กลับมา แล้วลองเข้าสู่ระบบ จดบันทึกว่าใช้เวลานานเท่าใด ตัวเลขนั้นคือระยะเวลาการกู้คืนจริงของคุณ
เมื่อตารางสถานะขยายตัว: การบีบอัดข้อมูล
Synapse จัดเก็บสถานะของห้องไว้ในรูปแบบ state groups และบนเซิร์ฟเวอร์ที่ทำ federation นั้น state_groups_state มักจะกลายเป็นออบเจกต์ที่มีขนาดใหญ่ที่สุดในฐานข้อมูล ให้ทำการวัดผลก่อนที่จะเปลี่ยนแปลงใดๆ:
sudo -u postgres psql synapse -c "SELECT pg_size_pretty(pg_database_size('synapse'));"
sudo -u postgres psql synapse -c "SELECT pg_size_pretty(pg_total_relation_size('state_groups_state'));"หากตารางดังกล่าวเป็นส่วนใหญ่ของฐานข้อมูลของคุณ ทางโครงการได้เผยแพร่เครื่องมือบีบอัดสำหรับตารางนี้คือ rust-synapse-compress-state ซึ่งจะเขียนลำดับชั้นของ state group ใหม่ให้เหลือจำนวนแถวน้อยลงโดยไม่เปลี่ยนแปลงความหมายของสถานะในห้องใดๆ เครื่องมือนี้ถูกสร้างขึ้นด้วย Rust:
sudo apt install -y build-essential libssl-dev pkg-config git
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
git clone https://github.com/matrix-org/rust-synapse-compress-state.git
cd rust-synapse-compress-state/synapse_auto_compressor
cargo build --release./target/release/synapse_auto_compressor -p postgresql://synapse_user:secretpassword@localhost/synapse -c 500 -n 100-c คือจำนวน state groups ที่เครื่องมือประมวลผลในคราวเดียว และ -n คือจำนวนกลุ่มข้อมูล (chunks) ที่การทำงานรอบนี้จะประมวลผล ตัวบีบอัดอัตโนมัติจะบันทึกความคืบหน้าไว้ ทำให้การทำงานรอบถัดไปสามารถดำเนินการต่อจากจุดเดิมได้ ซึ่งเป็นเหตุผลที่ทำให้การตั้งเวลาทำงานมีความปลอดภัย เอกสารประกอบระบุว่าการเปลี่ยนแปลงจะถูกนำไปใช้ในรูปแบบ transaction กับตารางแบบ append-only ดังนั้นจึงสามารถรันในขณะที่ Synapse กำลังทำงานอยู่ได้ อย่างไรก็ตาม ควรสำรองข้อมูลฐานข้อมูลก่อนการรันครั้งแรกเสมอ
มีรายละเอียดของ Postgres หนึ่งประการที่มักทำให้ผู้ใช้ประหลาดใจ การลบแถวข้อมูลจะเป็นการคืนพื้นที่ให้ Postgres นำกลับมาใช้ใหม่ ไม่ใช่การคืนพื้นที่ให้ระบบไฟล์ ดังนั้น df อาจไม่มีขนาดลดลงเลยหลังจากการบีบอัดข้อมูลขนาดใหญ่ VACUUM FULL จะเป็นคำสั่งที่คืนพื้นที่ดังกล่าวให้ระบบไฟล์ โดยคำสั่งนี้จะทำการล็อกตารางแบบ exclusive และต้องใช้พื้นที่ดิสก์ว่างประมาณเท่ากับขนาดของตาราง ดังนั้นควรวางแผนการรันเป็นงานบำรุงรักษา แทนที่จะรันตามอำเภอใจ
การตรวจสอบสถานะความพร้อมของเซิร์ฟเวอร์
systemctl status matrix-synapse
curl -s https://example.com/.well-known/matrix/server
curl -s https://matrix.example.com/_matrix/federation/v1/version
sudo -u postgres psql synapse -c "SELECT pg_size_pretty(pg_database_size('synapse'));"
sudo du -sh /var/lib/matrix-synapse/media_storeสถานะที่ปกติหมายถึง unit ทำงานอยู่และไม่มีการรีสตาร์ทตัวเอง ไฟล์ delegation ส่งค่า m.server ของคุณกลับมาได้ถูกต้อง endpoint ของ federation version ส่งข้อมูลกลับมาเป็น JSON และสามารถเปรียบเทียบตัวเลขขนาดข้อมูลทั้งสองค่ากับของเดือนที่แล้วได้ การตรวจสอบขนาดข้อมูลเป็นสิ่งที่ผู้ดูแลระบบมักละเลย และปัญหาพื้นที่ดิสก์เต็มคือสาเหตุที่ทำให้เซิร์ฟเวอร์ Synapse หยุดทำงานโดยไม่มีการแจ้งเตือนล่วงหน้า เมื่อพื้นที่จัดเก็บข้อมูลเต็ม Postgres จะไม่สามารถเขียนข้อมูลลงดิสก์ได้ และ Synapse จะปฏิเสธทุกคำขอที่ต้องมีการติดต่อกับฐานข้อมูล
FAQ
เซิร์ฟเวอร์ Matrix Synapse ต้องการ RAM เท่าไร?
สำหรับ homeserver ส่วนตัวที่มีผู้ใช้จำนวนน้อย ห้องขนาดเล็ก และไม่มีการเข้าร่วมห้องสาธารณะขนาดใหญ่ RAM ขนาด 2 GB ถือว่าใช้งานได้ ซึ่งเป็นขนาดที่หน้าแนะนำการตั้งค่าส่วนใหญ่ระบุไว้ ณ เดือนสิงหาคม 2026 เอกสารของ Synapse แนะนำให้มี RAM เหลือว่างอย่างน้อย 1 GB นอกเหนือจากส่วนที่ระบบใช้งานอยู่ หากผู้ใช้ของคุณจะเข้าร่วมห้องสาธารณะขนาดใหญ่ เช่น #matrix:matrix.org เนื่องจากเซิร์ฟเวอร์ของคุณจะต้องจัดเก็บสถานะของห้องนั้นและประมวลผล traffic อย่างต่อเนื่อง ควรเพิ่ม swap บนแผน 2 GB เพื่อป้องกันไม่ให้กระบวนการทำงานถูก kernel สั่ง kill เมื่อมีการเข้าร่วมห้องขนาดใหญ่
ฉันจำเป็นต้องใช้ PostgreSQL แทน SQLite หรือไม่?
หากมีผู้ใช้เกินจำนวนเล็กน้อย จำเป็นต้องใช้ SQLite ยอมให้มีการเขียนข้อมูลได้ทีละหนึ่งรายการเท่านั้น ทำให้ traffic ของการทำ federation และคำขอจาก client ขัดจังหวะกันเองเมื่อมีโหลดสูง และทำให้คำขอค้างเป็นเวลาหลายวินาที กระบวนการทำงานแบบ worker ของ Synapse ซึ่งเป็นวิธีที่รองรับการใช้งานมากกว่าหนึ่ง CPU core จำเป็นต้องใช้ Postgres การย้ายฐานข้อมูลในภายหลังสามารถทำได้ด้วย synapse_port_db แต่จะมีช่วงเวลาที่ระบบหยุดทำงาน ดังนั้นควรสร้างฐานข้อมูลด้วย --encoding=UTF8 --locale=C --template=template0 ตั้งแต่ก่อนเริ่มมีผู้ใช้งาน
ทำไมการใช้งานดิสก์ของ Synapse ถึงเพิ่มขึ้นเรื่อยๆ?
เกิดจากหนึ่งไดเรกทอรีและหนึ่งตาราง media store จะเก็บทุกไฟล์ที่ถูกอัปโหลดไปยังห้องที่เซิร์ฟเวอร์ของคุณอยู่ รวมถึงสำเนาแคชของสื่อจากผู้ใช้ภายนอกและภาพตัวอย่างที่สร้างขึ้น โดยจะไม่มีการลบข้อมูลออกจนกว่าคุณจะตั้งค่า media_retention ส่วนตาราง state_groups_state จะขยายตัวตามสถานะของห้องบนเซิร์ฟเวอร์ที่ทำ federation และ rust-synapse-compress-state จะช่วยลดขนาดลง ควรวัดขนาดทั้งสองส่วนด้วย du -sh บน media_store_path ของคุณ และด้วย SELECT pg_size_pretty(pg_total_relation_size('state_groups_state')); ก่อนที่จะตัดสินใจว่าจะจัดการส่วนใดก่อน
ฉันจะป้องกันไม่ให้คนแปลกหน้าลงทะเบียนบน homeserver ของฉันได้อย่างไร?
คงค่า enable_registration ไว้ที่ค่าเริ่มต้นคือ false และสร้างบัญชีผู้ใช้ด้วย register_new_matrix_user เมื่อวิธีนี้ไม่เพียงพอต่อการขยายตัว ให้ตั้งค่า enable_registration: true ร่วมกับ registration_requires_token: true แล้วแจกจ่ายโทเค็นที่สร้างผ่าน POST /_synapse/admin/v1/registration_tokens/new อย่าตั้งค่า enable_registration_without_verification: true เพียงเพื่อเลี่ยงการแจ้งเตือนตอนเริ่มระบบของ Synapse เพราะ homeserver ที่เปิดสาธารณะจะกลายเป็นแหล่งสแปม และผู้ดูแลระบบคนอื่นจะตอบโต้ด้วยการบล็อกโดเมนทั้งหมดของคุณ
homeserver ของฉันควรทำ federation หรือไม่?
Federation เป็นการตัดสินใจเรื่องการเปิดเผยข้อมูล ไม่ใช่ค่าเริ่มต้น ควรทำ federation หากผู้ใช้ของคุณจำเป็นต้องติดต่อกับผู้คนบน homeserver อื่น แต่ควรปิดไว้หากเซิร์ฟเวอร์ให้บริการเฉพาะทีมงานของคุณ เนื่องจากเซิร์ฟเวอร์ที่ไม่ได้ทำ federation จะจัดเก็บข้อมูลน้อยกว่า ได้รับข้อมูลน้อยกว่า และดึงดูดการละเมิดได้น้อยกว่ามาก ในกรณีที่อยู่กึ่งกลาง federation_domain_whitelist จะจำกัดการทำ federation ไว้เฉพาะโดเมนคู่ค้าที่ระบุไว้เท่านั้น และเอกสารของ Synapse แนะนำให้ตั้งค่า firewall กั้น federation listener ไว้ด้วย แทนที่จะพึ่งพาการตรวจสอบที่ระดับแอปพลิเคชันเพียงอย่างเดียว