English
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)" > .envPUID 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: 20sStart 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=50Or 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:localYou 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=8690For 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
| Mount | Purpose |
|---|---|
./data → /data | Complete application state: accounts, cloud credentials, targets, records, installation and licensing data |
./media → /media | Generated STRM and metadata for downstream apps to scan read-only |
Host /etc/machine-id → /run/host/machine-id | Read-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-recreateKeep 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_FILEin.envfor a different location. The container never generates a replacement device identity. - Missing or unwritable directory: check
data,mediaand 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 stopin the deployment directory. Stopping does not delete mounted data or original 115 files.