GiVo Server for Linux & NAS

Run the DVR companion headless on any Linux machine or NAS — Synology, Unraid, a home server, a Raspberry Pi, or Docker Desktop on a Mac or PC. Same full DVR as the desktop apps: recording, scheduling, catchup, live timeshift, commercial skip, and automatic captions for every paired device. Everything runs on x86-64 (amd64) and ARM (arm64).

Contents

  1. Docker Compose — Linux & NAS (recommended)
  2. Docker Desktop — Mac & Windows
  3. Synology (Container Manager)
  4. Unraid
  5. Native Linux binary (systemd)
  6. Pairing — codes, rotation & fixed codes
  7. Host vs. bridge networking
  8. Commercial skip & auto captions
  9. Storage, backups & updates
  10. All settings

1. Docker Compose — Linux & NAS (recommended)

Create a folder for the server, add this docker-compose.yml, and start it:

services:
  givo-server:
    image: ghcr.io/gjdigitaldev/givo-server:latest
    container_name: givo-server
    network_mode: host
    environment:
      - GIVO_NAME=GiVo DVR
      # Recommended when pairing several devices — see “Pairing” below:
      # - GIVO_PASSWORD=123456
      # Optional post-recording passes — see “Commercial skip & auto captions”:
      # - GIVO_COMMERCIAL_SKIP=true
      # - GIVO_WHISPER_CAPTIONS=true
      # - GIVO_WHISPER_MODEL=distil-large-v3
    volumes:
      - ./config:/config
      - ./recordings:/recordings
    restart: unless-stopped
mkdir -p config recordings
docker compose up -d
docker compose logs givo-server

The logs command prints the server's startup banner — your pairing code is in it.

That's the whole install. Point ./recordings at your big disk — that's where recordings are written — then jump to Pairing.

2. Docker Desktop — Mac & Windows

Never used Docker or a terminal? Start here.

  1. Install Docker Desktop (free) from docker.com, then open it. Wait until it says it's running (Mac: the whale icon in the menu bar; Windows: the whale in the system tray). Every command below fails if Docker Desktop isn't running.
  2. Open a command window. Mac: press Cmd + Space, type Terminal, press Return. Windows: open the Start menu, type cmd, press Enter (Command Prompt).
  3. Use the Copy button in the corner of each command box below, paste into the command window, and press Return. A command that spans several lines ending in \ is still ONE command — always copy and paste the whole box, never a single line from inside it.
  4. Success often looks like nothing. Some commands print nothing at all when they work; each box below says what you should see.

Docker Desktop doesn't support host networking the way Linux does, so use published ports (bridge).

First: is the GiVo Server desktop app also running on this same computer? If yes, skip the block below and use the alternate-port command further down — the desktop app already owns ports 8088/8090, so this first command will fail with "address already in use." If no, carry on. In a terminal:

mkdir -p ~/givo-server/config ~/givo-server/recordings
docker run -d --name givo-server \
  -p 8088:8088 -p 8090:8090 \
  -v ~/givo-server/config:/config \
  -v ~/givo-server/recordings:/recordings \
  ghcr.io/gjdigitaldev/givo-server:latest
docker logs givo-server

