{"id":1169,"date":"2026-11-05T12:24:01","date_gmt":"2026-11-05T12:24:01","guid":{"rendered":"https:\/\/www.vps.tc\/blog\/?p=1169"},"modified":"2026-11-05T09:36:08","modified_gmt":"2026-11-05T09:36:08","slug":"jitsi-meet-vps-setup","status":"publish","type":"post","link":"https:\/\/www.vps.tc\/blog\/en\/jitsi-meet-vps-setup\/","title":{"rendered":"Self-Host Jitsi Meet on a VPS for Private Video Meetings"},"content":{"rendered":"<div class=\"aiw-summary\" id=\"aiw-ozet\">\n<p class=\"aiw-summary-title\">Quick Summary &#8211; Jitsi Meet on a VPS<\/p>\n<p>You can run your own meeting server with Jitsi Meet, but a complete setup needs verified media connectivity and room permissions, not just a working website. The environment and resources below describe a hypothetical lab, not measured capacity.<\/p>\n<ul>\n<li><strong>Starting environment<\/strong> \u2014 A clean Ubuntu Server 24.04 LTS amd64 VPS with 4 vCPU, 8 GiB RAM and 40 GiB SSD is a starting assumption, not a participant capacity guarantee.<\/li>\n<li><strong>Domain preparation<\/strong> \u2014 Point the A record for a domain you control to your VPS&#039;s actual public IPv4 address, and do not publish an AAAA record because this setup does not configure IPv6.<\/li>\n<li><strong>Network access<\/strong> \u2014 Allow TCP 80\/443 and UDP 10000 through both UFW and the provider firewall, while restricting SSH TCP 22 to your actual administration source address.<\/li>\n<li><strong>Packages and HTTPS<\/strong> \u2014 Use Jitsi&#039;s official stable APT repository, record installed package revisions and obtain a trusted certificate for your actual domain.<\/li>\n<li><strong>Meeting permissions<\/strong> \u2014 Use secure domain to reserve room creation for authenticated accounts, treating guest access, the lobby and meeting passwords as separate controls.<\/li>\n<li><strong>Operational validation<\/strong> \u2014 Test the media path with at least three clients, measure resource and traffic usage, and verify restoration from an encrypted off-server backup.<\/li>\n<\/ul>\n<\/div>\n<p class=\"aiw-lead\">A working meeting page does not mean your Jitsi server is ready. To self-host Jitsi Meet on VPS, you need official Ubuntu packages, DNS, HTTPS, UDP 10000 media access and restricted room creation. Treat 4 vCPU and 8 GiB RAM as a starting assumption; validate capacity with at least three clients and traffic measurements.<\/p>\n<div class=\"aiw-toc\" style=\"border:1px solid #dbe3ea;border-radius:8px;padding:16px 20px;margin:0 0 28px\">\n<p class=\"aiw-toc-head\"><strong>Table of Contents<\/strong><span class=\"aiw-toc-meta\"> \u00b7 18 min read<\/span><\/p>\n<ol style=\"margin:10px 0 0;padding-left:22px\">\n<li><a href=\"#set-capacity-expectations-before-choosing-a-vps\">Set Capacity Expectations Before Choosing a VPS<\/a><\/li>\n<li><a href=\"#prepare-dns-and-firewall-rules-before-installation\">Prepare DNS and Firewall Rules Before Installation<\/a><\/li>\n<li><a href=\"#install-jitsi-meet-from-the-official-repository\">Install Jitsi Meet from the Official Repository<\/a><\/li>\n<li><a href=\"#validate-media-connectivity-as-well-as-https\">Validate Media Connectivity as Well as HTTPS<\/a><\/li>\n<li><a href=\"#restrict-room-creation-with-authentication\">Restrict Room Creation with Authentication<\/a><\/li>\n<li><a href=\"#test-with-three-clients-and-scale-from-measurements\">Test with Three Clients and Scale from Measurements<\/a><\/li>\n<li><a href=\"#prepare-backups-and-updates-before-the-first-meeting\">Prepare Backups and Updates Before the First Meeting<\/a><\/li>\n<li><a href=\"#check-before-the-first-meeting\">Check Before the First Meeting<\/a><\/li>\n<li><a href=\"#frequently-asked-questions\">Frequently Asked Questions<\/a><\/li>\n<li><a href=\"#sources\">Sources<\/a><\/li>\n<\/ol>\n<\/div>\n<h2 id=\"set-capacity-expectations-before-choosing-a-vps\">Set Capacity Expectations Before Choosing a VPS<\/h2>\n<p>A smooth two-person call tells you little about twenty people switching cameras on. Load changes. When I size a VPS for Jitsi Meet, I consider participants, simultaneous rooms, resolution, active cameras and outbound media traffic-not headcount alone.<\/p>\n<p>Jitsi Meet provides the browser interface; Nginx serves it over HTTPS. Prosody handles authentication and session signalling over XMPP. Jicofo coordinates conferences and selects the media bridge. The Jitsi Handbook&#8217;s secure-domain documentation configures both Prosody and Jicofo for access control; web-server settings alone are insufficient.<\/p>\n<p>Jitsi Videobridge 2 is an SFU: it selectively forwards incoming streams to participants rather than combining them into one video. Two-person calls can use direct P2P media when configuration and connectivity permit. Larger calls use the bridge; two browsers may not exercise its conference workload.<\/p>\n<p>This hypothetical lab uses clean Ubuntu Server 24.04 LTS amd64, systemd, the distribution&#8217;s Nginx 1.24.x package and the Jitsi Meet 2.0 package family from Jitsi&#8217;s official stable APT repository, with compatible Jicofo, Jitsi Videobridge 2 and Prosody dependencies. <strong>4 vCPU, 8 GiB RAM and 40 GiB SSD are starting assumptions, not capacity guarantees.<\/strong> I&#8217;ll record exact package revisions at installation; subsequent steps will use that same package set.<\/p>\n<p>Participants add potential receivers; active cameras add video sources. Resolution and frame rate affect per-stream bandwidth, while receiver layouts and quality adaptation change forwarded layers. Simultaneous rooms share CPU, memory and network resources. The same headcount spread across different rooms need not produce the same load.<\/p>\n<p>Watch egress: the bridge can forward one stream to multiple receivers. This lab assumes one directly assigned public IPv4 address, provider-console access and connectivity advertised at 1 Gbit\/s or higher. Port speed does not guarantee sustained throughput. Verify actual bandwidth, traffic allowances and overage charges; plan to <a href=\"https:\/\/www.vps.tc\/blog\/en\/prometheus-grafana-setup-vps-monitoring\/\">monitor a VPS with Prometheus and Grafana<\/a> for resource visibility.<\/p>\n<p>Jibri provides recording and live streaming but is outside this setup. If you need either, allocate separate resources rather than stretching the meeting server&#8217;s starting budget.<\/p>\n<div class=\"aiw-callout aiw-callout-tip\">\n<p class=\"aiw-callout-label\">Tip<\/p>\n<p>The 4 vCPU, 8 GiB RAM and 40 GiB SSD allocation is the starting point for this hypothetical lab, not a guarantee of any participant count. Check the actual throughput and monthly traffic allowance behind the advertised 1 Gbit\/s connection. Jibri, used for recording and live streaming, is outside this setup&#039;s scope.<\/p>\n<\/div>\n<h2 id=\"prepare-dns-and-firewall-rules-before-installation\">Prepare DNS and Firewall Rules Before Installation<\/h2>\n<p>A working meeting page proves nothing about media connectivity. I check them separately. This hypothetical lab uses clean Ubuntu Server 24.04 LTS amd64 with one public IPv4 assigned directly to its interface; no NAT or port forwarding is needed.<\/p>\n<p>Before installation, plan an A record pointing <code>meet.example.com<\/code> to <code>203.0.113.10<\/code>. These reserved documentation values cannot support real DNS or Let&#8217;s Encrypt validation. Before running commands, substitute your controlled domain and real public IPv4. Replace the documentation-only management source <code>198.51.100.25\/32<\/code> too. With IPv6 unconfigured, publish no AAAA record; remove existing ones to prevent clients trying a broken IPv6 path.<\/p>\n<pre><code>sudo apt-get update\nsudo apt-get install dnsutils ufw\nsudo hostnamectl set-hostname meet.example.com\nhostnamectl --static\ndig +short A meet.example.com\ndig +short AAAA meet.example.com<\/code><\/pre>\n<p>Expect <code>hostnamectl --static<\/code> to show your chosen hostname, the A query your real public IPv4, and AAAA an empty answer. Empty is not necessarily successful: check the status in <code>dig AAAA meet.example.com<\/code> if uncertain. Setting a hostname creates no DNS record. <a href=\"https:\/\/www.vps.tc\/blog\/en\/what-is-dns-propagation-how-long-does-it-take\/\">What Is DNS Propagation? How Long Does It Take?<\/a> explains caching behind stale answers.<\/p>\n<p>Before adding the SSH rule, verify provider console access and your connection&#8217;s public outbound IPv4-not its private LAN address. Keep SSH open. Use a normal sudo-enabled account; these commands assume a clean server, so inspect any existing rules first.<\/p>\n<pre><code>sudo ufw status numbered\nsudo ufw default deny incoming\nsudo ufw default allow outgoing\nsudo ufw allow proto tcp from 198.51.100.25\/32 to any port 22\nsudo ufw allow proto tcp from 0.0.0.0\/0 to any port 80\nsudo ufw allow proto tcp from 0.0.0.0\/0 to any port 443\nsudo ufw allow proto udp from 0.0.0.0\/0 to any port 10000\nsudo ufw show added<\/code><\/pre>\n<p>Mirror these rules in the provider firewall: TCP 22 only from your management address; TCP 80\/443 and UDP 10000 for meeting clients. Let&#8217;s Encrypt&#8217;s challenge documentation specifies TCP 80 for HTTP-01 validation; permitting TCP 443 cannot replace it. UDP 10000 carries Videobridge media. Review <code>ufw show added<\/code> and recheck the SSH source before enabling.<\/p>\n<pre><code>sudo ufw enable\nsudo ufw status numbered<\/code><\/pre>\n<p>Expect <code>Status: active<\/code> and your allow rules. This does not prove external reachability: meeting ports may have no listening services before installation. Both firewall layers must permit traffic. Do not close your first SSH session until a second connects from your management address.<\/p>\n<div class=\"aiw-callout aiw-callout-warn\">\n<p class=\"aiw-callout-label\">Caution<\/p>\n<p>meet.example.com, 203.0.113.10 and 198.51.100.25\/32 are documentation examples only; do not use them for actual DNS, certificate validation or administration access rules. Before enabling UFW, prepare an SSH rule for your actual administration source address and verify access to the provider console. Compare the provider firewall rules against the same access plan.<\/p>\n<\/div>\n<h2 id=\"install-jitsi-meet-from-the-official-repository\">Install Jitsi Meet from the Official Repository<\/h2>\n<p>A wrong hostname can mean repairing several configuration files later. I check first. This hypothetical lab uses clean Ubuntu Server 24.04 LTS amd64, systemd, and Ubuntu&#8217;s Nginx 1.24.x package. APT resolves Jicofo, Jitsi Videobridge 2, and Prosody dependencies for the Jitsi Meet 2.0 family. Record exact revisions during installation; repository contents change.<\/p>\n<p>The Jitsi Handbook&#8217;s Debian\/Ubuntu installation flow uses the official stable APT repository. Below, a separate keyring holds its signing key; <code>signed-by<\/code> specifies that repository&#8217;s key. No <code>apt-key<\/code> or downloaded scripts piped into privileged shells. Run commands sequentially as a sudo-enabled normal user; fix errors before continuing. Installing Nginx first lets Jitsi detect it.<\/p>\n<pre><code>sudo apt update\nsudo apt install ca-certificates curl gnupg software-properties-common\nsudo add-apt-repository -y universe\nsudo apt update\nsudo apt install nginx\n\nsudo install -d -m 0755 \/usr\/share\/keyrings\nkey_file=$(mktemp)\ncurl -fsSL https:\/\/download.jitsi.org\/jitsi-key.gpg -o \"$key_file\"\nsudo gpg --dearmor --yes --output \/usr\/share\/keyrings\/jitsi-keyring.gpg \"$key_file\"\nrm -f \"$key_file\"\nsudo chmod 0644 \/usr\/share\/keyrings\/jitsi-keyring.gpg\n\nprintf '%s\\n' 'deb [signed-by=\/usr\/share\/keyrings\/jitsi-keyring.gpg] https:\/\/download.jitsi.org stable\/' | sudo tee \/etc\/apt\/sources.list.d\/jitsi-stable.list\nsudo apt update\nsudo install -d -m 0700 \/var\/backups\/jitsi\napt-cache policy jitsi-meet jicofo jitsi-videobridge2 prosody nginx | sudo tee \/var\/backups\/jitsi\/package-candidates.txt\nsudo apt install jitsi-meet<\/code><\/pre>\n<p>In <code>apt-cache policy<\/code>, <code>Candidate:<\/code> shows the proposed version; <code>jitsi-meet<\/code> should come from Jitsi&#8217;s official repository. Stop at <code>(none)<\/code>. For signature errors, check the repository entry, key-file readability, and system clock-not by disabling verification. This record documents versions without pinning them. Nginx and Prosody normally come from Ubuntu&#8217;s archive; not every dependency comes from Jitsi.<\/p>\n<p>Enter <code>meet.example.com<\/code> for the shared example hostname, without a URL scheme or path. That name and <code>203.0.113.10<\/code> are reserved documentation values: real installation requires your controlled domain and the VPS&#8217;s actual public IPv4 address.<\/p>\n<p>Select the self-signed certificate option for the following HTTPS step; wording varies by package revision. This temporary certificate will not establish browser trust. Let&#8217;s Encrypt&#8217;s documentation specifies TCP 80 for subsequent HTTP-01 validation; both UFW and the provider firewall must allow access. The reserved example domain cannot obtain a real certificate.<\/p>\n<pre><code>sudo systemctl status nginx prosody jicofo jitsi-videobridge2 --no-pager\nsudo journalctl -u nginx -u prosody -u jicofo -u jitsi-videobridge2 -b -n 100 --no-pager\n\ndpkg-query -W -f='${binary:Package}\\t${Version}\\t${Architecture}\\t${db:Status-Abbrev}\\n' | sudo tee \/var\/backups\/jitsi\/package-versions.txt<\/code><\/pre>\n<p>Expect <code>active (running)<\/code>; this does not prove meeting traffic works. <code>journalctl<\/code> shows these services&#8217; last 100 log entries from the current boot. Inspect errors before restarting. The final command records the system-wide package inventory, including versions, architectures, and status; <code>ii<\/code> marks installed packages. Keep <code>\/var\/backups\/jitsi\/package-versions.txt<\/code> as the package-set reference for subsequent sections.<\/p>\n<h2 id=\"validate-media-connectivity-as-well-as-https\">Validate Media Connectivity as Well as HTTPS<\/h2>\n<p>The page loads. Where is the audio? HTTPS does not validate media through Jitsi Videobridge 2; I check both separately in this hypothetical Ubuntu Server 24.04 LTS lab. Replace reserved documentation values <code>meet.example.com<\/code> and <code>203.0.113.10<\/code> with your own domain and directly assigned public IPv4; neither works for real DNS or certificate validation. Leave IPv6 unconfigured; publish no AAAA record.<\/p>\n<p>Let&#8217;s Encrypt&#8217;s challenge documentation specifies TCP 80 for HTTP-01. Point the domain&#8217;s A record to your server; allow validation requests through UFW and the provider firewall. TCP 443 alone is insufficient. Check the packaged script and its usage:<\/p>\n<pre><code>test -r \/usr\/share\/jitsi-meet\/scripts\/install-letsencrypt-cert.sh &amp;&amp; \\\n  less \/usr\/share\/jitsi-meet\/scripts\/install-letsencrypt-cert.sh\n<\/code><\/pre>\n<p>If missing, stop; avoid random downloads. Consult instructions matching your recorded package versions. Otherwise, read its usage, dependencies and interactive prompts. Request the certificate only if your installed version supports this invocation:<\/p>\n<pre><code>sudo bash \/usr\/share\/jitsi-meet\/scripts\/install-letsencrypt-cert.sh\n<\/code><\/pre>\n<p>After success, enter your real meeting domain below. <code>grep<\/code> finds candidate Nginx site files; inspect <code>server_name<\/code> lines if several match. A file&#8217;s existence does not prove activation: confirm its server block appears in <code>nginx -T<\/code>.<\/p>\n<pre><code>read -r -p 'Ger\u00e7ek toplant\u0131 alan ad\u0131n\u0131z: ' MEET_DOMAIN\nsudo grep -RlF -- \"$MEET_DOMAIN\" \/etc\/nginx\/sites-available\/\nsudo nginx -T\nsudo nginx -t &amp;&amp; sudo systemctl reload nginx\ncurl --head --show-error \"https:\/\/${MEET_DOMAIN}\/\"\n<\/code><\/pre>\n<p>Expect <code>syntax is ok<\/code> and <code>test is successful<\/code> from <code>nginx -t<\/code>, then HTTP headers without certificate errors from <code>curl<\/code>. Check redirect destinations; never add <code>-k<\/code>. These are expected behaviors, not measured results.<\/p>\n<pre><code>sudo ss -lunp 'sport = :10000'\nsudo less \/etc\/jitsi\/videobridge\/jvb.conf\nsudo journalctl -u jitsi-videobridge2 -n 100 --no-pager\n<\/code><\/pre>\n<p>A UDP 10000 socket shows only local listening; the remaining commands expose bridge configuration and recent logs. Verify meeting-client access to TCP 80\/443 and UDP 10000 through both firewalls. Directly assigned public IPv4 needs no unnecessary NAT mapping. An incorrectly advertised media address can leave the interface working without audio or video. Compare ICE and address-mapping options in <code>\/etc\/jitsi\/videobridge\/jvb.conf<\/code> with your installed version&#8217;s reference; do not transplant obsolete keys.<\/p>\n<p>Restricted client networks may require TURN; the basic installation cannot guarantee connectivity everywhere. Independently of HTTPS, inspect the selected ICE candidate pair and connection state in your browser&#8217;s WebRTC diagnostics.<\/p>\n<div class=\"aiw-callout aiw-callout-warn\">\n<p class=\"aiw-callout-label\">Caution<\/p>\n<p>A valid HTTPS certificate covers the web layer; it does not prove that audio and video can reach the Videobridge. Do not add unnecessary NAT settings to this directly assigned public IPv4 setup. Client networks that restrict UDP may need TURN, so the basic installation cannot guarantee connectivity from every network.<\/p>\n<\/div>\n<h2 id=\"restrict-room-creation-with-authentication\">Restrict Room Creation with Authentication<\/h2>\n<p>HTTPS protects connections, not who can start meetings. The Jitsi Handbook&#8217;s secure-domain setup restricts room creation to authenticated accounts; guests join an authorized user&#8217;s meeting without accounts. I keep creation rights, admission approval, and media privacy separate.<\/p>\n<p>Keep the previously recorded Jitsi Meet 2.0 packages for this hypothetical Ubuntu Server 24.04 LTS lab. Back up first. These three files need partial edits, preserving components, service accounts, and unrelated settings. Compare installed configuration with the handbook: package revisions change.<\/p>\n<h3>Keep the three files consistent<\/h3>\n<p>In <code>\/etc\/prosody\/conf.avail\/meet.example.com.cfg.lua<\/code>, change this inside the existing <code>VirtualHost \"meet.example.com\"<\/code> block:<\/p>\n<pre><code>authentication = \"internal_hashed\"<\/code><\/pre>\n<p>Add this separate guest block only if absent; never duplicate the domain. The handbook specifies <code>jitsi-anonymous<\/code>:<\/p>\n<pre><code>VirtualHost \"guest.meet.example.com\"\n    authentication = \"jitsi-anonymous\"\n    c2s_require_encryption = false<\/code><\/pre>\n<p>Here, <code>guest.meet.example.com<\/code> is a logical XMPP domain needing no additional DNS record, Nginx virtual host, or certificate. <code>c2s_require_encryption<\/code> does not disable browser HTTPS. Replace the reserved documentation domain <code>meet.example.com<\/code> everywhere, including paths, with your controlled domain when deploying.<\/p>\n<p>In <code>\/etc\/jitsi\/meet\/meet.example.com-config.js<\/code>, add this after the existing <code>config<\/code> object definition. Keep any existing <code>anonymousdomain<\/code> setting consistent:<\/p>\n<pre><code>config.hosts.anonymousdomain = 'guest.meet.example.com';<\/code><\/pre>\n<p>Merge <code>authentication<\/code> into the existing <code>jicofo<\/code> block in <code>\/etc\/jitsi\/jicofo\/jicofo.conf<\/code>, without duplicating the outer block. The handbook&#8217;s XMPP setup uses <code>login-url<\/code> for the main account domain:<\/p>\n<pre><code>jicofo {\n    authentication {\n        enabled = true\n        type = XMPP\n        login-url = \"meet.example.com\"\n    }\n}<\/code><\/pre>\n<h3>Keep passwords out of history<\/h3>\n<p>As your sudo-enabled normal user, run <code>adduser<\/code>: it prompts interactively, keeping the password out of command arguments and shell history. Then check Prosody&#8217;s configuration:<\/p>\n<pre><code>sudo prosodyctl adduser moderator@meet.example.com\nsudo prosodyctl check config<\/code><\/pre>\n<p>Fix reported errors; this checks neither Jicofo nor JavaScript configuration. Once ready, restart services, potentially disrupting existing meetings:<\/p>\n<pre><code>sudo systemctl restart prosody jicofo &amp;&amp;\nsudo systemctl is-active prosody jicofo<\/code><\/pre>\n<p>Expect two <code>active<\/code> lines-not authorization proof. A lobby controls admission, a meeting password supplies a shared entry secret, and end-to-end encryption protects media privacy. None replaces room-creation authorization. An unauthenticated browser must not start a new meeting; after an authenticated user starts it, guests should join through the same link.<\/p>\n<h2 id=\"test-with-three-clients-and-scale-from-measurements\">Test with Three Clients and Scale from Measurements<\/h2>\n<p>I would not accept a two-person call as proof of Videobridge connectivity: with P2P enabled, direct client-to-client media can hide bridge access problems. Add a third. Use separate devices on home broadband, mobile data, and another fixed network.<\/p>\n<p>Keep the hypothetical lab&#8217;s Ubuntu Server 24.04 LTS amd64 and recorded Jitsi Meet 2.0 package set unchanged. Its 4 vCPU, 8 GiB RAM, and 40 GiB SSD guarantee no participant capacity. Three clients validate functionality, not capacity.<\/p>\n<p>Create a room as an authenticated user; add two guests. The Jitsi Handbook&#8217;s secure-domain documentation describes authenticated room creation with guest access to existing meetings. Verify that a guest in a private browser session cannot create a room. Test every device&#8217;s camera, microphone, and screen sharing in turn, keeping personal data off-screen. Briefly disconnect one device&#8217;s network and observe reconnection.<\/p>\n<pre><code>sudo ss -lunp 'sport = :10000'\nsudo journalctl -u jitsi-videobridge2 -u jicofo --since '10 minutes ago' --no-pager\nvmstat 1 5\nfree -h\niface=$(ip -4 route show default | awk '{print $5; exit}')\nif [ -n \"$iface\" ]; then\n    date -Is\n    ip -s link show dev \"$iface\"\n    sleep 10\n    date -Is\n    ip -s link show dev \"$iface\"\nfi<\/code><\/pre>\n<p>Expect <code>ss<\/code> to show the UDP 10000 socket and process information, not proof of external reachability. If media fails, check UFW and the provider firewall together. Search <code>journalctl<\/code> for bridge connection and session errors. The first <code>vmstat<\/code> CPU sample averages activity since boot; inspect subsequent samples for CPU usage, <code>st<\/code> (steal time), and swap activity. Watch <code>free<\/code>&#8216;s <code>available<\/code> memory.<\/p>\n<p>Calculate average bit\/s as TX byte-counter difference divided by elapsed seconds, multiplied by 8. Counters include all interface traffic. For that interval, record candidate pair, packet loss, and RTT through Chromium&#8217;s <code>chrome:\/\/webrtc-internals<\/code> or Firefox&#8217;s <code>about:webrtc<\/code>. RTT is round-trip time, not one-way latency.<\/p>\n<p>This blank template contains no measured results. Use equal-duration load steps; record resolution, camera, and screen-sharing conditions.<\/p>\n<table>\n<thead>\n<tr>\n<th>Time \/ duration<\/th>\n<th>Clients \/ networks \/ scenario<\/th>\n<th>Resolution \/ cameras \/ sharing<\/th>\n<th>CPU \/ available RAM<\/th>\n<th>TX bit\/s<\/th>\n<th>Packet loss \/ RTT<\/th>\n<th>Observations<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><\/td>\n<td><\/td>\n<td><\/td>\n<td><\/td>\n<td><\/td>\n<td><\/td>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>For longer comparisons, <a href=\"https:\/\/www.vps.tc\/blog\/en\/prometheus-grafana-setup-vps-monitoring\/\">monitor a VPS with Prometheus and Grafana<\/a>. Sustained CPU or memory pressure supports resource upgrades; distributing bridge load supports another Videobridge. Client-network loss alone does not justify upgrades. If egress saturates, verify actual usable bandwidth and traffic quotas on the connection advertised as at least 1 Gbit\/s before adding RAM.<\/p>\n<div class=\"aiw-callout aiw-callout-example\">\n<p class=\"aiw-callout-label\">Example<\/p>\n<p>Hypothetical lab scenario, not a completed test or firsthand incident: two clients could communicate over P2P while a UDP 10000 block becomes apparent only when a third client brings the Videobridge into use. In that scenario, compare local listening information from ss -lunp with jitsi-videobridge2 service logs and browser WebRTC statistics. A listening socket does not prove external reachability.<\/p>\n<\/div>\n<h2 id=\"prepare-backups-and-updates-before-the-first-meeting\">Prepare Backups and Updates Before the First Meeting<\/h2>\n<p>A working meeting proves nothing about recovery. In this hypothetical Ubuntu Server 24.04 LTS amd64 lab, I would plan renewal checks, off-server backups, and restoration before invitations. <code>\/var\/backups\/jitsi\/<\/code> is only staging space. It cannot protect against VPS loss.<\/p>\n<p>Identify the certificate client and actual renewal task through <code>systemctl list-timers --all<\/code>, service definitions, <code>\/etc\/crontab<\/code>, <code>\/etc\/cron.d\/<\/code>, periodic cron directories, and the relevant user&#8217;s crontab. Assume no timer name. Check the last run&#8217;s logs, certificate expiry, and any supported renewal dry run. Let&#8217;s Encrypt specifies TCP 80 for HTTP-01; UFW and the provider firewall must permit renewal validation.<\/p>\n<p>The Jitsi Handbook describes Prosody authentication: protect credentials alongside configuration. Include <code>\/etc\/jitsi\/<\/code>, <code>\/etc\/prosody\/<\/code>, <code>\/var\/lib\/prosody\/<\/code>, <code>\/etc\/nginx\/<\/code>, and the certificate client&#8217;s state directory. External Prosody storage requires a separate, consistent database backup.<\/p>\n<p>This hypothetical example requires BorgBackup 1.x, four initially running services, and verified SSH access under sudo. Prompts request a new off-server repository and actual certificate-state directory; omit <code>borg init<\/code> for existing repositories. During maintenance, freeze configuration changes, pause the identified renewal task, and await active renewal completion. Expect downtime. The commands also record package versions and APT policy.<\/p>\n<pre><code>sudo bash &lt;&lt;'BASH'\nset -euo pipefail\numask 077\nread -r -p 'Yeni SSH Borg deposunun adresi: ' BORG_REPO &lt; \/dev\/tty\nread -r -p 'Sertifika istemcisinin mutlak durum dizini: ' CERT_STATE &lt; \/dev\/tty\n[[ \"$BORG_REPO\" == ssh:\/\/* ]]\n[[ \"$CERT_STATE\" == \/* &amp;&amp; -d \"$CERT_STATE\" ]]\nexport BORG_REPO\ninstall -d -m 700 \/var\/backups\/jitsi\ndpkg-query -W -f='${binary:Package}\\t${Version}\\n' &gt; \/var\/backups\/jitsi\/packages.tsv\napt-cache policy jitsi-meet jicofo jitsi-videobridge2 prosody nginx &gt; \/var\/backups\/jitsi\/apt-policy.txt\nborg init --encryption=repokey-blake2\ntrap 'systemctl start prosody jicofo jitsi-videobridge2 nginx' EXIT\nsystemctl stop nginx jicofo jitsi-videobridge2 prosody\nborg create --stats \"::jitsi-$(date -u +%Y%m%dT%H%M%SZ)\" \\\n  \/etc\/jitsi \/etc\/prosody \/var\/lib\/prosody \/etc\/nginx \\\n  \"$CERT_STATE\" \/var\/backups\/jitsi\nBASH<\/code><\/pre>\n<p>Borg requests an encryption passphrase; successful creation reports archive statistics. Inspect warnings and exit status, verify services, and re-enable renewal. Secure the passphrase and <code>borg key export<\/code> backup separately from the repository. Run this only in a network-restricted recovery VM:<\/p>\n<pre><code>sudo bash &lt;&lt;'BASH'\nset -euo pipefail\numask 077\nread -r -p 'SSH Borg deposunun adresi: ' BORG_REPO &lt; \/dev\/tty\n[[ \"$BORG_REPO\" == ssh:\/\/* ]]\nexport BORG_REPO\nborg check --verify-data\nborg list\nread -r -p 'Geri y\u00fcklenecek ar\u015fivin ad\u0131: ' ARSIV &lt; \/dev\/tty\n[[ -n \"$ARSIV\" ]]\nRESTORE_DIR=$(mktemp -d \/var\/tmp\/jitsi-restore.XXXXXX)\ncd \"$RESTORE_DIR\"\nborg extract \"::$ARSIV\"\nprintf 'Dosyalar\u0131n \u00e7\u0131kar\u0131ld\u0131\u011f\u0131 dizin: %s\\n' \"$RESTORE_DIR\"\nBASH<\/code><\/pre>\n<p><code>borg list<\/code> shows archive names; extraction is usually silent. Inspect ownership, private-key permissions, and Prosody accounts. Extraction alone proves no service recovery. Validate updates in the isolated lab copy; retain exact Jitsi Meet 2.0-family revisions in the manifest and previous packages or a rollback image. Align automatic updates with maintenance. I would accept meetings only after three clients confirm authorized room creation, blocked unauthorized creation, and bidirectional audio\/video.<\/p>\n<h2 id=\"check-before-the-first-meeting\">Check Before the First Meeting<\/h2>\n<ul class=\"aiw-checklist\">\n<li>Verify the clean Ubuntu 24.04 LTS amd64 environment, allocated resources, traffic allowance and access to the provider console.<\/li>\n<li>Replace the example domain and IP addresses with your actual values; check the A record and remove any unused AAAA record.<\/li>\n<li>Restrict SSH to your actual administration source address, and verify TCP 80\/443 and UDP 10000 rules in both UFW and the provider firewall.<\/li>\n<li>Use a separate keyring and signed-by repository definition for the official signing key; record package candidates and installed versions.<\/li>\n<li>Check the HTTPS certificate, run nginx -t and inspect the certificate renewal mechanism actually created by the installation.<\/li>\n<li>Test that unauthorized room creation is blocked and guest access works, using at least three clients on different networks.<\/li>\n<li>Create encrypted off-server backups of configuration, Prosody state and certificate client state; verify restoration in an isolated environment.<\/li>\n<\/ul>\n<div class=\"aiw-cta\">\n<p>Before choosing a VPS, write down your expected concurrent rooms, active cameras and traffic allowance. Before scheduling the first real meeting, use three clients on different networks to verify media connectivity and confirm that unauthorized room creation is blocked.<\/p>\n<p class=\"aiw-cta-action\"><a href=\"https:\/\/www.vps.tc\/en\/vps\">Explore VPS plans<\/a><\/p>\n<\/div>\n<h2 id=\"frequently-asked-questions\">Frequently Asked Questions<\/h2>\n<div class=\"aiw-faq\">\n<details class=\"aiw-faq-item\" open>\n<summary>How much RAM and how many vCPUs does Jitsi Meet need?<\/summary>\n<p>This hypothetical setup starts with 4 vCPU, 8 GiB RAM and 40 GiB SSD; these are neither minimum requirements nor a participant capacity guarantee. Concurrent rooms, active cameras, resolution and outbound traffic all affect demand. Validate your resource choice with CPU, memory and network measurements under realistic meeting conditions. Jibri recording workloads are outside this sizing assumption.<\/p>\n<\/details>\n<details class=\"aiw-faq-item\">\n<summary>Which ports should I open for Jitsi Meet?<\/summary>\n<p>This setup uses TCP 80 and 443 for web access and UDP 10000 for Videobridge media. SSH on TCP 22 should be reachable only from your actual administration source address. Apply the rules in both UFW and the provider firewall. If you add TURN, plan additional access rules for its chosen transport protocol and relay port range.<\/p>\n<\/details>\n<details class=\"aiw-faq-item\">\n<summary>Does Jitsi Meet need a domain name and an SSL certificate?<\/summary>\n<p>This setup assumes a domain you control and an HTTPS certificate trusted by browsers. Browser access to cameras and microphones requires a secure context; an IP-only deployment or an untrusted certificate is not a suitable operating target here. Let&#039;s Encrypt HTTP-01 validation requires TCP 80 access. meet.example.com and 203.0.113.10 are reserved examples and cannot be used for actual validation.<\/p>\n<\/details>\n<details class=\"aiw-faq-item\">\n<summary>How do I stop anyone from creating meetings on Jitsi Meet?<\/summary>\n<p>Use secure domain to restrict room creation to authenticated users while allowing guests to join existing meetings. The Prosody, Jicofo and Jitsi Meet client configurations must agree and match your installed package versions. In this arrangement, guest.meet.example.com is a logical XMPP domain. The lobby and meeting passwords control admission; they do not replace room creation authorization or end-to-end encryption.<\/p>\n<\/details>\n<details class=\"aiw-faq-item\">\n<summary>Why does audio stop when a third person joins a working two-person call?<\/summary>\n<p>A two-person meeting can use P2P and hide a Videobridge connectivity problem. When a third participant changes the media path, blocked UDP 10000 traffic or an incorrectly advertised media address may become apparent, though these are not the only possible causes. Compare Videobridge logs, firewall rules and WebRTC statistics. Do not add NAT settings to a directly addressed public IPv4 server without diagnosing the problem.<\/p>\n<\/details>\n<details class=\"aiw-faq-item\">\n<summary>Which Jitsi Meet server files should I back up?<\/summary>\n<p>Include \/etc\/jitsi\/, \/etc\/prosody\/, \/var\/lib\/prosody\/, \/etc\/nginx\/ and your certificate client&#039;s state directory. Protect credentials and private keys, and choose a consistent copying method for state belonging to running services. A local \/var\/backups\/jitsi\/ directory is not sufficient on its own. Restore an encrypted off-server copy in an isolated environment, then verify accounts, configuration and meeting functionality.<\/p>\n<\/details>\n<\/div>\n<h2 id=\"sources\">Sources<\/h2>\n<ul class=\"aiw-sources\">\n<li><a href=\"https:\/\/github.com\/\" target=\"_blank\" rel=\"noopener\">GitHub &#8211; Hosting platform for the Jitsi Handbook<\/a> \u2014 github.com<\/li>\n<li><a href=\"https:\/\/github.com\/jitsi\/handbook\/blob\/master\/docs\/devops-guide\/secure-domain.md\" target=\"_blank\" rel=\"noopener\">Jitsi Handbook &#8211; Restricting room creation with secure domain<\/a> \u2014 github.com<\/li>\n<li><a href=\"https:\/\/letsencrypt.org\/docs\/challenge-types\/\" target=\"_blank\" rel=\"noopener\">Let&#039;s Encrypt &#8211; Domain validation methods, including HTTP-01<\/a> \u2014 letsencrypt.org<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>A working meeting page does not prove that audio and video work. Plan your Jitsi Meet installation on Ubuntu 24.04 around DNS, media connectivity, room creation permissions and three-client testing.<\/p>\n","protected":false},"author":2,"featured_media":1167,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9],"tags":[],"class_list":["post-1169","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-how-to"],"lang":"en","translations":{"en":1169,"tr":1168},"pll_sync_post":[],"_links":{"self":[{"href":"https:\/\/www.vps.tc\/blog\/wp-json\/wp\/v2\/posts\/1169","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.vps.tc\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.vps.tc\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.vps.tc\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.vps.tc\/blog\/wp-json\/wp\/v2\/comments?post=1169"}],"version-history":[{"count":1,"href":"https:\/\/www.vps.tc\/blog\/wp-json\/wp\/v2\/posts\/1169\/revisions"}],"predecessor-version":[{"id":1171,"href":"https:\/\/www.vps.tc\/blog\/wp-json\/wp\/v2\/posts\/1169\/revisions\/1171"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.vps.tc\/blog\/wp-json\/wp\/v2\/media\/1167"}],"wp:attachment":[{"href":"https:\/\/www.vps.tc\/blog\/wp-json\/wp\/v2\/media?parent=1169"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.vps.tc\/blog\/wp-json\/wp\/v2\/categories?post=1169"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.vps.tc\/blog\/wp-json\/wp\/v2\/tags?post=1169"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}