SSD Nodes Learn 🎉 VPS از $5.50/ماه
راهنماها Matt Connorتوسط Matt Connor

راهنمای کامل راه‌اندازی و نگهداری Matrix Synapse روی VPS

برای اجرای پایدار Matrix Synapse روی Ubuntu 24.04 به چه منابعی نیاز دارید؟ در این راهنما تنظیمات دیتابیس Postgres، مدیریت media store و روش‌های امنیتی را بررسی می‌کنیم.

ملزومات نگهداری و پایداری یک homeserver از نوع Matrix Synapse

نصب Matrix Synapse ساده است و به همان اندازه به‌راحتی ممکن است نادیده گرفته شود. نصب آن شامل یک مخزن apt، یک فایل پیکربندی، یک بلاک reverse proxy و یک رکورد DNS است. اما حفظ سلامت homeserver در طول یک سال، کاری متفاوت است: نیاز به یک دیتابیس واقعی، یک media store که به‌طور مرتب پاکسازی شود، محدود کردن ثبت‌نام برای جلوگیری از سوءاستفاده غریبه‌ها، و یک نسخه پشتیبان که هر دو بخش سرور را پوشش دهد.

این راهنما سیستم‌عامل Ubuntu 24.04 LTS را هدف قرار داده و Synapse را از مخزن apt رسمی matrix.org نصب می‌کند؛ این همان منبع بسته‌ای است که پروژه Synapse برای Debian و Ubuntu نگهداری می‌کند. نسخه‌های بسته هر چند هفته یک‌بار به‌روز می‌شوند، بنابراین در اینجا هیچ شماره نسخه‌ای ذکر نشده است. تمامی مسیرها و گزینه‌های زیر بر اساس مستندات فعلی Synapse استخراج شده‌اند.

تخمین منابع: با 1 vCPU و 2 GB رم واقعاً چه چیزی در اختیار دارید

صفحات رسمی تخمین منابع، تا اوت 2026، معمولاً یک homeserver از نوع Synapse را با 1 vCPU و 2 GB رم پیشنهاد می‌دهند. این پیشنهاد برای یک سناریو صادقانه است: یک سرور خصوصی، با تعداد کمی کاربر، اتاق‌های کوچک و بدون عضویت در اتاق‌های عمومی شلوغ. مستندات Synapse در مورد سناریوی دیگر صریح است. این مستندات «حداقل 1GB رم آزاد برای پیوستن به اتاق‌های عمومی بزرگ مانند #matrix:matrix.org» را درخواست می‌کند. رم آزاد، علاوه بر رم مورد نیاز برای Python، Postgres و هسته سیستم‌عامل.

یک اتاق می‌تواند تخمین منابع شما را تغییر دهد، زیرا نحوه پیوستن به اتاق‌ها این‌گونه است. وقتی یک کاربر محلی به یک اتاق می‌پیوندد، homeserver شما به یک شرکت‌کننده کامل در آن اتاق تبدیل می‌شود. سرور شما هر رویدادی را از هر سرور دیگری در آن اتاق دریافت می‌کند، امضای دیجیتال هر رویداد را تأیید کرده و وضعیت (state) اتاق را به‌صورت محلی ذخیره می‌کند. یک اتاق عمومی بزرگ هزاران عضو دارد که در صدها سرور پخش شده‌اند، بنابراین سرور شما به‌طور مداوم این پردازش‌ها را انجام می‌دهد، فارغ از اینکه کاربر شما دوباره آن اتاق را باز کند یا خیر. ترک کردن اتاق در آینده، تاریخچه‌ای که قبلاً ذخیره کرده‌اید را حذف نمی‌کند.

بیشتر رم Synapse صرف کش‌ها می‌شود. بخش caches دارای یک global_factor است که تمام کش‌ها را به‌طور هم‌زمان مقیاس‌بندی می‌کند و متغیر محیطی SYNAPSE_CACHE_FACTOR نیز همین کار را انجام می‌دهد. افزایش آن باعث مصرف رم برای جلوگیری از کوئری‌های دیتابیس می‌شود. کاهش آن باعث مصرف CPU و زمان Postgres برای صرفه‌جویی در رم می‌شود. Postgres نیز به حافظه اختصاصی خود نیاز دارد، بنابراین در یک سرور 2 GB، این دو برای تصاحب همان مگابایت‌های حافظه با هم رقابت می‌کنند.

