With the SARS-CoV-2 pandemic in full swing, “social distancing” is the order of the day. Since we're not allowed to get together with our friends and family, video conferencing is surging, and one popular free tool for that is Jitsi Meet. We've had a bunch of video chats on Jitsi Meet and have always been wondering whether the server(s) provided by Jitsi and shared by presumably thousands of conferences are a bottleneck that impacts the conference user experience. Here's how I've set up a private Jitsi Meet server on a Hetzner Cloud virtual machine.
Basics
Jitsi Meet is open-source software and the manufacturer offers ready-made packages for the current version of Debian GNU/Linux. Hence it should be reasonably simple to install, and in fact there are good explanations available that tell you what to do. So let's build our own Jitsi Meet server on a Hetzner Cloud virtual machine; right now this costs €3/month and the entertainment budget can probably bear that for a few months until the pandemic is over and we get to hang out in RL again.
Just to spice things up a little, we don't want to do a manual installation of Jitsi Meet – instead we're going to use Terraform to provision the VM and install and configure the software. Our goal is to be able to bring up the server with one single
$ terraform apply
command, so even if at some point we decide to save those three Euros per month and have an ice cream cone instead, we're ready for the next pandemic when we may want to do video conferences again.
We could use something like Ansible to configure Jitsi Meet after Terraform has done its thing, but this is a bit of a hassle because Terraform and Ansible don't work together out of the box. It's simpler to let cloud-init do the configuration; this means we will need to do some shell scripting to accomplish what we would otherwise use a few Ansible recipes to do, but it's not a lot of extra work. Cloud-init comes preinstalled on the VMs offered by virtually all commercial IaaS services including Hetzner Cloud, and Terraform supports it natively.
While the public Jitsi Meet instance on meet.jit.si
lets anyone
start or join a conference, we don't want to allow the whole Internet
to avail itself of our private server. Hence we will be enabling a
more secure mode of operation where only registered Jitsi Meet users
will be allowed to start conferences (they will be prompted for a user
name and password). Once a conference is running, anyone who knows the
conference URL is free to join it, but the organiser can kick them off
again if they are unknown strangers and/or don't behave as they
should. Organisers are also free to add a password to a conference and
share it with the legitimate participants, who can then use it to get
in.
Terraform
The basic idea behind Terraform is to write down the structure of one's datacenter in Terraform's configuration language and let Terraform worry about setting this up on the cloud IaaS provider of one's choice. This works as long as Terraform knows about the cloud IaaS provider of one's choice and can interact with its API to do what is needed. Fortunately for us, being Hetzner Cloud customers, Terraform comes with the necessary interface to talk to Hetzner's API.
Since our “datacenter” consists of one single VM the Terraform
configuration is pretty simple. The jitsimeet.tf
file looks
essentially like
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
The provider
declaration in lines 5–7 tells Terraform that we're
using Hetzner Cloud as our IaaS provider. The token
is an API token
which we can obtain from our Hetzner account. For privacy, we don't
include the token directly in this configuration; instead it goes into
a separate file called hetzner.auto.tfvars
, which looks like
1 2 3 |
|
The assignments in this file match the variable
declarations at the
top of jitsimeet.tf
(lines 1–3) – apart from hcloud_token
,
meet_fqdn
is the fully qualified host name of our new VM, and
ssh_key_id
refers to a public SSH key which Hetzner will install in
the VM's root account. You can upload public SSH keys to Hetzner's web
site and assign names to them, and that name is what we're looking for
here. (You could also let Terraform handle the business of creating
SSH keys and making them available to the Hetzner cloud, but since the
rest of the PinguCloud infrastructure, including the public SSH key,
are already there it seems a little extraneous. Maybe some day.)
Back in jitsimeet.tf
, the hcloud_server
resource on lines 9–17
describes the new VM which we're going to use for Jitsi Meet. This
will be the smallest and cheapest type of VM which Hetzner offers
right now (April 2020), a cx11
instance with 2 cores, 2 gigs of RAM,
and 20 gigs of mirrored SSD backing store. This is about as low as one
should go for Jitsi Meet, and as we're not dealing with huge
conferences it should be all right. The VM will run Debian GNU/Linux
10 (“buster”, the current version at this time of writing) and be
situated in Hetzner's Nuremberg datacentre (the nbg1
).
The user_data
declaration on line 16 specifies the meet.userdata
file as the input for the cloud-init
service on the instance, and
we'll be coming back to that soon.
Finally, the hcloud_rdns
resource on lines 19–23 controls the
reverse mapping of the VM's public IP address, i.e., what happens if
someone asks the DNS which name is associated with the machine's IP
address. This is very importante for mail servers, and even for
private servers like ours it makes the overall impression look
neater. Note that we're not hardcoding anything here – all the
variable elements come either from the hetzner.auto.tfvars
file or
else from the dynamic setup of other parts of the
configuration. Terraform takes care of the proper sequencing of
things; for example, it ensures that the VM is provisioned before the
reverse DNS mapping, just so that the VM's public IP address is known
to Terraform before it is used to configure the reverse mapping.
We can use the
$ terraform plan
command to preview what Terraform intends to do, and
$ terraform apply
to actually do it (this needs to be confirmed). If we want to get rid of the setup again, the command
$ terraform destroy
removes it (also after confirmation because this step cannot be undone).
Cloud-Init
(To be written.)
Jitsi Meet
(To be written.)