This article steps you through the process of setting up your own server to host studio sessions
JackTrip Studio Sessions are normally powered by cloud computing servers managed by JackTrip Labs. This is completely transparent so that no IT skills are required, but availability is limited to certain locations worldwide. Unmanaged studio servers utilize infrastructure that you provide, which can be located anywhere in the world. Both offer all the same features and functionality and work exactly the same for anyone who joins your studio sessions.
Most things you need to set up your own unmanaged server is bundled into our JackTrip studio container image. If you are not familiar with containers or cloud-native computing, we recommend starting with Docker's Getting Started Guide.
In its simplest form, you can run the studio container directly from a command line using one of the examples provided. However, in order for things to work properly, it's also necessary to configure an HTTPS (encrypted) web proxy that forwards HTTP (unencrypted) traffic to port 8000.
There are many different ways to do this, and the best way depends on your own unique network and preferences. The details of configuring a web proxy are beyond the scope of this guide, but we'll step you through a few examples using Docker below to help get you started.
Basic Requirements
If you meet all of these requirements and have questions or run into problems, we are happy to help! Please file a support ticket.
- Managing a studio server requires advanced IT skills, including a strong understanding of things like cloud-native computing, network routing and firewalls, ingress, DNS, TLS, etc. If you are unfamiliar or uncomfortable with any of these topics, we encourage you to use our fully managed studio servers instead.
- You must have a paid subscription plan to host unmanaged studio servers (free trial and coupon minutes are OK). While there are no limits on maximum participants or session duration, your plan's concurrent session limits do still apply.
- You must have a fully-qualified domain name (FQDN) with DNS pointing to your server. Check out nip.io and sslip.io if you don't have this. They both resolve for example, A-B-C-D.nip.io to A.B.C.D.
- Your server must have a Linux container runtime available. A modern Linux server distribution is strongly recommended, but not strictly required. When using other operating systems, virtualization is likely to get in the way of realtime CPU priorities, resulting in additional audio glitches.
- Your server should have the following resources available:
- 2-4 vCPUs for each 5 participants. More compute is used for recording, live streaming, etc.
- About 2GB memory.
- About 2GB disk space. This is only used while recording and live streaming.
- Enough network capacity for all participants (a few Mbps each).
- Your firewall must allow direct access to your server from the Internet (and your own computer, in case it is on the same LAN/WAN) via the following ports:
-
- TCP ports 443, 4464, 7881 and 3478
- UDP ports 22124 and 3478
- UDP ports 61000-61099 (at least one for each participant)
- UDP ports 50000-50099 (at least one for each participant)
Migrating Your Studio
The first thing that you will need to do is create a new studio, if you haven't already done so. Next, open your studio dashboard and go to the "Settings" tab. Find the "Server Settings" pane and select "Unmanaged." A dialog will appear asking for your server's hostname. Enter your FQDN and confirm.
After migrating, the Server Settings will display two environment variables that you'll need to provide to the studio container: JACKTRIP_STUDIO_ID and JACKTRIP_STUDIO_TOKEN.
Finally, select and follow the steps in one of these examples:
You Already Have a TLS Key and Certificate
This example assumes that you would like to use an existing TLS key and certificate for your FQDN, and that you are using Docker for container orchestration.
- Create a new directory called "studio" and save your PEM-encoded TLS key to a file named "server.key" and your certificate to a file named "server.crt". Note that you need to provide a complete certificate chain so that for example the following command succeeds:
openssl verify -untrusted <( { openssl x509 >/dev/null; cat; } < server.crt ) server.crt
- Create a new "default.conf.template" file with the following contents:
## Basic Settings
tcp_nopush on;
tcp_nodelay on;
types_hash_max_size 2048;
proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_send_timeout 300;
gzip off;
## SSL Settings
ssl_certificate /etc/ssl/certs/server.crt;
ssl_certificate_key /etc/ssl/private/server.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
## Connection upgrade for websockets
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
## Forward 443/tcp to studio container port 8000
server {
listen 443 ssl;
server_name ${JACKTRIP_STUDIO_HOST};
location / {
proxy_pass http://${JACKTRIP_STUDIO_HOST}:8000;
proxy_buffers 100 128k;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
} - Create a new "compose.yaml" file with the following contents:
services:
Replace "REPLACE_WITH_FQDN" with your server's fully-qualified domain name.
nginx:
image: nginx
container_name: nginx
ports:
- "443:443"
environment:
- JACKTRIP_STUDIO_HOST=REPLACE_WITH_FQDN
volumes:
- ./server.key:/etc/ssl/private/server.key:z
- ./server.crt:/etc/ssl/certs/server.crt:z
- ./default.conf.template:/etc/nginx/templates/default.conf.template:z
studio:
image: jacktrip/studio
container_name: studio
privileged: true
shm_size: '128M'
cap_add:
- sys_nice
ulimits:
rtprio: 95
network_mode: host
environment:
- JACKTRIP_STUDIO_ID=REPLACE_WITH_STUDIO_ID
- JACKTRIP_STUDIO_TOKEN=REPLACE_WITH_STUDIO_TOKEN
Replace "REPLACE_WITH_STUDIO_ID" with your JACKTRIP_STUDIO_ID environment variable.
Replace "REPLACE_WITH_STUDIO_TOKEN" with your JACKTRIP_STUDIO_TOKEN environment variable. - You should now be able to start up your studio server by running:
docker-compose up -d
-
Test to make sure the containers are running and TLS works
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8585286181bc nginx "/docker-entrypoint.…" 45 seconds ago Up 45 seconds 80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp nginx
c90d6fc28a48 jacktrip/studio "/sbin/init" 45 seconds ago Up 45 seconds studio
$ curl https://REPLACE_WITH_FQDN/ping
{"status":"OK"} -
You are now ready to join your unmanaged studio!
To stop the server after you are finished, run:docker-compose down
Using Let's Encrypt to Handle TLS for You
This example uses the popular certbot software and Let's Encrypt service to obtain a new TLS certificate for your server, which is automatically rotated. It's based on guidance from this Medium article which we recommend reading first for additional context. In fact, you may want to set up a basic web server by following those instructions, before attempting to do it for your studio.
Note that this example also requires having TCP port 80 accessible from the Internet.
- Create a new directory called "studio"
- Create a new "default.conf" file with the following contents:
## Basic Settings
Replace "REPLACE_WITH_FQDN" with your server's fully-qualified domain name.
tcp_nopush on;
tcp_nodelay on;
types_hash_max_size 2048;
proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_send_timeout 300;
gzip off;
## SSL Settings
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
## Connection upgrade for websockets
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
## This is used by certbot for domain validation
server {
listen 80;
server_name REPLACE_WITH_FQDN;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
## Forward 443/tcp to studio container port 8000
server {
listen 443 ssl;
server_name REPLACE_WITH_FQDN;
# Certificates generated by Let's Encrypt
ssl_certificate /etc/letsencrypt/live/REPLACE_WITH_FQDN/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/REPLACE_WITH_FQDN/privkey.pem;
# Let's Encrypt best practice configs for nginx
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / {
proxy_pass http://REPLACE_WITH_FQDN:8000;
proxy_buffers 100 128k;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
} - Create a new "compose.yaml" file with the following contents:
services:
Replace "REPLACE_WITH_STUDIO_ID" with your JACKTRIP_STUDIO_ID environment variable.
nginx:
image: nginx
container_name: nginx
ports:
- "80:80"
- "443:443"
volumes:
- ./data/certbot/conf:/etc/letsencrypt:z
- ./data/certbot/www:/var/www/certbot:z
- ./default.conf:/etc/nginx/conf.d/default.conf:z
command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
certbot:
image: certbot/certbot
volumes:
- ./data/certbot/conf:/etc/letsencrypt:z
- ./data/certbot/www:/var/www/certbot:z
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
studio:
image: jacktrip/studio
container_name: studio
privileged: true
shm_size: '128M'
cap_add:
- sys_nice
ulimits:
rtprio: 95
network_mode: host
environment:
- JACKTRIP_STUDIO_ID=REPLACE_WITH_STUDIO_ID
- JACKTRIP_STUDIO_TOKEN=REPLACE_WITH_STUDIO_TOKEN
Replace "REPLACE_WITH_STUDIO_TOKEN" with your JACKTRIP_STUDIO_TOKEN environment variable. - Create a bootstrap certificate for "the chicken or the egg problem" (from Medium article):
-
Download the script to your working directory as
init-letsencrypt.sh:
curl -L https://raw.githubusercontent.com/wmnnd/nginx-certbot/master/init-letsencrypt.sh > init-letsencrypt.sh
-
Edit the script to add in your domain(s) and your email address.
-
Then run
chmod +x init-letsencrypt.sh
and./init-letsencrypt.sh
.
-
- You should now be able to start up your studio server by running:
docker-compose up -d
-
Test to make sure the containers are running and TLS works
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
391547e7d2a9 jacktrip/studio "/sbin/init" About a minute ago Up About a minute studio
74fd54feb41a certbot/certbot "/bin/sh -c 'trap ex…" About a minute ago Up About a minute 80/tcp, 443/tcp example2-certbot-1
4afbcc334962 nginx "/docker-entrypoint.…" About a minute ago Up About a minute 0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp nginx
$ curl https://REPLACE_WITH_FQDN/ping
{"status":"OK"} -
You are now ready to join your unmanaged studio!
To stop the server after you are finished, run:docker-compose down
Troubleshooting
If the nginx container fails to start, or the curl ping fails, check logs by running:
docker logs nginx
You can tail all logs for the studio container by running:
docker exec -it studio journalctl -f
It can sometimes be helpful to narrow things down to a specific service. For example , you can tail logs for just the "jacktrip" audio server by running:
docker exec -it studio journalctl -u jacktrip -f
Please feel free to also file a support ticket for help.