What you should see: the first command prints nothing (that's success). The docker run command downloads the server the first time (a minute of progress lines), then prints one long string of random letters and numbers — that string means it started. The logs command prints the server's startup banner — your pairing code is in it. To double-check it's running at any time, run docker ps: you should see a givo-server row whose STATUS starts with "Up".

On Windows, use these one-line versions in Command Prompt instead (the multi-line \ style above is Mac/Linux shell syntax):

mkdir "%USERPROFILE%\givo-server\config" "%USERPROFILE%\givo-server\recordings"
docker run -d --name givo-server -p 8088:8088 -p 8090:8090 -v "%USERPROFILE%\givo-server\config:/config" -v "%USERPROFILE%\givo-server\recordings:/recordings" ghcr.io/gjdigitaldev/givo-server:latest

With bridge networking the server is not auto-discovered — in the GiVo app choose Add Server Manually and enter the computer's IP address and port 8088.

Port 8088 already in use? (For example, the GiVo Server desktop app is also running on the same machine.) Move the server to another port — set GIVO_PORT and publish the same numbers on both sides, keeping the second port at API port + 2:

docker run -d --name givo-server \
  -e GIVO_PORT=18088 \
  -p 18088:18088 -p 18090:18090 \
  -v ~/givo-server/config:/config \
  -v ~/givo-server/recordings:/recordings \
  ghcr.io/gjdigitaldev/givo-server:latest

The -e GIVO_PORT=18088 line is what moves the server itself to the new port — don't drop it. Without it the server keeps listening on 8088 inside the container and the published 18088 port leads nowhere, so the container runs but pairing can't connect. (Windows one-line version:)

docker run -d --name givo-server -e GIVO_PORT=18088 -p 18088:18088 -p 18090:18090 -v "%USERPROFILE%\givo-server\config:/config" -v "%USERPROFILE%\givo-server\recordings:/recordings" ghcr.io/gjdigitaldev/givo-server:latest

Already ran the wrong command? No harm done — remove the attempt and start over. This is always safe (your recordings and settings live in the givo-server folders, not in the container):

docker rm -f givo-server

Common errors, decoded:

Then pair by IP with port 18088. (Mismatched inside/outside numbers — like -p 18088:8088 — will pair and record fine but break casting, so prefer the same-number form above.)

3. Synology (Container Manager)

On DSM 7.2+ with Container Manager installed:

  1. Open Container Manager → Registry, search for gjdigitaldev/givo-server on ghcr.io and download the latest tag. (If your DSM can't search ghcr, add it via Project → paste the compose file from section 1 instead — that's often the easier path.)
  2. Create two shared-folder locations first in File Station, e.g. /docker/givo-server/config and a recordings folder on your big volume, e.g. /video/GiVo Recordings.
  3. Container Manager → Container → Create from the image. In the wizard:
    • Network: select Use the same network as Docker Host if available — auto-discovery and casting then just work. Otherwise keep bridge and add port mappings 8088 → 8088 and 8090 → 8090 (TCP, same numbers on both sides).
    • Volumes: map /docker/givo-server/config/config and your recordings folder → /recordings.
    • Environment: optionally add GIVO_NAME, GIVO_PASSWORD (fixed pairing code), and the feature toggles from section 8.
    • Enable auto-restart.
  4. Start the container, open its Log tab, and read the pairing code from the banner. With bridge networking, pair via Add Server Manually using the NAS IP and port 8088.

4. Unraid

Until a Community Applications template lands, add the container from the Docker tab (Add Container) or a terminal. The equivalent docker run:

docker run -d --name givo-server \
  --network host \
  -e GIVO_NAME="GiVo DVR" \
  -v /mnt/user/appdata/givo-server:/config \
  -v "/mnt/user/media/GiVo Recordings":/recordings \
  --restart unless-stopped \
  ghcr.io/gjdigitaldev/givo-server:latest

In the Add Container form that maps to: Repository ghcr.io/gjdigitaldev/givo-server:latest, Network Type Host, a path mapping for /config/mnt/user/appdata/givo-server, a path mapping for /recordings → your media share, plus any GIVO_* variables. Host networking is the Unraid-typical choice and keeps auto-discovery + casting working; if you use a custom bridge instead, publish 8088 and 8090 at the same numbers and pair by IP. Read the pairing code with docker logs givo-server (or the container's log icon in the UI).

5. Native Linux binary (systemd)

Prefer no Docker? Download GiVo-Server-Linux-amd64.tar.gz or GiVo-Server-Linux-arm64.tar.gz. Each contains static binaries (the server plus the commercial-skip and caption engines), a README with step-by-step instructions, and a ready-made givo-server.service systemd unit. The only requirement is ffmpeg from your distribution:

sudo apt install ffmpeg          # Debian/Ubuntu (dnf/pacman equivalents work too)
tar xzf GiVo-Server-Linux-amd64.tar.gz && cd givo-server-linux-amd64
sudo useradd --system --home-dir /var/lib/givo-server --shell /usr/sbin/nologin givo
sudo mkdir -p /opt/givo-server /var/lib/givo-server/recordings
sudo cp givo-server comskip comskip.ini whisper-cli /opt/givo-server/
sudo chown -R givo:givo /var/lib/givo-server
sudo cp givo-server.service /etc/systemd/system/
sudo systemctl daemon-reload && sudo systemctl enable --now givo-server
journalctl -u givo-server | grep "PAIRING CODE" | tail -1

Keep givo-server, comskip, comskip.ini, and whisper-cli in the same directory — the server finds the feature binaries beside itself. Point --recordings-dir in the unit file at a big disk.

Updating the native binary (build 37 and later): the server updates itself in place —

sudo givo-server update --check    # see what's available
sudo givo-server update            # download, verify, swap & restart

The update command never interrupts a recording — if one is running it waits and tells you to retry, and the previous binary is kept beside the new one as givo-server.previous in case you ever want to roll back. Prefer it fully automatic? The tarball ships an optional givo-server-update.timer systemd unit (off by default) that checks once a day — enable it with sudo systemctl enable --now givo-server-update.timer. See §6 of the bundled README for details.

6. Pairing — codes, rotation & fixed codes

The server prints a six-digit pairing code in its logs, inside a clearly marked banner:

docker logs givo-server
...
[Server]  ==============================================================
[Server]    GiVo DVR is ready.
[Server]    PAIRING CODE:  481523
[Server]    API:           https://<this machine's LAN IP>:8088
...

On each iPhone, iPad, or Apple TV (same network):

  1. In GiVo Stream, open DVR → DVR Server.
  2. If the server appears automatically, select it. If not (normal with bridge networking), choose Add Server Manually and enter the machine's IP address and port 8088.
  3. Enter the pairing code. Pairing is one-time per device.

The code rotates. For security, the random pairing code changes after every successful pairing — the code that paired your iPhone will not pair your Apple TV. Re-read the current code right before pairing each device:

Docker:

docker logs givo-server | grep "PAIRING CODE" | tail -1

systemd:

journalctl -u givo-server | grep "PAIRING CODE" | tail -1

(Each prints just the newest code — any codes above it in the full log are already used up.)

Pairing several devices? Set a fixed code — it never rotates, so every device uses the same one. Pick your own six digits. These are settings, not commands — a bare -e GIVO_PASSWORD=… pasted on its own does nothing. Add the setting where your setup defines the server, then restart it:

Docker Compose — un-comment (or add) the line in your docker-compose.yml, then re-run docker compose up -d:

    environment:
      - GIVO_PASSWORD=123456

docker run — a container's settings can't be changed while it exists, so remove it and run it again with the extra -e line included. Devices you already paired STAY paired (pairings live in the config folder, which survives):

docker rm -f givo-server

⚠️ A run command replaces ALL of your settings — copy the block that matches YOUR setup (and keep any other lines yours uses).

Standard setup (port 8088):

docker run -d --name givo-server \
  -e GIVO_PASSWORD=123456 \
  -p 8088:8088 -p 8090:8090 \
  -v ~/givo-server/config:/config \
  -v ~/givo-server/recordings:/recordings \
  ghcr.io/gjdigitaldev/givo-server:latest

Alternate-port setup from section 2 (the GiVo Server desktop app also runs on this computer):

docker run -d --name givo-server \
  -e GIVO_PORT=18088 \
  -e GIVO_PASSWORD=123456 \
  -p 18088:18088 -p 18090:18090 \
  -v ~/givo-server/config:/config \
  -v ~/givo-server/recordings:/recordings \
  ghcr.io/gjdigitaldev/givo-server:latest

systemd — add this line in the [Service] section of givo-server.service, then sudo systemctl daemon-reload && sudo systemctl restart givo-server:

Environment=GIVO_PASSWORD=123456

Treat the fixed code like a password for your DVR — anyone on your network who has it can pair.

7. Host vs. bridge networking

Host networking (Linux/NAS only) is the simple path: automatic discovery works, casting to AirPlay and Chromecast devices works, no port bookkeeping.

Bridge networking (Docker Desktop, Synology's default, custom bridges) also works — publish both ports at the same numbers and pair by IP:

    ports:
      - "8088:8088"   # API
      - "8090:8090"   # casting relay (always API port + 2)

8. Commercial skip & auto captions

The Linux build ships the same optional post-recording passes as the macOS and Windows apps: commercial skip (powered by Comskip) and automatic captions (speech-to-text via Whisper) for recordings without broadcast captions. Both are off by default — they are CPU-heavy passes that run after each recording finishes — and recordings themselves are never delayed by them.

Docker Compose — un-comment (or add) these lines in your docker-compose.yml, then re-run docker compose up -d:

    environment:
      - GIVO_COMMERCIAL_SKIP=true
      - GIVO_WHISPER_CAPTIONS=true
      - GIVO_WHISPER_MODEL=distil-large-v3

docker run — settings can't be added to an existing container, so remove it and run it again with the extra lines (recordings, pairings, and settings all survive — they live in your givo-server folders):

docker rm -f givo-server

⚠️ A run command replaces ALL of your settings — copy the block that matches YOUR setup. If your command has other lines (a fixed pairing code, a different name), keep them too.

Standard setup (port 8088):

docker run -d --name givo-server \
  -e GIVO_COMMERCIAL_SKIP=true \
  -e GIVO_WHISPER_CAPTIONS=true \
  -e GIVO_WHISPER_MODEL=distil-large-v3 \
  -p 8088:8088 -p 8090:8090 \
  -v ~/givo-server/config:/config \
  -v ~/givo-server/recordings:/recordings \
  ghcr.io/gjdigitaldev/givo-server:latest

Alternate-port setup from section 2 (the GiVo Server desktop app also runs on this computer):

docker run -d --name givo-server \
  -e GIVO_PORT=18088 \
  -e GIVO_COMMERCIAL_SKIP=true \
  -e GIVO_WHISPER_CAPTIONS=true \
  -e GIVO_WHISPER_MODEL=distil-large-v3 \
  -p 18088:18088 -p 18090:18090 \
  -v ~/givo-server/config:/config \
  -v ~/givo-server/recordings:/recordings \
  ghcr.io/gjdigitaldev/givo-server:latest

Caption model tiers (pick one with GIVO_WHISPER_MODEL; approximate one-time download):

First-enable behavior: the model downloads automatically the first time captions are enabled — watch progress in the container log. It lands in /config/models on your config volume and is kept there permanently, so container updates and restarts never re-download it. Captions appear on new recordings once the model is ready. On modest CPUs a transcription can take a large fraction of the recording's length; passes queue one at a time so recording is never starved.

Commercial skip needs no download — enable it and skip points appear on new recordings (and can be added to older ones from the app). Comskip is GPL-licensed; its license and notice ship inside the image and tarballs.

9. Storage, backups & updates

10. All settings

Every setting is available as an environment variable (handy in compose) or a command-line flag; flags win over environment:

Questions or stuck? We're happy to help — support@givostreamapp.com or the Discord.