Deployment / Deploy to a VM

Deploy to a VM

This guide helps you to set up a production-ready LiveKit server on a cloud virtual machine.

This configuration uses Docker Compose and Caddy. Your LiveKit server will support a wide range of connectivity, including those behind VPN and firewalls (via TURN/TLS)

You do not need separate SSL certificates for this set up, we will provision them automatically with Caddy.


To start, you'll need:

  • A domain you control
  • The ability to add DNS records for subdomains for your new LiveKit server

Generate configuration

Use our configuration generation tool to create a customized configuration for your domain.

docker run --rm -it -v$PWD:/output livekit/generate

You should have a folder with the following files:

  • caddy.yaml
  • docker-compose.yaml
  • livekit.yaml
  • redis.conf
  • OR cloud_init.xxxx.yaml

Deploy to a VM

Depending on your cloud provider, there are a couple of options:

This is the easiest method for deploying LiveKit Server. AWS, Azure, Digital Ocean, and others support cloud-init.

We have tested our scripts on Ubuntu and Amazon Linux, but it's possible the same scripts may work on other platforms. (Please let us know in Slack or open a PR!)

When starting a VM, paste the contents of the file cloud-init.xxxx.yaml into the User data field.

That's it! When the machine starts up, it'll execute the cloud-init protocol and install LiveKit.

When the install script is finished, your instance should be set up. It will have installed:

  • docker
  • docker-compose
  • generated configuration to /opt/livekit
  • systemd service livekit-docker

To start/stop the service you could use systemctl:

systemctl stop livekit-docker
systemctl start livekit-docker


Ensure that the following ports are open on your firewall and accessible on the instance:

  • 443 - primary HTTPS and TURN/TLS
  • 80 - TLS issuance
  • 7881 - WebRTC over TCP
  • 443/UDP - TURN/UDP
  • 50000-60000/UDP - WebRTC over UDP


Ensure both primary domain and TURN domain are pointed at the IP address of your instance.

This is required for Caddy to start provisioning your TLS certificates.


If something is not working as expected, SSH in to your server and use the following commands to investigate:

systemctl status livekit-docker
cd /opt/livekit
sudo docker-compose logs

Checking TLS certificates

If certificate acquisition process has been successful, you should see the following log entry:

livekit-caddy-1 | {"level":"info","ts":1642786068.3883107,"logger":"tls.obtain","msg":"certificate obtained successfully","identifier":"<yourhost>"}

If you don't see these messages, it means your server could not be reached from the internet.

Ensure DNS is pointed at your domain

Running host <yourdomain> should show the IP address of your server. Ensure that it matches the IP address of your server.

Instance started before networking

When using cloud-init, it's possible that the instance started up before networking was available to the machine. This is commonly the case on EC2 instances. When this happens, your cloud-init scripts will be stuck in a bad state. To fix this, you can SSH into the machine and trigger a re-run:

sudo cloud-init clean --logs
sudo reboot now

Instance firewall

Certain Linux distributions ship with an instance-specific firewall enabled. To check if this is the case, run:

sudo firewall-cmd --list-all

If firewall is enabled, you could add the following rules to it and restart the firewall:

sudo firewall-cmd --zone=public --permanent --add-port=80/tcp
sudo firewall-cmd --zone=public --permanent --add-port=443/tcp
sudo firewall-cmd --zone=public --permanent --add-port=7881/tcp
sudo firewall-cmd --zone=public --permanent --add-port=443/udp
sudo firewall-cmd --zone=public --permanent --add-port=50000-60000/udp
sudo firewall-cmd --reload

When the ports are successfully opened, running curl http://<yourdomain> should return a 404 response. (instead of hanging)