دو قانون کاربردی برای یک پلن کوچک: swap اضافه کنید. swap باعث سریع‌تر شدن Synapse نمی‌شود، اما از کشته شدن پروسه توسط هسته سیستم‌عامل در هنگام پیوستن به اتاق‌های بزرگ جلوگیری می‌کند. سپس از هفته اول دیسک را زیر نظر بگیرید، زیرا دو موردی که بدون محدودیت رشد می‌کنند، media store و جداول وضعیت اتاق (room state tables) هستند و هر دو روی دیسک قرار دارند.

چرا Postgres، و چرا SQLite دیگر گزینه مناسبی نیست

بسته Debian به‌صورت پیش‌فرض با SQLite راه‌اندازی می‌شود. این برای اولین بوت مناسب است، اما برای سروری که کاربران دیگر از آن استفاده می‌کنند، انتخاب اشتباهی است. SQLite در هر لحظه تنها به یک نویسنده اجازه فعالیت می‌دهد. ترافیک فدراسیون و درخواست‌های کلاینت‌ها هم‌زمان اقدام به نوشتن می‌کنند؛ بنابراین یک درخواست سبک پشت یک درخواست سنگین منتظر می‌ماند و نشانه‌ای که کاربران شما گزارش می‌دهند، هنگ کردن تصادفی برنامه برای چند ثانیه است.

دلیل دوم ساختاری است. استفاده از worker processها در 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 یا روی host آمده است.

نصب 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 را چاپ می‌کند و مخزن رسمی matrix.org یک مجموعه noble ارائه می‌دهد. از بسته matrix-synapse موجود در مخازن پیش‌فرض Ubuntu استفاده نکنید. پروژه Synapse اکیداً توصیه می‌کند این کار را انجام ندهید، زیرا نسخه‌های موجود در مخازن رسمی از آخرین releaseهای پروژه عقب‌تر هستند و دارای باگ‌های امنیتی شناخته‌شده می‌باشند.

