go2rtc
Videos
Overview: go2rtc on Ubuntu 24.04 LTS on Azure: overview (watch on YouTube)
Launch and log in: go2rtc on Ubuntu 24.04 LTS on Azure: launch and log in (watch on YouTube)
Deep Dive: go2rtc on Ubuntu 24.04 LTS on Azure: deep dive (watch on YouTube)
Overview
go2rtc is an ultra-low-latency camera streaming application and restreaming gateway. It connects to your cameras and video sources over the protocols they speak (RTSP, ONVIF, RTMP, HTTP and USB) and republishes each stream over whatever protocol the viewer needs: WebRTC for sub-second latency in a browser, Media Source Extensions, HLS, MJPEG and RTSP. It is a single, self-contained Go binary with no database, driven by one readable configuration file, so a working streaming gateway is answering within minutes of launch.
This SecureAnyCloud image installs go2rtc 1.9.14 behind an nginx TLS reverse proxy that binds go2rtc to loopback, and it is secure by default. Upstream go2rtc ships with its web interface and API completely open, which is unsafe on any network. In this image, go2rtc binds only to the local host and sits behind nginx on port 443, and its api.local_auth setting forces HTTP Basic authentication on every request, including the loopback requests the proxy makes.
There is no default or shared login. On first boot, go2rtc-firstboot.service generates a unique username and password, renders them into the configuration, writes the plaintext once to a root-only file at /root/go2rtc-credentials.txt, and regenerates a per-VM self-signed TLS certificate. Nothing is baked into the image.
To show the pipeline working on first boot, the image ships a demonstration stream: a self-contained ffmpeg test pattern that needs no camera hardware. It is transcoded to H.264 so that it plays over WebRTC, MSE and HLS and yields JPEG snapshots the moment you sign in. Step 10 and Step 11 show you how to add your own cameras.
What you get:
- go2rtc 1.9.14 as a single Go binary (
/opt/go2rtc/go2rtc) - One readable configuration file (
/etc/go2rtc/go2rtc.yaml) and no database to maintain go2rtc.servicerunning as the unprivilegedgo2rtcuser, with the web UI and API bound to loopback127.0.0.1:1984- The RTSP restream server on TCP 8554 and WebRTC media on 8555 (with automatic public address discovery via STUN)
nginx.servicereverse proxy terminating TLS on 443, with the whole UI and API behind HTTP Basic authentication, a WebSocket upgrade for browser playback, an unauthenticated/healthzendpoint, and a 301 redirect from port 80- A self-contained demonstration stream so that the dashboard is populated on first boot
go2rtc-firstboot.service, which generates a per-VM UI/API credential and TLS certificate on first boot- An Ubuntu 24.04 LTS base with the latest patches and unattended security upgrades enabled
- 24/7 SecureAnyCloud support
Prerequisites
You need an active Azure subscription, an SSH key, and a VNet with a subnet. The recommended VM size is Standard_B2s (2 vCPU, 4 GB RAM). go2rtc is lightweight, so a larger size helps only when you transcode many simultaneous high-resolution streams.
Deploy from the Azure Portal
Search the Azure Marketplace for go2rtc, choose the plan, and create the VM. In the networking step, attach a network security group (NSG) that allows inbound TCP 22 (SSH) and TCP 443 (the web UI and API) from your client networks only. If you want low-latency browser playback and RTSP restreaming from outside the VM, also allow TCP/UDP 8555 (WebRTC) and TCP 8554 (RTSP). The go2rtc API on port 1984 is bound to loopback and is never exposed directly.
Deploy from the Azure CLI
RG="go2rtc-prod"; LOCATION="eastus"; VM_NAME="go2rtc-01" IMAGE_URN="sac1647283583153:go2rtc-ubuntu-24-04:default:latest" SSH_KEY="$(cat ~/.ssh/id_rsa.pub)" az group create --name "$RG" --location "$LOCATION" az network vnet create -g "$RG" --name g2-vnet --address-prefix 10.120.0.0/16 --subnet-name g2-subnet --subnet-prefix 10.120.1.0/24 az network nsg create -g "$RG" --name g2-nsg az network nsg rule create -g "$RG" --nsg-name g2-nsg --name allow-ssh --priority 100 \
--source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 22 --access Allow --protocol Tcp az network nsg rule create -g "$RG" --nsg-name g2-nsg --name allow-https --priority 110 \
--source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 443 --access Allow --protocol Tcp az network nsg rule create -g "$RG" --nsg-name g2-nsg --name allow-webrtc --priority 120 \
--source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 8555 --access Allow --protocol '*'
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:go2rtc-ubuntu-24-04:default:latest
az vm create -g "$RG" --name "$VM_NAME" --image "$IMAGE_URN" \
--size Standard_B2s --storage-sku StandardSSD_LRS \
--admin-username azureuser --ssh-key-values "$SSH_KEY" \
--vnet-name g2-vnet --subnet g2-subnet --nsg g2-nsg --public-ip-sku StandardConnect via SSH
ssh azureuser@<vm-ip>go2rtc.service, nginx.service and go2rtc-firstboot.service all start automatically on first boot.
Verify the service
sudo systemctl is-active go2rtc nginx go2rtc-firstboot
sudo test -f /var/lib/sac/data/go2rtc-firstboot.done && echo FIRSTBOOT_DONE
sudo ss -tlnp | grep -E ':443 |:1984 |:8554 |:8555 'In the expected output, the services are active, nginx is bound to the public port 443, go2rtc's API is bound to loopback 127.0.0.1:1984 only, and the RTSP and WebRTC ports are listening:
active active active FIRSTBOOT_DONE LISTEN 0 4096 127.0.0.1:1984 0.0.0.0:* users:... LISTEN 0 511 0.0.0.0:443 0.0.0.0:* users:... LISTEN 0 4096 *:8555 *:* users:... LISTEN 0 4096 *:8554 *:* users:...Get your UI credentials
go2rtc has no default login. On first boot, a unique username and password are generated, rendered into the configuration and written to a root-only note, so no usable credential is baked into the image:
sudo cat /root/go2rtc-credentials.txtThe note contains the username, password and URL, all unique to this VM:
GO2RTC_URL=https://<vm-ip>/ go2rtc.username=admin_<random> go2rtc.password=<go2rtc-password> go2rtc.host=<vm-ip>Verify the auth round trip
The /healthz endpoint is public for liveness checks, but the web UI and the entire API require the per-VM credential, even over loopback. Verify this end to end over TLS without printing your password:
UN=$(sudo grep '^go2rtc.username=' /root/go2rtc-credentials.txt | cut -d= -f2-)
PW=$(sudo grep '^go2rtc.password=' /root/go2rtc-credentials.txt | cut -d= -f2-)
curl -sk -o /dev/null -w 'GET /healthz -> HTTP %{http_code}\n' https://127.0.0.1/healthz
curl -sk -o /dev/null -w 'GET /api (no creds) -> HTTP %{http_code}\n' https://127.0.0.1/api
curl -sk -o /dev/null -w 'GET /api (per-VM creds) -> HTTP %{http_code}\n' -u "$UN:$PW" https://127.0.0.1/apiThe health endpoint answers 200, the API refuses requests without credentials, and the per-VM credential signs you in:
GET /healthz -> HTTP 200 GET /api (no creds) -> HTTP 401 GET /api (per-VM creds) -> HTTP 200Issue the certificate for your public address
First boot writes the address that Azure reports into the TLS certificate, the credentials note and the login banner. With a Standard SKU public IP (the Azure default, and the --public-ip-sku Standard in Step 2), the current image records the VM's private address (for example 10.120.1.4). As a result, GO2RTC_URL points at an address you cannot reach, and a client that trusts go2rtc.crt refuses the certificate at the public IP. Check the recorded address:
sudo grep '^GO2RTC_URL=' /root/go2rtc-credentials.txtIf the output shows a private 10. address, issue a new certificate for the public IP on the VM. Azure's instance metadata service reports the public IP to the VM itself, and nothing leaves the VM:
PUBLIC_IP=$(curl -s -H Metadata:true 'http://169.254.169.254/metadata/loadbalancer?api-version=2020-10-01' | grep -o '"frontendIpAddress":"[^"]*"' | head -1 | cut -d'"' -f4)
PRIV=$(hostname -I | awk '{print $1}'); echo "public $PUBLIC_IP, private $PRIV"
sudo openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
-keyout /etc/nginx/tls/go2rtc.key -out /etc/nginx/tls/go2rtc.crt \
-subj "/C=GB/O=sac/CN=$PUBLIC_IP" \
-addext "subjectAltName=IP:127.0.0.1,DNS:localhost,DNS:$(hostname -s),IP:$PRIV,IP:$PUBLIC_IP" sudo chmod 0600 /etc/nginx/tls/go2rtc.key
sudo sed -i "s/\b$PRIV\b/$PUBLIC_IP/g" /root/go2rtc-credentials.txt /etc/update-motd.d/90-go2rtc
sudo systemctl restart nginxFor a DNS name, set PUBLIC_IP to the name and write DNS:$PUBLIC_IP in place of IP:$PUBLIC_IP. Your credentials do not change. The certificate is still self-signed, so the browser warning in Step 7 remains until you add a real certificate (Step 16).
Open the stream dashboard
Open the web UI in a browser and sign in with the username and password from Step 5. Your browser shows a certificate warning the first time, because the certificate is self-signed and unique to this VM. Accept the warning, or add a real certificate in Step 16. The dashboard lists every configured stream and its online state, with one-click links to view it, copy its protocol URLs, or inspect it:
open https://<vm-ip>/Watch the live stream
Select stream next to the demo stream to open the player. go2rtc negotiates the lowest-latency protocol that the browser supports, trying WebRTC first and then Media Source Extensions, so the demonstration test pattern plays live in the browser:
Copy the stream links
Select links next to a stream to see every way to consume it: WebRTC and MSE for browsers, HLS for Apple devices, MJPEG and a frame.jpeg snapshot, a stream.mp4 recording URL, and the raw rtsp:// restream address with a ready-to-paste ffplay command. Use these links to embed a stream in your own page or wire it into another tool:
Add a camera in the web UI
Select add in the top navigation to open the add source page. go2rtc can ingest a wide range of cameras and platforms: RTSP and ONVIF network cameras, USB and V4L2 devices, and integrations such as Apple HomeKit, Google Nest, Ring, Tuya and Home Assistant. Pick your source type and follow the prompts. go2rtc writes the new stream into /etc/go2rtc/go2rtc.yaml for you:
Add a camera in the config file
You can also edit the configuration directly. Each entry under streams maps a name to one or more sources. Add your camera's RTSP URL (most IP cameras expose one) alongside the demo stream:
streams: demo: "ffmpeg:virtual?video&size=1280x720#video=h264" front_door: rtsp://<camera-username>:<camera-password>@<camera-ip>:554/stream1Apply the change, then reload the dashboard in your browser:
# After editing /etc/go2rtc/go2rtc.yaml, apply the change and reload https://<vm-ip>/
sudo systemctl restart go2rtc.servicego2rtc connects to the camera on demand when a viewer opens the stream, and republishes it over WebRTC, MSE, HLS, MJPEG and RTSP without any further changes to the camera.
Server components
The following table lists the key components and their paths.
Component Path
go2rtc binary /opt/go2rtc/go2rtc
Configuration /etc/go2rtc/go2rtc.yaml
Configuration template (for firstboot) /etc/go2rtc/go2rtc.yaml.template
Systemd unit /etc/systemd/system/go2rtc.service
Firstboot script /usr/local/sbin/go2rtc-firstboot.sh
nginx TLS reverse proxy /etc/nginx/sites-available/sac-go2rtc
Self-signed TLS certificate /etc/nginx/tls/go2rtc.crt
Per-VM credentials note /root/go2rtc-credentials.txt (mode 0600)
Sentinel /var/lib/sac/data/go2rtc-firstboot.done
/opt/go2rtc/go2rtc --version ls /opt/go2rtc/go2rtc /etc/go2rtc/go2rtc.yaml /etc/systemd/system/go2rtc.service
UN=$(sudo grep '^go2rtc.username=' /root/go2rtc-credentials.txt | cut -d= -f2-)
PW=$(sudo grep '^go2rtc.password=' /root/go2rtc-credentials.txt | cut -d= -f2-)
curl -sk -u "$UN:$PW" https://127.0.0.1/api/streams | jq 'keys'go2rtc reports version 1.9.14, the component paths exist, and the API lists the configured streams:
go2rtc version 1.9.14 (b5948cf) linux/amd64 /opt/go2rtc/go2rtc /etc/go2rtc/go2rtc.yaml /etc/systemd/system/go2rtc.service [ "demo" ]Manage the service
sudo systemctl restart go2rtc.service
sudo journalctl -u go2rtc.service --no-pager -n 20go2rtc restarts in well under a second because it is a single binary with no database. The service is hardened with NoNewPrivileges, ProtectSystem=full, ProtectHome and PrivateTmp. It has write access only to its own configuration directory, so the web UI can save the streams you add.
Configuration
go2rtc is configured entirely through /etc/go2rtc/go2rtc.yaml. The following table lists the key sections that this image sets.
Section Meaning Image default
api.listen Web UI and API bind address 127.0.0.1:1984 (loopback)
api.local_auth Force Basic auth on every request true
api.username / api.password Per-VM credential (generated at first boot) unique per VM
rtsp.listen RTSP restream server :8554
webrtc.listen WebRTC media :8555
webrtc.candidates Public address discovery stun:8555
streams Named streams and their sources the demo stream
After you edit the file, apply the changes with sudo systemctl restart go2rtc.service. nginx is the sole public listener and terminates TLS. go2rtc never binds a public port for its UI.
Change the UI password
The credential is generated per VM at first boot. To set your own, edit api.username and api.password in the configuration and restart go2rtc, replacing <new-password> with your password:
sudo sed -i 's/^ password:.*/ password: "<new-password>"/' /etc/go2rtc/go2rtc.yaml
sudo systemctl restart go2rtc.serviceUpdate /root/go2rtc-credentials.txt to match so that your note stays accurate, and keep that file readable only by root.
Add a real TLS certificate (optional)
The image ships a per-VM self-signed certificate so that the UI is encrypted out of the box. For production, point a DNS record at the VM and install a certificate from Let's Encrypt so that browsers trust it without a warning:
sudo apt-get install -y certbot
sudo certbot certonly --standalone -d <your-domain>
sudo sed -i 's#/etc/nginx/tls/go2rtc.crt#/etc/letsencrypt/live/<your-domain>/fullchain.pem#; s#/etc/nginx/tls/go2rtc.key#/etc/letsencrypt/live/<your-domain>/privkey.pem#' /etc/nginx/sites-available/sac-go2rtc
sudo systemctl reload nginxcertbot obtains the certificate and sets up automatic renewal, so your credentials and streams travel over a trusted TLS connection.
Security recommendations
- Restrict the NSG so that ports 443, 22 and the streaming ports reach only trusted networks.
- Keep the API on loopback. The image binds go2rtc to
127.0.0.1behind nginx. Do not expose port 1984 directly. - Change the credential (Step 15) and keep the note
/root/go2rtc-credentials.txtreadable only by root. - Use a real certificate (Step 16) so that the per-VM credential and your camera streams travel over trusted TLS.
- Secure your cameras too. Give each camera its own account, and restrict which networks can reach the RTSP and WebRTC ports.
- Patch the OS monthly with
sudo apt-get update && sudo apt-get upgrade. Unattended security upgrades are already enabled.
Support and licensing
go2rtc is MIT licensed, with no per-CPU or per-user fee. SecureAnyCloud provides commercial support separately.
- Email: sales@secureanycloud.com
- Website: secureanycloud.com
- Support hours: 24/7, with a 24-hour response SLA
Deploy on Azure
Launch go2rtc on Ubuntu 24.04 with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7. sales@secureanycloud.com
Deploy on Azure
Launch go2rtc 1.9.14 on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com
Overview
go2rtc is an ultra-low-latency camera streaming application and restreaming gateway. It connects to your cameras and video sources over the protocols they speak (RTSP, ONVIF, RTMP, HTTP and USB) and republishes each stream over whatever protocol the viewer needs: WebRTC for sub-second latency in a browser, Media Source Extensions, HLS, MJPEG and RTSP. It is a single, self-contained Go binary with no database, driven by one readable configuration file, so a working streaming gateway is answering within minutes of launch.
This SecureAnyCloud image installs go2rtc 1.9.14 behind an nginx TLS reverse proxy that binds go2rtc to loopback, and it is secure by default. Upstream go2rtc ships with its web interface and API completely open, which is unsafe on any network. In this image, go2rtc binds only to the local host and sits behind nginx on port 443, and its api.local_auth setting forces HTTP Basic authentication on every request, including the loopback requests the proxy makes.
There is no default or shared login. On first boot, go2rtc-firstboot.service generates a unique username and password, renders them into the configuration, writes the plaintext once to a root-only file at /root/go2rtc-credentials.txt, and regenerates a per-instance self-signed TLS certificate. Nothing is baked into the image.
To show the pipeline working on first boot, the image ships a demonstration stream: a self-contained ffmpeg test pattern that needs no camera hardware. It is transcoded to H.264 so that it plays over WebRTC, MSE and HLS and yields JPEG snapshots the moment you sign in. Step 10 and Step 11 show you how to add your own cameras.
What you get:
- go2rtc 1.9.14 as a single Go binary (
/opt/go2rtc/go2rtc) - One readable configuration file (
/etc/go2rtc/go2rtc.yaml) and no database to maintain go2rtc.servicerunning as the unprivilegedgo2rtcuser, with the web UI and API bound to loopback127.0.0.1:1984- The RTSP restream server on TCP 8554 and WebRTC media on 8555 (with automatic public address discovery via STUN)
nginx.servicereverse proxy terminating TLS on 443, with the whole UI and API behind HTTP Basic authentication, a WebSocket upgrade for browser playback, an unauthenticated/healthzendpoint, and a 301 redirect from port 80- A self-contained demonstration stream so that the dashboard is populated on first boot
go2rtc-firstboot.service, which generates a per-instance UI/API credential and TLS certificate on first boot- An Ubuntu 24.04 LTS base with the latest patches and unattended security upgrades enabled
- 24/7 SecureAnyCloud support
Prerequisites
You need an active AWS account, an EC2 key pair in your target region, and a VPC with a subnet. The recommended instance type is m5.large (2 vCPU, 8 GB RAM). go2rtc is lightweight, so a larger size helps only when you transcode many simultaneous high-resolution streams.
You also need a security group. go2rtc uses the following ports:
Port Protocol Purpose
22 TCP SSH management
443 TCP HTTPS web UI and REST API (nginx TLS reverse proxy)
8554 TCP RTSP restream server (pull ingested streams back out over RTSP)
8555 TCP and UDP WebRTC media (low latency browser playback)
Open each port only to the client networks that need it. The go2rtc API on port 1984 is bound to loopback and is never exposed directly. go2rtc uses RTSP port 554 outbound when it pulls from your cameras, so it is not an inbound security group rule.
Launch the instance from the AWS Marketplace
Find the SecureAnyCloud go2rtc listing on AWS Marketplace, then choose Continue to Subscribe, Continue to Configuration and Continue to Launch. Select the m5.large instance type, your VPC and subnet, your EC2 key pair, and a security group that opens the ports in the table above. Launch the instance and note its public IPv4 address once it is running.
Launch the instance from the AWS CLI
The following command launches an instance from the SecureAnyCloud go2rtc Marketplace AMI into an existing subnet and security group. Replace <ami-id> with the AMI ID shown on the Marketplace listing, <key-name> with your EC2 key pair name, <subnet-id> with your subnet ID, and <security-group-id> with a security group that opens ports 22, 443, 8554 and 8555 as described above.
aws ec2 run-instances \
--image-id <ami-id> \
--instance-type m5.large \
--key-name <key-name> \
--subnet-id <subnet-id> \
--security-group-ids <security-group-id> \
--block-device-mappings '[{"DeviceName":"/dev/sda1","Ebs":{"VolumeSize":16,"VolumeType":"gp3"}}]' \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=go2rtc-01}]'On success, the command prints a JSON document. Note the instance ID, then retrieve the instance's public address once it is running withaws ec2 describe-instances --instance-ids <instance-id> --query "Reservations[].Instances[].PublicIpAddress" --output text.
Connect via SSH
Connect over SSH with the key pair you selected and the public IPv4 address from Step 2. The SSH login user depends on the operating system of the AMI variant that you launched:
AMI variant SSH login user
go2rtc 1.9.14 on Ubuntu 24.04 ubuntu
ssh <login-user>@<public-ip>go2rtc.service, nginx.service and go2rtc-firstboot.service all start automatically on first boot, so the credentials file is in place when you log in for the first time.
Verify the service
sudo systemctl is-active go2rtc nginx go2rtc-firstboot
sudo test -f /var/lib/sac/data/go2rtc-firstboot.done && echo FIRSTBOOT_DONE
sudo ss -tlnp | grep -E ':443 |:1984 |:8554 |:8555 ' | sed 's/users:.*/users:.../'In the expected output, the services are active, nginx is bound to the public port 443, go2rtc's API is bound to loopback 127.0.0.1:1984 only, and the RTSP and WebRTC ports are listening:
active active active FIRSTBOOT_DONE LISTEN 0 4096 127.0.0.1:1984 0.0.0.0:* users:... LISTEN 0 511 0.0.0.0:443 0.0.0.0:* users:... LISTEN 0 4096 *:8554 *:* users:... LISTEN 0 4096 *:8555 *:* users:...Get your UI credentials
go2rtc has no default login. On first boot, a unique username and password are generated, rendered into the configuration and written to a root-only note, so no usable credential is baked into the image. The following command confirms that the note exists with 0600 root:root permissions and shows the URL, username and host without printing the password:
sudo stat -c '%a %U:%G %n' /root/go2rtc-credentials.txt
sudo grep -E '^(GO2RTC_URL|go2rtc.username|go2rtc.host)=' /root/go2rtc-credentials.txtThe note is root-only and carries the per-instance URL, username and host:
600 root:root /root/go2rtc-credentials.txt GO2RTC_URL=https://<public-ip>/ go2rtc.username=admin_<random> go2rtc.host=<public-ip>To read the password itself, run sudo cat /root/go2rtc-credentials.txt on the instance. Keep this file readable by root only.
Verify the auth round trip
The /healthz endpoint is public for liveness checks, but the web UI and the entire API require the per-instance credential, even over loopback. Verify this end to end over TLS without printing your password:
UN=$(sudo grep '^go2rtc.username=' /root/go2rtc-credentials.txt | cut -d= -f2-)
PW=$(sudo grep '^go2rtc.password=' /root/go2rtc-credentials.txt | cut -d= -f2-)
curl -sk -o /dev/null -w 'GET /healthz -> HTTP %{http_code}\n' https://127.0.0.1/healthz
curl -sk -o /dev/null -w 'GET /api (no creds) -> HTTP %{http_code}\n' https://127.0.0.1/api
curl -sk -o /dev/null -w 'GET /api (per-instance) -> HTTP %{http_code}\n' -u "$UN:$PW" https://127.0.0.1/apiThe health endpoint answers 200, the API refuses requests without credentials, and the per-instance credential signs you in:
GET /healthz -> HTTP 200 GET /api (no creds) -> HTTP 401 GET /api (per-instance) -> HTTP 200Open the stream dashboard
Open the web UI in a browser at https://<public-ip>/ and sign in with the username and password from Step 5. Your browser shows a certificate warning the first time, because the certificate is self-signed and unique to this instance. Accept the warning, or add a real certificate in Step 16. The dashboard lists every configured stream and its online state, with one-click links to view it, copy its protocol URLs, or inspect it:
Watch the live stream
Select stream next to the demo stream to open the player. go2rtc negotiates the lowest-latency protocol that the browser supports, trying WebRTC first and then Media Source Extensions, so the demonstration test pattern plays live in the browser. WebRTC playback uses port 8555, so make sure your security group allows TCP and UDP 8555 from your client network:
Copy the stream links
Select links next to a stream to see every way to consume it: WebRTC and MSE for browsers, HLS for Apple devices, MJPEG and a frame.jpeg snapshot, a stream.mp4 recording URL, and the raw rtsp:// restream address with a ready-to-paste ffplay command. Use these links to embed a stream in your own page or wire it into another tool:
Add a camera in the web UI
Select add in the top navigation to open the add source page. go2rtc can ingest a wide range of cameras and platforms: RTSP and ONVIF network cameras, USB and V4L2 devices, and integrations such as Apple HomeKit, Google Nest, Ring, Tuya and Home Assistant. Pick your source type and follow the prompts. go2rtc writes the new stream into /etc/go2rtc/go2rtc.yaml for you:
Add a camera in the config file
You can also edit the configuration directly. Each entry under streams maps a name to one or more sources. Add your camera's RTSP URL (most IP cameras expose one) alongside the demo stream:
streams: demo: "ffmpeg:virtual?video&size=1280x720#video=h264" front_door: rtsp://<camera-username>:<camera-password>@<camera-ip>:554/stream1After you edit /etc/go2rtc/go2rtc.yaml, apply the change and reload the dashboard in your browser:
sudo systemctl restart go2rtc.servicego2rtc connects to the camera on demand when a viewer opens the stream, and republishes it over WebRTC, MSE, HLS, MJPEG and RTSP without any further changes to the camera.
Server components
The following table lists the key components and their paths.
Component Path
go2rtc binary /opt/go2rtc/go2rtc
Configuration /etc/go2rtc/go2rtc.yaml
Configuration template (for firstboot) /etc/go2rtc/go2rtc.yaml.template
Systemd unit /etc/systemd/system/go2rtc.service
Firstboot script /usr/local/sbin/go2rtc-firstboot.sh
nginx TLS reverse proxy /etc/nginx/sites-available/sac-go2rtc
Self-signed TLS certificate /etc/nginx/tls/go2rtc.crt
Per-instance credentials note /root/go2rtc-credentials.txt (mode 0600)
Sentinel /var/lib/sac/data/go2rtc-firstboot.done
/opt/go2rtc/go2rtc --version sudo ls /opt/go2rtc/go2rtc /etc/go2rtc/go2rtc.yaml /etc/systemd/system/go2rtc.service
UN=$(sudo grep '^go2rtc.username=' /root/go2rtc-credentials.txt | cut -d= -f2-)
PW=$(sudo grep '^go2rtc.password=' /root/go2rtc-credentials.txt | cut -d= -f2-)
curl -sk -u "$UN:$PW" https://127.0.0.1/api/streams | jq 'keys'go2rtc reports version 1.9.14, the component paths exist, and the API lists the configured streams:
go2rtc version 1.9.14 (b5948cf) linux/amd64 /etc/go2rtc/go2rtc.yaml /etc/systemd/system/go2rtc.service /opt/go2rtc/go2rtc [ "demo" ]Manage the service
sudo systemctl restart go2rtc.service
sudo journalctl -u go2rtc.service --no-pager -n 20go2rtc restarts in well under a second because it is a single binary with no database. The service is hardened with NoNewPrivileges, ProtectSystem=full, ProtectHome and PrivateTmp. It has write access only to its own configuration directory, so the web UI can save the streams you add.
Configuration
go2rtc is configured entirely through /etc/go2rtc/go2rtc.yaml. The following table lists the key sections that this image sets.
Section Meaning Image default
api.listen Web UI and API bind address 127.0.0.1:1984 (loopback)
api.local_auth Force Basic auth on every request true
api.username / api.password Per-instance credential (generated at first boot) unique per instance
rtsp.listen RTSP restream server :8554
webrtc.listen WebRTC media :8555
webrtc.candidates Public address discovery stun:8555
streams Named streams and their sources the demo stream
After editing the file, apply changes by restarting the go2rtc service. nginx is the sole public listener and terminates TLS; go2rtc never binds a public port for its UI.
Change the UI password
The credential is generated per instance at first boot. To set your own, edit api.username and api.password in the configuration and restart go2rtc, replacing <new-password> with your password:
sudo sed -i 's/^ password:.*/ password: "<new-password>"/' /etc/go2rtc/go2rtc.yaml
sudo systemctl restart go2rtc.serviceUpdate /root/go2rtc-credentials.txt to match so that your note stays accurate, and keep that file readable only by root.
Add a real TLS certificate (optional)
The image ships a per-instance self-signed certificate so that the UI is encrypted out of the box. For production, point a DNS record at the instance and install a certificate from Let's Encrypt so that browsers trust it without a warning:
sudo apt-get install -y certbot
sudo certbot certonly --standalone -d <your-domain>
sudo sed -i 's#/etc/nginx/tls/go2rtc.crt#/etc/letsencrypt/live/<your-domain>/fullchain.pem#; s#/etc/nginx/tls/go2rtc.key#/etc/letsencrypt/live/<your-domain>/privkey.pem#' /etc/nginx/sites-available/sac-go2rtc
sudo systemctl reload nginxcertbot obtains the certificate and sets up automatic renewal, so your credentials and streams travel over a trusted TLS connection.
Security recommendations
- Restrict the security group so that ports 443, 22 and the streaming ports reach only trusted networks. Do not expose an unauthenticated camera gateway to the public internet.
- Keep the API on loopback. The image binds go2rtc to
127.0.0.1behind nginx. Do not expose port 1984 directly. - Change the credential (Step 15) and keep the note
/root/go2rtc-credentials.txtreadable only by root. - Use a real certificate (Step 16) so that the per-instance credential and your camera streams travel over trusted TLS.
- Secure your cameras too. Give each camera its own account, and restrict which networks can reach the RTSP and WebRTC ports.
- Patch the OS regularly with
sudo apt-get update && sudo apt-get upgrade. Unattended security upgrades are already enabled.
Support and licensing
go2rtc is MIT licensed, with no per-CPU or per-user fee. SecureAnyCloud provides commercial support separately.
- Email: sales@secureanycloud.com
- Website: secureanycloud.com
- Support hours: 24/7, with a 24-hour response SLA
Support
SecureAnyCloud provides 24/7/365 expert technical support for this image, with a guaranteed response within 24 hours and a one-hour average for critical issues. Contact sales@secureanycloud.com.
For general go2rtc questions, consult the project documentation at https://github.com/AlexxIT/go2rtc. go2rtc is a trademark of its respective owner. It is named here only to identify the software and does not imply affiliation or endorsement.
Deploy on AWS
Launch go2rtc 1.9.14 on Ubuntu 24.04 LTS on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com