Deployment guide

Kyoo

Overview

Kyoo is an open-source, self-hosted media server for a personal collection of movies and TV, in the same space as Jellyfin and Plex. Point it at a folder of video files and it scans them, then matches each title against online metadata providers for posters, summaries, cast and episode details. The result is a browsable library in a web client.

You stream to your browser with on-the-fly transcoding, so a file plays smoothly even when its original format or bitrate does not suit the device or the connection.

Kyoo is built from cooperating services: a web front end, a library API, a filesystem scanner and matcher, a transcoder and a database, all behind a single reverse proxy. This SecureAnyCloud image runs them the officially supported way, as the upstream containers pinned by image digest and captured into the VM, so your instance starts in seconds without downloading anything.

Kyoo's sample configuration ships published default secrets: a database password of password, a fixed sample scanner key and an open first user. On a reachable server, those would be an obvious risk. This image never runs on them. On the first boot of every VM, it generates a fresh database password, a fresh scanner key and a fresh administrator account with a random password. Unauthenticated visitors are locked out until they sign in.

What you get:

  • Kyoo v5.1.0 (the GPL-3.0 licensed media server), run as seven official upstream containers pinned by image digest
  • The Kyoo web UI, library API, auth service, filesystem scanner and matcher, and CPU transcoder
  • PostgreSQL 18 as the datastore and Traefik v3.6 as the single public reverse proxy on port 80
  • Docker Engine, with every service except the Traefik front door reachable only on a private internal network
  • kyoo-firstboot.service, kyoo.service and kyoo-postboot.service as systemd units, enabled and active on boot
  • A per-VM PostgreSQL password, a per-VM scanner key and a per-VM admin account, all generated on first boot and never baked into the image
  • Metadata enrichment that works out of the box, with no third-party key to obtain
  • A short pre-loaded demo title, so your library shows a real, scannable, streamable item the moment the VM boots
  • An Ubuntu 24.04 LTS base with the latest security patches applied at build time and unattended security upgrades enabled
  • 24/7 SecureAnyCloud support

Kyoo is a trademark of its respective owner. This image is produced by SecureAnyCloud and is not affiliated with, endorsed by, or sponsored by the Kyoo project, Traefik, PostgreSQL, TheMovieDB or TheTVDB. It ships the free and open-source software unmodified.

Metadata without a key

Kyoo enriches your library (posters, summaries, cast) with data from TheMovieDB and, optionally, TheTVDB. Supplying your own provider key is entirely optional. The upstream image bundles a default TheMovieDB read token, so scanning and matching work with nothing more than outbound internet access.

The demo title in this guide is matched to its real poster and details with no key configured. To use your own read access token, or to add a TheTVDB key, see Step 11.

Sizing: what this really needs

Kyoo browses and direct plays comfortably on a modest VM, but transcoding is CPU-heavy. When a file's format or bitrate does not suit the client, the transcoder re-encodes it in software in real time. 1080p and above is genuinely demanding.

  • Browsing, metadata, single direct play (no re-encode): Standard_B2s (2 vCPU) is enough for a trial
  • Real use, one or two concurrent transcodes: Standard_B4ms (4 vCPU), the recommended size
  • Several concurrent transcodes: a non-burstable D series, Standard_D4s_v5 or larger

Two practical points:

  • Prefer a non-burstable size for regular use. B series VMs are credit-limited. Sustained transcoding exhausts the credits and then throttles, and playback stutters. B series is fine for trying the image out and for light direct play. A D series sustains heavy concurrent transcoding far better.
  • The transcoder is CPU-only here. A generic VM has no GPU, so all re-encoding is done in software. That is why concurrency, not library size, drives the sizing.

Prerequisites

You need:

  • An Azure subscription with permission to create VMs and edit network security groups
  • The Azure CLI, installed and signed in, if you deploy from the command line
  • An SSH key pair for administrative access to the VM
  • A modern browser on the viewing side
1

Deploy from the Azure Portal

  • In the Azure Portal, search the Marketplace for Kyoo on Ubuntu 24.04 LTS by SecureAnyCloud and select Create.
  • Choose your subscription, resource group and region.
  • Set the VM size to Standard_B4ms or larger (see the sizing guidance above).
  • Provide an administrator username and SSH public key.
  • On the Networking tab, allow inbound HTTP (80). That single port is the whole public surface of this image.
  • Review and create the VM.
2

Deploy from the Azure CLI

Run these commands on your own machine. Replace the resource group, name and region to suit.

az group create --name kyoo-rg --location eastus
az vm image terms accept --urn sac1647283583153:kyoo-ubuntu-24-04:default:latest
az vm create \
  --resource-group kyoo-rg \
  --name kyoo-vm \
  --image sac1647283583153:kyoo-ubuntu-24-04:default:latest \
  --size Standard_B4ms \
  --admin-username azureuser \
  --generate-ssh-keys \
  --public-ip-sku Standard
# open port 80, the only port this image needs:
az vm open-port --resource-group kyoo-rg --name kyoo-vm --port 80 --priority 1001

To restrict access to your own network instead of the whole internet, add --source-address-prefixes <your.public.ip>/32 to the rule. Because your library is personal, this is recommended.

3

Connect to your VM

Connect over SSH as azureuser:

ssh azureuser@<vm-ip>
4

Confirm the services are running

Check the systemd units:

systemctl is-active docker.service kyoo-firstboot.service kyoo.service kyoo-postboot.service

Every line should read active. Docker Compose manages the seven containers, and PostgreSQL reports its health through its own Compose healthcheck:

sudo docker compose -f /etc/kyoo/docker-compose.yml ps

You should see front, auth, api, scanner, transcoder, traefik and postgres all Up, with postgres marked (healthy).

5

Read the per instance credentials