نصب‌کننده از شما یک نام سرور می‌خواهد و پاسخ را در /etc/matrix-synapse/conf.d/server_name.yaml می‌نویسد. در انتخاب آن دقت کنید. server_name بخشی است که بعد از علامت دونقطه در تمام شناسه‌های کاربری (@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ها را فعال کرده و سپس به حالت پایدار می‌رسد. unit سیستم‌عامل 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 صرفاً ظاهری نیستند. اگر مقادیر COLLATE و CTYPE در دیتابیس با تنظیمات Synapse متفاوت باشند، این سرویس اجرا نمی‌شود؛ مگر آنکه 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 خودداری کنید تا ابهامی در مورد اینکه کدام تنظیم فعال است، وجود نداشته باشد. پس از restart، بررسی کنید که Synapse واقعاً روی Postgres قرار دارد:

sudo -u postgres psql synapse -c "SELECT count(*) FROM users;"

نمایش یک عدد به این معناست که Synapse طرح‌واره (schema) خود را در این دیتابیس ایجاد کرده است. دریافت خطا مبنی بر نبود یک relation به این معناست که سرویس همچنان در حال نوشتن روی فایل SQLite است؛ بنابراین فایلی که ویرایش کرده‌اید، همان فایلی نیست که توسط برنامه خوانده می‌شود.

Reverse proxy، TLS و نیازهای federation فایل‌های .well-known

سرویس 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: false

تنظیم x_forwarded: true به Synapse می‌گوید که به هدر X-Forwarded-For که توسط پروکسی تنظیم شده است، اعتماد کند. بدون این تنظیم، تمام کلاینت‌ها از دید سیستم از آدرس 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 یک هشدار مهم در مورد این بلوک می‌دهد که نادیده گرفتن آن می‌تواند روزها وقت شما را تلف کند. پس از شماره پورت در proxy_pass، هیچ مسیری (path) اضافه نکنید، حتی یک / ساده. در غیر این صورت، nginx آدرس URI را استاندارد (canonicalize) می‌کند که باعث تغییر بایت‌های امضا شده توسط سرور فرستنده می‌شود. در نتیجه، درخواست‌های federation به دلیل عدم تایید امضا شکست می‌خورند، در حالی که درخواست‌های عادی کلاینت‌ها همچنان به درستی کار می‌کنند.

مقدار client_max_body_size باید حداقل به اندازه max_upload_size در Synapse باشد. اگر nginx عدد کوچک‌تری را در نظر بگیرد، آپلودهای بزرگ‌تر از آن توسط nginx و با خطای 413 Request Entity Too Large رد می‌شوند، پیش از آنکه Synapse آن‌ها را دریافت کند؛ بنابراین هیچ لاگی در Synapse برای توضیح این خطا ثبت نخواهد شد.

برای دریافت گواهی، راهنمای Certbot و Let's Encrypt روی Ubuntu 24.04 را دنبال کنید. اگر هنوز در انتخاب پروکسی تردید دارید، بخش مقایسه reverse proxy بررسی می‌کند که کدام‌یک عملیات TLS را برای شما انجام می‌دهد.

Delegation قابلیتی است که اجازه می‌دهد server_name همان example.com باقی بماند، در حالی که Synapse روی matrix.example.com اجرا می‌شود. دو فایل زیر را از طریق دامنه اصلی (bare domain) ارائه دهید:

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ها می‌گوید که ترافیک federation را به کجا ارسال کنند؛ این همان روشی است که باعث می‌شود federation به جای پورت پیش‌فرض 8448، روی پورت 443 اجرا شود. فایل client به کلاینت‌های Matrix می‌گوید که کدام URL پشتیبان @alice:example.com است. وجود هدر Access-Control-Allow-Origin در فایل client حیاتی است، زیرا کلاینت‌های مبتنی بر مرورگر آن را به صورت cross-origin دریافت می‌کنند؛ بدون این هدر، مرورگر پاسخ را مسدود کرده و کلاینت گزارش می‌دهد که نمی‌تواند 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 شامل نام پیاده‌سازی سرور و نسخه آن را برمی‌گرداند که ثابت می‌کند پروکسی از طریق مسیر federation به Synapse دسترسی دارد. در نهایت، دامنه خود را از طریق ابزار تست federation در https://federationtester.matrix.org بررسی کنید؛ این ابزار همان مسیری را طی می‌کند که یک سرور راه دور واقعی طی خواهد کرد.

فدراسیون یا عدم فدراسیون: آگاهانه تصمیم بگیرید

فدراسیون هدف اصلی Matrix است و در عین حال بیشترین هزینه را نیز به همراه دارد. یک homeserver فدراسیون‌کننده، اتصالات را از سرورهایی که هرگز نامشان را نشنیده‌اید می‌پذیرد، رویدادهای آن‌ها را دریافت می‌کند، رسانه‌هایشان را کش می‌کند و وضعیت (state) تمام اتاق‌هایی که کاربران شما در آن حضور دارند را ذخیره می‌نماید. این یک تصمیم در مدل تهدید (threat model) است، نه یک تنظیم پیش‌فرض.

زمانی فدراسیون را فعال کنید که کاربران شما نیاز دارند با افراد حاضر در سایر homeserverها ارتباط برقرار کنند، یا زمانی که دلیل انتخاب شما برای Matrix، داشتن یک هویت قابل‌حمل (portable identity) است. اگر سرور برای یک تیم خاص ایجاد شده و تمام حساب‌های کاربری متعلق به خودتان است، فدراسیون را فعال نکنید. یک سرور بسته، داده‌های کمتری ذخیره می‌کند، ترافیک ورودی کمتری دارد و برای سوءاستفاده، هدف بسیار جذاب‌تری نیست.

برای محدود کردن (به جای غیرفعال کردن کامل)، Synapse از یک لیست مجاز (allow list) استفاده می‌کند:

federation_domain_whitelist:
- lon.example.com
- nyc.example.com

مستندات توصیه می‌کنند که listener فدراسیون را در سطح فایروال نیز مسدود کنید تا ترافیک ناخواسته در سطح شبکه متوقف شود و به لایه Python نرسد. برای خاموش کردن کامل فدراسیون، federation را از لیست resources حذف کنید، /.well-known/matrix/server را منتشر نکنید و پورت 8448 را بسته نگه دارید.

اگر دلیل شما برای راه‌اندازی Matrix، چت خصوصی تیمی بوده و فدراسیون هرگز بخشی از نیاز شما نبوده است، پیش از متعهد شدن به Synapse، هزینه‌های جاری آن را با سایر جایگزین‌های Slack برای میزبانی شخصی مقایسه کنید. Rocket.Chat روی Docker Compose چت تیمی را روی ماشین‌های کوچک‌تر انجام می‌دهد، زیرا هرگز نیازی به ذخیره وضعیت اتاق‌های سازمان‌های دیگر ندارد.

مخزن رسانه همان چیزی است که به‌آرامی دیسک را پر می‌کند

فایل‌هایی که کاربران خودتان آپلود می‌کنند، به‌طور دائمی روی دیسک باقی می‌مانند. فایل‌هایی که توسط کاربران در سایر homeserverها ارسال می‌شوند، به‌محض اینکه یکی از کلاینت‌های شما آن‌ها را نمایش دهد، دریافت و روی دیسک شما کش (cache) می‌شوند. همچنین Synapse برای تصاویر، بندانگشتی (thumbnail) تولید می‌کند؛ بنابراین یک عکس به چندین فایل تبدیل می‌شود. به‌صورت پیش‌فرض، هیچ مکانیزمی برای منقضی شدن این فایل‌ها وجود ندارد.

محل ذخیره‌سازی را پیدا کرده و حجم آن را اندازه بگیرید:

grep media_store_path /etc/matrix-synapse/homeserver.yaml
sudo du -sh /var/lib/matrix-synapse/media_store

مسیری که در پیکربندی خودتان چاپ شده است را اندازه بگیرید. بسته 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 آپلودهای کاربران خودتان را پس از رسیدن به آن سن، به‌طور دائمی حذف می‌کند. تیمی که اسناد را در چت به اشتراک می‌گذارد و انتظار دارد سال آینده آن‌ها را پیدا کند، آن‌ها را از دست خواهد داد. بسیاری از سرورها فقط مقدار remote را تنظیم می‌کنند.

برای یک پاک‌سازی موردی، 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 رسانه‌های راه دور (remote) کش‌شده‌ای که آخرین دسترسی به آن‌ها پیش از آن timestamp بوده است را حذف می‌کند. POST /_synapse/admin/v1/media/delete?before_ts=<ms> رسانه‌های محلی (local) را طبق همان قانون حذف می‌کند. ابتدا پاک‌سازی remote را اجرا کنید و دوباره اندازه بگیرید، زیرا در یک سرور فدریتد (federating)، کش remote معمولاً بخش بزرگ‌تر است.

دو تنظیمات، یک دیسک را تغذیه می‌کنند. 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 tokens راهکار میانی است. توکن رشته‌ای است که کاربر جدید باید هنگام ثبت‌نام ارائه دهد و هر توکن می‌تواند محدودیتی برای تعداد دفعات استفاده داشته باشد:

enable_registration: true
registration_requires_token: true
curl -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 را از بدنه درخواست حذف کنید تا Synapse یکی تولید کرده و برگرداند. GET /_synapse/admin/v1/registration_tokens توکن‌های فعال را لیست می‌کند. هر دو فراخوانی به access token یک حساب مدیر سرور نیاز دارند که با ورود به سیستم به عنوان مدیر سروری که در بالا ایجاد کردید، به دست می‌آید.

سازمانی که از قبل حساب‌ها را در جای دیگری مدیریت می‌کند، می‌تواند کلاً از رمزهای عبور محلی صرف‌نظر کند، زیرا Synapse می‌تواند ورود به سیستم را به یک ارائه‌دهنده OIDC (OpenID Connect) محول کند، برای مثال Authentik به عنوان یک ارائه‌دهنده SSO خودمیزبان. در این صورت، ورود و خروج کاربران در یک نقطه مدیریت می‌شود.

بک‌آپ‌گیری به شکلی که واقعاً بتواند سرور را بازیابی کند

بک‌آپ Synapse از سه بخش تشکیل شده است و اگر هر یک از آن‌ها در بک‌آپ نباشد، سروری بازیابی می‌شود که هیچ‌کس نمی‌تواند از آن استفاده کند.

  • دیتابیس Postgres که تمام رویدادها، حساب‌های کاربری و اتاق‌ها را در خود نگه می‌دارد.
  • دایرکتوری media store که تمام فایل‌های آپلود شده را ذخیره می‌کند.
  • /etc/matrix-synapse که تنظیمات و کلید امضای سرور را در خود دارد.

کلید امضا (signing key) بخشی است که افراد فراموش می‌کنند. این همان کلید خصوصی است که homeserver شما رویدادها را با آن امضا می‌کند و سرورهای راه دور، رویدادها را با کلید عمومی متناظر آن تأیید می‌کنند. دستور 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 ارجاع داده می‌شوند، بنابراین کپی رسانه‌ای که پس از dump گرفته شود، فقط می‌تواند شامل فایل‌های اضافی باشد و هرگز فایلی را از دست نخواهد داد. ترتیب معکوس ممکن است باعث شود دیتابیس بازیابی‌شده به فایلی اشاره کند که بک‌آپ شما هرگز آن را ثبت نکرده است.

هر سه بخش را از روی VPS خارج کنید. restic با اسنپ‌شات‌های خارج از سایت به‌خوبی با این ساختار سازگار است، زیرا media store بخش بزرگ‌تر است و بین دفعات اجرا تغییر چندانی نمی‌کند، بنابراین deduplication باعث می‌شود حجم هر اسنپ‌شات کوچک باقی بماند.

سپس عملیات بازیابی را تمرین کنید، زیرا بک‌آپی که هرگز بازیابی نکرده‌اید، فقط یک فرضیه است. یک VPS دوم بسازید، همان پکیج را نصب کنید، تنظیمات را بازیابی کنید، دیتابیس را با همان encoding و locale ایجاد کنید، dump را با pg_restore وارد آن کنید، media store را برگردانید و وارد سیستم شوید. مدت زمانی که این کار طول کشید را یادداشت کنید. آن عدد، زمان واقعی بازیابی شماست.

هنگامی که جداول وضعیت رشد می‌کنند: فشرده‌سازی

Synapse وضعیت اتاق‌ها را به صورت گروه‌های وضعیت ذخیره می‌کند و در یک سرور فدرال، 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، که سلسله‌مراتب گروه‌های وضعیت را بدون تغییر در معنای وضعیت هیچ اتاقی، به سطرهای کمتری بازنویسی می‌کند. این ابزار با 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 نشان‌دهنده تعداد گروه‌های وضعیتی است که ابزار در هر لحظه روی آن‌ها کار می‌کند و -n تعداد این قطعات (chunks) است که در هر اجرا پردازش می‌شوند. فشرده‌ساز خودکار میزان پیشرفت را ثبت می‌کند، بنابراین اجرای بعدی از همان‌جا ادامه می‌یابد؛ همین ویژگی باعث می‌شود زمان‌بندی آن ایمن باشد. مستندات آن اشاره می‌کند که تغییرات در تراکنش‌هایی علیه جداول فقط‌افزودنی (append-only) اعمال می‌شوند، بنابراین می‌تواند در حالی که Synapse فعال است اجرا شود. با این حال، پیش از اولین اجرا حتماً از پایگاه داده نسخه پشتیبان تهیه کنید.

یک نکته در مورد Postgres وجود دارد که معمولاً کاربران را غافلگیر می‌کند. حذف سطرها فضا را برای استفاده مجدد به Postgres بازمی‌گرداند، نه به سیستم فایل؛ بنابراین df ممکن است پس از یک فشرده‌سازی بزرگ اصلاً تغییر نکند. دستور VACUUM FULL فضا را به سیستم‌عامل بازمی‌گرداند و یک قفل انحصاری روی جدول می‌گیرد؛ همچنین به فضای دیسک آزاد تقریباً معادل اندازه جدول نیاز دارد، بنابراین آن را به عنوان یک عملیات نگهداری زمان‌بندی کنید و نه به صورت ناگهانی.

بررسی‌هایی که سلامت سرور را تأیید می‌کنند

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 خروجی JSON ارائه می‌دهد و دو عدد مربوط به حجم داده‌ها قابل مقایسه با ماه گذشته هستند. بررسی حجم داده‌ها موردی است که معمولاً نادیده گرفته می‌شود، در حالی که پر شدن دیسک خطایی است که بدون هشدار قبلی سرور Synapse را از کار می‌اندازد: پر شدن فضای ذخیره‌سازی مانع از نوشتن Postgres می‌شود و در نتیجه، Synapse تمامی درخواست‌هایی که با پایگاه داده در ارتباط هستند را با شکست مواجه می‌کند.

FAQ

سرور Matrix Synapse به چه مقدار RAM نیاز دارد؟

برای یک homeserver خصوصی با تعداد کمی کاربر، اتاق‌های کوچک و بدون عضویت در اتاق‌های عمومی بزرگ، 2 GB رم کافی است و این همان مقداری است که اکثر صفحات راهنمای ابعاد‌سنجی تا اوت 2026 توصیه کرده‌اند. مستندات Synapse توصیه می‌کند اگر کاربران شما قصد عضویت در اتاق‌های عمومی بزرگی مانند #matrix:matrix.org را دارند، حداقل 1 GB رم آزاد علاوه بر سایر نیازها در نظر بگیرید؛ زیرا سرور شما در این حالت وضعیت (state) آن اتاق را ذخیره کرده و ترافیک آن را به‌طور مداوم پردازش می‌کند. در پلن‌های 2 GB حتماً از swap استفاده کنید تا یک عضویت سنگین باعث نشود که پردازش توسط kernel متوقف (kill) شود.

آیا باید به‌جای SQLite از PostgreSQL استفاده کنم؟

بله، اگر تعداد کاربران از چند نفر فراتر رود. SQLite در هر لحظه تنها اجازه یک عملیات نوشتن را می‌دهد؛ بنابراین تحت بار کاری، ترافیک فدراسیون و درخواست‌های کلاینت یکدیگر را مسدود می‌کنند و درخواست‌ها ممکن است برای چندین ثانیه معلق بمانند. worker processهای Synapse که روش پشتیبانی‌شده برای استفاده از بیش از یک هسته CPU هستند، به Postgres نیاز دارند. مهاجرت به آن در آینده با synapse_port_db امکان‌پذیر است اما باعث downtime می‌شود، بنابراین پیش از جذب کاربر، دیتابیس را با --encoding=UTF8 --locale=C --template=template0 ایجاد کنید.

چرا مصرف دیسک Synapse من مدام افزایش می‌یابد؟

دلیل آن یک دایرکتوری و یک جدول است. media store تمام فایل‌های آپلود شده در اتاق‌هایی که سرور شما در آن‌ها حضور دارد، شامل کپی‌های کش‌شده از رسانه‌های کاربران راه دور و تصاویر بندانگشتی (thumbnails) تولیدشده را نگه می‌دارد و تا زمانی که media_retention را تنظیم نکنید، هیچ‌کدام منقضی نمی‌شوند. جدول state_groups_state با افزایش وضعیت اتاق‌ها در یک سرور فدراسیون‌کننده رشد می‌کند و 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 من باید فدراسیون داشته باشد؟

فدراسیون یک تصمیم در مورد میزان دسترسی است، نه یک تنظیم پیش‌فرض. اگر کاربران شما نیاز دارند با افراد در سایر homeserverها در ارتباط باشند، فدراسیون را فعال کنید. اگر سرور فقط به یک تیم خاص خدمات می‌دهد، آن را غیرفعال نگه دارید؛ زیرا سرور غیرفدراسیون داده‌های کمتری ذخیره می‌کند، ترافیک کمتری دریافت می‌کند و سوءاستفاده‌های بسیار کمتری را به خود جذب می‌کند. در حالت بینابین، federation_domain_whitelist فدراسیون را به دامنه‌های شریک مشخص محدود می‌کند و مستندات Synapse توصیه می‌کند که علاوه بر بررسی در لایه اپلیکیشن، listener فدراسیون را در سطح فایروال نیز محدود کنید.

#matrix#synapse#self-hosting#postgresql#federation