Skip to content

Docker deployment ​

Docker delivery is currently a local candidate, with no formal image download or registry address. These steps apply to a validation environment where the deployment maintainer has already prepared the local image and an application administrator account. leelaa-strm:local refers only to that local candidate; it is never pulled from a registry.

For fnOS installation, see Install and upgrade. Installation steps for ordinary Docker users will be added once formal image distribution and initial-account delivery are ready.

You need Docker Engine and Compose v2 or later. The current local candidate has been validated on linux/arm64; the deployment maintainer must confirm that the image matches the target architecture. The runtime host must provide a valid Linux /etc/machine-id. With a Linux VM, this is the VM's identity.

1. Prepare a deployment directory ​

Once the local image and administrator account are ready, prepare a deployment directory on the Docker host:

bash
mkdir -p "$HOME/leelaa-strm"
cd "$HOME/leelaa-strm"
mkdir -p data media
printf 'PUID=%s\nPGID=%s\n' "$(id -u)" "$(id -g)" > .env

PUID and PGID must match the owner of these directories. Running the commands as a regular user keeps them aligned. For an existing NAS share, use its actual UID/GID rather than making it writable by everyone.

Bind paths must exist on the Docker daemon host. With a remote daemon or a VM that does not share this directory, create the directories on that host and set STRM_DATA_DIR and STRM_OUTPUT_DIR to their absolute paths in .env; for docker run, set those environment variables before the command. The identity file also belongs to the daemon host. See Docker's bind-mount guidance.

2. Use Compose ​

Save the following configuration as compose.yml in the deployment directory, or download compose.yml and place it there.

yaml
name: leelaa-strm
services:
  strm:
    image: leelaa-strm:local
    pull_policy: never
    container_name: ${STRM_CONTAINER_NAME:-leelaa-strm}
    user: "${PUID:-10001}:${PGID:-10001}"
    restart: unless-stopped
    ports:
      - "${STRM_BIND_ADDRESS:-127.0.0.1}:${STRM_HTTP_PORT:-8690}:8690"
    volumes:
      - type: bind
        source: ${STRM_DATA_DIR:-./data}
        target: /data
        bind:
          create_host_path: false
      - type: bind
        source: ${STRM_OUTPUT_DIR:-./media}
        target: /media
        bind:
          create_host_path: false
      - type: bind
        source: ${STRM_MACHINE_ID_FILE:-/etc/machine-id}
        target: /run/host/machine-id
        read_only: true
        bind:
          create_host_path: false
    read_only: true
    tmpfs:
      - /tmp:rw,noexec,nosuid,size=16m
    cap_drop:
      - ALL
    security_opt:
      - no-new-privileges:true
    stop_grace_period: 20s

Start and inspect it from that directory:

bash
docker compose -f compose.yml up -d
docker compose -f compose.yml ps
docker compose -f compose.yml logs --tail=50

Or use docker run ​

With the local candidate image ready, run this in the deployment directory containing data and media:

sh
#!/bin/sh
set -eu

docker run -d \
  --name "${STRM_CONTAINER_NAME:-leelaa-strm}" \
  --pull never \
  --restart unless-stopped \
  --user "${PUID:-$(id -u)}:${PGID:-$(id -g)}" \
  --network "${STRM_DOCKER_NETWORK:-bridge}" \
  --publish "${STRM_BIND_ADDRESS:-127.0.0.1}:${STRM_HTTP_PORT:-8690}:8690" \
  --mount "type=bind,source=${STRM_DATA_DIR:-$(pwd)/data},target=/data" \
  --mount "type=bind,source=${STRM_OUTPUT_DIR:-$(pwd)/media},target=/media" \
  --mount "type=bind,source=${STRM_MACHINE_ID_FILE:-/etc/machine-id},target=/run/host/machine-id,readonly" \
  --read-only \
  --tmpfs /tmp:rw,noexec,nosuid,size=16m \
  --cap-drop ALL \
  --security-opt no-new-privileges:true \
  --stop-timeout 20 \
  leelaa-strm:local

You can also download the startup script. Choose one method: both use the same container name and port.

First sign-in ​

Open http://127.0.0.1:8690. Docker uses application account/password sign-in and does not offer NAS sign-in.

Sign in with the application administrator account supplied by the deployment maintainer, complete the required initial password change, then open application licensing and cloud setup. Contact the maintainer if you have not received an account; the Docker candidate does not yet offer an initial-account delivery flow for ordinary users. The app administrator creates members; NAS administrator status grants no Docker application privileges.

LAN access and playback address ​

Access defaults to the host's loopback interface. To allow LAN access, add these settings to Compose's .env, then recreate with the original Compose command:

dotenv
STRM_BIND_ADDRESS=0.0.0.0
STRM_HTTP_PORT=8690

For docker run, set the same environment variables before the command. Open http://your-NAS-LAN-address:8690. Use this on a trusted LAN; public access requires separate HTTPS and access controls.

Save an address reachable by players in Settings → Playback service address, such as http://your-NAS-LAN-address:8690. LAN players cannot use 127.0.0.1. Independent players still follow playback authorization; an additional listener also needs its own explicit Docker port mapping.

Data, upgrades and license identity ​

MountPurpose
./data → /dataComplete application state: accounts, cloud credentials, targets, records, installation and licensing data
./media → /mediaGenerated STRM and metadata for downstream apps to scan read-only
Host /etc/machine-id → /run/host/machine-idRead-only host identity used by the shared licensing SDK

Give downstream apps read-only access to media with the same file-access UID or explicit read permission. Do not expose data to players.

Stop the container and back up data, media and deployment configuration together before upgrading. Once the maintainer has prepared a new candidate image for the same architecture, return to the original deployment directory and run:

bash
docker compose -f compose.yml up -d --force-recreate

Keep the original directories, UID/GID and host identity mount to retain accounts and the installation. License validity, revocation and platform rules still apply. A new NAS or recreated VM requires the official recovery flow; a bare device ID does not automatically restore a license.

Startup problems ​

  • Machine-id error: check the Docker host's valid identity file and read-only mount. Set STRM_MACHINE_ID_FILE in .env for a different location. The container never generates a replacement device identity.
  • Missing or unwritable directory: check data, media and their PUID/PGID ownership. Keep existing data while fixing access.
  • Occupied port: preserve the existing service, choose a free STRM_HTTP_PORT, and update the playback service address.
  • To stop, run docker compose -f compose.yml stop in the deployment directory. Stopping does not delete mounted data or original 115 files.