| How to set up your own secure messenger with Matrix + Element » |
Matrix + Element with Voice & Video Calling
Launching your own messenger: Matrix + Element + NPM 🔥 + Calls 📲
In the first part I described how to set up your own messenger, just messaging, without calls
This is an addition on how to do the same but with audio/video calls
Just like in the first part, you only need to follow everything step by step... let’s go!
---------
Today, the issue of privacy and control over your data is more relevant than ever.
When I was looking for a simple and clear guide to installing Matrix, I encountered either overloaded manuals or fragmented information.
That’s why I decided to write my own guide in a “4-in-1” format.

In this guide, we will deploy a full stack:
-
Matrix (Synapse) - the brain and server-side of the messenger.
-
Element - a modern and convenient web client.
- TURN server - for making calls
-
Nginx Proxy Manager - for SSL automation and convenient traffic management.
Why Matrix?
-
Decentralization. You run your own “instance”. All communication within your server stays on your resources — you fully own the infrastructure.
-
End-to-end encryption (E2EE). No compromises. Thanks to the Olm/Megolm protocol, even the server administrator (you) cannot read encrypted chats.
-
Federation. It’s like “email in the world of messengers”. You are not locked into your server and can communicate with users from other Matrix instances, join global chats and rooms.
Â
Prerequisites
You need to rent a VPS server in a reliable location
Since we are adding calls, the server should be more powerful, I use this one
In AWS this can be expensive, consider options like your home server or for example Contabo, it’s cheaper there
You should have two DNS records:
16.52.246.29 - replace with your server IP address
16.52.246.29 - yourdomain.com
16.52.246.29 - turn.yourdomain.com
Here is mine:
For Matrix calls, the following ports must be open:
80/tcp81/tcp443/tcp8448/tcp3478/tcp3478/udp49152-65535/udp
In this example, I deploy on Debian 12
Â
Installation and setup
Connect to the created server via SSH and switch to root mode
sudo su
Update packages
apt update && apt upgrade -y
Install GIT, Cron, Curl if they are not installed
apt install git cron curl -y
Clone my repository
git clone https://github.com/nikita-butakov/matrix_element.git
Go to the new project folder
cd matrix_element
Important! Rename the docker-compose file, because here it will be a different one with calls!
mv docker-compose-calls.yml docker-compose.yml
First, we need to edit the config.json file
nano config.json
In it, specify your server name instead of yourdomain.com, in my case it is jitsidevops.website
After making changes, you need to exit the file. In nano, this is done with CTRL + X
And save the file by pressing Y and ENTER
You can check that the file contains the correct information with the command
cat config.json
Also update the COTURN configuration file
Go to the folder
cd coturn
Edit the file
nano turnserver.conf
Replace the line
static-auth-secret=CHANGE_THIS_TO_LONG_RANDOM_SECRET
with your own secret and save it somewhere — it will be needed later
Replace yourdomain.com with your domain and YOUR_REAL_PUBLIC_IP with the server’s public IP
Here is how mine looks:
Exit the file saving it with CTRL + X , Y , Enter
Return to the main folder
cd ../
Grant execution permissions to the certificate copy script
chmod +x certs.sh
You can verify permissions with
ls -l
The letter x should appear
After granting execute permissions, you need to add a scheduled run of this script in Cron
Check the path to your folder
pwd
Mine is /home/admin/matrix_element, so the command will be:
0 3 * * * /home/admin/matrix_element/certs.sh
If your path is different, replace it with your own
Open the Cron editor
crontab -e
When asked which editor to use, you can choose nano by pressing 1 and Enter
Add the command at the very bottom
0 3 * * * /home/admin/matrix_element/certs.sh
Then exit the file with CTRL + X, then Y and Enter
You can verify it was added with
crontab -l
Now you need to install Docker, go to the link https://docs.docker.com/engine/install/debian/
Find the section "Install using the convenience script"
Install using the provided commands
Verify installation with
docker -v
Run the command to generate the config, replacing yourdomain.com with your domain
docker run --rm -it \
-e SYNAPSE_SERVER_NAME=yourdomain.com \
-e SYNAPSE_REPORT_STATS=no \
-v $(pwd)/synapse/data:/data \
matrixdotorg/synapse:latest generate
After running the command, go to the folder
cd synapse/data/
Edit the homeserver.yaml file
nano homeserver.yaml
Carefully delete all lines up to database
Then paste the config from the link. Also replace yourdomain.com with your domain
At the bottom of the file, also replace turn.yourdomain.com
https://github.com/nikita-butakov/matrix_element/blob/main/homeserver_example_calls
For security, also replace with your own secret that you saved earlier
turn_shared_secret: "CHANGE_THIS_TO_LONG_RANDOM_SECRET"
The file after editing with my domain will look like this:
https://github.com/nikita-butakov/matrix_element/blob/main/homeserver_example_calls_done
Go back two levels up to the main folder
cd ../..
First, start only Nginx Proxy Manager to obtain certificates
docker compose up npm -d
After the container starts, open Nginx Proxy Manager, in my case it is (replace with your domain):
http://jitsidevops.website:81/
The first time, you need to register and set a password
After registration, on the main page go to Proxy hosts
Click Add proxy
In the domain field, enter your domain name, in my case jitsidevops.website
Scheme: http
Forward Hostname / IP: element
Forward Port: 80
Block Common Exploits: ON
Websockets Support: ONCustom locations tab
Location: /_matrix
Scheme: http
Forward Hostname / IP: synapse
Forward Port: 8008Location: /_synapse
Scheme: http
Forward Hostname / IP: synapse
Forward Port: 8008
Click Save and return to the console
Start the remaining containers
docker compose up -d
After successful startup, go back to Nginx Proxy Manager and add a certificate by editing the existing Proxy Host
SSL tab
Request a new certificate
Force SSL: ON
HTTP/2 Support: ON
Click Save again
As a result, in Nginx Proxy Manager the status should be Online and must have a certificate
In the console, run the first certificate copy manually
./certs.sh
Important: if the script returns an error, check the folder name
npm/letsencrypt/live
with the certificate and change it to the correct one
If it is, for example, npm-2, then in the script you need to change it to npm-2. Mine is npm-1
Restart all containers
docker compose down
docker compose up -d
Check that all containers are in UP status with
docker ps
Open the website and make sure it loads
In my case it is https://jitsidevops.website (replace with your domain)
Also go to https://federationtester.matrix.org/ and check federation by entering your domain
Checks should be green with status Success
Now you can create a user with the command
docker compose exec synapse register_new_matrix_user \
-c /data/homeserver.yaml \
http://localhost:8008 \
-u admin \
-p strongpassword \
-a
Success! - the user has been created
Go back to the site and test login by clicking Sign in and entering the created user credentials
admin
strongpassword
The password can be changed later in user settings
Now you can test federation — when you can message users from other servers and rooms
Find a room/chat on the website https://matrixrooms.info/search
For example
#linux:makigas.es
Paste it into the Search field and click Join
If you see other rooms, messages, etc. — great, everything works correctly
Download the app for smartphone or Windows/Linux/Mac
https://element.io/en/download
Now test calls
I created two users and found myself
I call myself from the computer to the phone

Now you have your own messenger with full federation and calling functionality!
-----------------
An important feature of Matrix federation is that you can send messages and make calls with users who have deployed their own server or use the Matrix.org server
For testing, I also created a user on matrix.org
In the profile description you can see @username:matrix.org
Calls and messaging — everything works. The only thing if you use matrix.org:
- there are limits on file size, quantity, and speed
- a paid subscription is required to remove limits
- you trust your privacy to the Matrix Foundation; without your own server you are limited in this

No feedback yet
Nikita
#IT #Explorer #ImmigrantSearch
Archives
- March 2026 (2)
- February 2026 (2)
- January 2026 (1)
- November 2025 (1)
- September 2025 (1)
- More...