On first boot, a random administrator password was generated for this VM alone. The account was registered as the first Kyoo user, which upstream grants administrator rights. The credentials are stored in a root-only file. Read it:

sudo cat /root/kyoo-credentials.txt

The file records three values:

  • ADMIN_USERNAME: the administrator login, admin
  • ADMIN_PASSWORD: the per-instance administrator password
  • WEB_URL: the address to open in your browser

The file is 0600 root:root, so only root can read it. Confirm the permissions:

sudo stat -c '%a %U:%G' /root/kyoo-credentials.txt

The per-VM database password and scanner key live in the environment file, also 0600 root:root. Their values are never displayed. Confirm that the file exists with the right permissions:

sudo stat -c '%a %U:%G' /etc/kyoo/.env
6

Verify the security model

Every service other than the Traefik front door runs on a private internal network with no public port. Only port 80 is bound to the outside world. List the listening sockets:

ss -tln

You see 0.0.0.0:80 and [::]:80 and nothing else public. PostgreSQL (5432), the auth service (4568) and the API (5000/3567) are reachable only inside the Docker network.

The library API refuses unauthenticated access. An anonymous request for the video list is rejected, and so is a request that carries an invalid token:

curl -s -o /dev/null -w 'no token: HTTP %{http_code}\n' http://127.0.0.1/api/videos
curl -s -o /dev/null -w 'invalid token: HTTP %{http_code}\n' \
  -H 'Authorization: Bearer definitely-wrong-token' http://127.0.0.1/api/videos

The first request returns 401 (no credentials). The second returns 403 (the token is rejected). Guest access is disabled by default, so a visitor must sign in before browsing or playing anything.

7

Run the end-to-end self-test

The image ships a self-test that exercises the whole path with the real per-VM administrator account. It signs in, confirms that the API is reachable only with a valid token, triggers a library scan, finds the pre-loaded demo title, and streams real bytes back from it. Run it:

sudo /usr/local/sbin/kyoo-roundtrip.sh

It prints a single OK round-trip: line that reports the streamed byte count. A title that you just scanned appears in the library and returns real media bytes. That proves the scanner, database, API and transcoder work together.

8

Open Kyoo and sign in

Open http://<vm-ip>/ in your browser. Kyoo shows its sign-in page.

Sign in with ADMIN_USERNAME and ADMIN_PASSWORD from the credentials file in Step 5. Then select Browse in the top navigation to open your library.

9

Browse your library

The Browse view is your library. On a fresh VM it already contains the pre-loaded demo title, scanned and matched to its real poster and details with no metadata key configured.

Select a title to open its detail page. It shows the backdrop, poster, synopsis, rating, runtime, genres and cast that the scanner pulled from the metadata providers.

10

Play a title

On the detail page, select Play. The title streams to your browser. The transcoder re-encodes on the fly where needed, so you do not have to prepare the file in any way.

11

Add your own media

The demo title lives under /var/lib/kyoo/media on the VM. Add your own films and series to that folder, then rescan. From your own machine, copy the files onto the VM and move them into the library folder:

scp "My Film (2021).mkv" azureuser@<vm-ip>:/tmp/ ssh azureuser@<vm-ip> 'sudo mv "/tmp/My Film (2021).mkv" /var/lib/kyoo/media/ && sudo chmod -R a+rX /var/lib/kyoo/media'

Name files so the scanner can match them. Title (Year).ext works well for films. You can delete the demo clip once your own media is in place.

Trigger a rescan in the web UI under Admin, or wait for the scanner to pick up new files on its next pass.

To use your own TheMovieDB read access token, or to add a TheTVDB key, edit the environment file and restart Kyoo:

sudo sed -i 's#^THEMOVIEDB_API_ACCESS_TOKEN=.*#THEMOVIEDB_API_ACCESS_TOKEN=<your-token>#' /etc/kyoo/.env
sudo systemctl restart kyoo.service
12

Manage the service

Check the status of the stack:

sudo systemctl status kyoo.service --no-pager

Restart the whole stack:

sudo systemctl restart kyoo.service

View the logs of one service, for example the scanner:

sudo docker compose -f /etc/kyoo/docker-compose.yml logs --tail 40 scanner
13

Use your own domain and HTTPS

For anything beyond a trial, put a real host name and a certificate in front of Traefik. Kyoo serves only HTTP on port 80 to the outside. The simplest robust approach is to run a TLS-terminating reverse proxy, or a cloud load balancer, in front of the VM and forward to port 80.

Serve over HTTPS for any deployment reachable from the internet. Some browser playback features also expect a secure context.

14

Security recommendations

  • Restrict the source addresses on the network security group rule to your own network wherever you can. Your library is personal.
  • Treat the admin password as privileged. The first user is an administrator and can manage the library, users and scans.
  • Keep new users in check. Self-registered users are unverified and have no access until an administrator verifies them. Leave that default in place unless you intend to open the server up.
  • Put HTTPS in front of Kyoo for any internet-facing deployment, as described in Step 13.
  • Keep the OS patched. Unattended security upgrades are enabled on this image by default.
15

Support and Licensing

Kyoo is free and open-source software under the GPL-3.0 licence. The image also includes Traefik (MIT) as the reverse proxy and PostgreSQL (PostgreSQL licence) as the database. Both are used unmodified, as their official upstream containers.

This image is produced by SecureAnyCloud and is not affiliated with, endorsed by, or sponsored by the Kyoo project, Traefik, PostgreSQL, TheMovieDB or TheTVDB. Those names are used only to identify the software included.

For help with the image, contact SecureAnyCloud support, which is available 24/7. For questions about Kyoo itself, see the upstream project at github.com/zoriya/Kyoo.

Deploy on Azure

Launch Kyoo 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

Deploy on Azure