Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
113 commits
Select commit Hold shift + click to select a range
6f435fd
chore 🤖(deps): bump yt-dlp from 2025.2.19 to 2025.3.21
dependabot[bot] Mar 25, 2025
47b551c
Merge pull request #479 from dangeroustech/dependabot/uv/staging/yt-d…
biodrone Mar 25, 2025
e9b1b2a
chore 🤖(deps): bump yt-dlp from 2025.3.21 to 2025.3.25
dependabot[bot] Mar 25, 2025
832b19b
Merge pull request #480 from dangeroustech/dependabot/uv/staging/yt-d…
biodrone Mar 26, 2025
0500d9b
chore 🤖(deps): bump yt-dlp from 2025.3.25 to 2025.3.26
dependabot[bot] Mar 26, 2025
26318e2
Merge pull request #481 from dangeroustech/dependabot/uv/staging/yt-d…
biodrone Mar 27, 2025
8379c5b
chore 🤖(deps): bump yt-dlp from 2025.3.26 to 2025.3.27
dependabot[bot] Mar 28, 2025
5fa4352
Merge pull request #482 from dangeroustech/dependabot/uv/staging/yt-d…
biodrone Mar 30, 2025
3d61db2
chore 🤖(deps): bump yt-dlp from 2025.3.27 to 2025.3.31
dependabot[bot] Apr 1, 2025
fdcc16d
Merge pull request #483 from dangeroustech/dependabot/uv/staging/yt-d…
biodrone Apr 1, 2025
02a9518
chore 🤖(deps): bump streamlink from 7.1.3 to 7.2.0
dependabot[bot] Apr 4, 2025
3afbbd0
Merge pull request #484 from dangeroustech/dependabot/uv/staging/stre…
biodrone Apr 5, 2025
9c43216
chore 🤖(deps): bump wheel from 0.45.1 to 0.46.1
dependabot[bot] Apr 8, 2025
35e8354
Merge pull request #485 from dangeroustech/dependabot/uv/staging/whee…
biodrone Apr 10, 2025
dfe5251
build(deps): bump golang.org/x/net from 0.37.0 to 0.38.0
dependabot[bot] Apr 16, 2025
8b63cc2
Merge pull request #486 from dangeroustech/dependabot/go_modules/gola…
biodrone Apr 27, 2025
bed2ad4
chore 🤖(deps): bump streamlink from 7.2.0 to 7.3.0
dependabot[bot] Apr 29, 2025
7cf91e5
Merge pull request #487 from dangeroustech/dependabot/uv/staging/stre…
biodrone Apr 30, 2025
2c1caf5
chore 🤖(deps): bump yt-dlp from 2025.3.31 to 2025.4.30
dependabot[bot] Apr 30, 2025
26cdbc2
Merge pull request #488 from dangeroustech/dependabot/uv/staging/yt-d…
biodrone May 7, 2025
0599ecd
chore 🤖(deps): bump curl-cffi from 0.10.0 to 0.11.1
dependabot[bot] May 15, 2025
472140b
Merge pull request #489 from dangeroustech/dependabot/uv/staging/curl…
biodrone May 19, 2025
89f3769
chore 🤖(deps): bump grpcio from 1.71.0 to 1.72.1
dependabot[bot] Jun 2, 2025
bb2c4f8
Merge pull request #491 from dangeroustech/dependabot/uv/staging/grpc…
biodrone Jun 5, 2025
07932b1
chore 🤖(deps): bump curl-cffi from 0.11.1 to 0.11.3
dependabot[bot] Jun 9, 2025
a930dfc
chore 🤖(deps): bump yt-dlp from 2025.4.30 to 2025.6.9
dependabot[bot] Jun 10, 2025
42ee95f
chore 🤖(deps): bump grpcio from 1.72.1 to 1.73.0
dependabot[bot] Jun 13, 2025
b9d372a
Merge pull request #494 from dangeroustech/dependabot/uv/staging/curl…
biodrone Jun 14, 2025
9b75f6f
Merge pull request #496 from dangeroustech/dependabot/uv/staging/grpc…
biodrone Jun 16, 2025
06833e4
Merge pull request #495 from dangeroustech/dependabot/uv/staging/yt-d…
biodrone Jun 18, 2025
fe3aa77
chore 🤖(deps): bump curl-cffi from 0.11.3 to 0.11.4
dependabot[bot] Jun 20, 2025
9e6ad91
Merge pull request #497 from dangeroustech/dependabot/uv/staging/curl…
biodrone Jun 22, 2025
4615a13
chore 🤖(deps): bump yt-dlp from 2025.6.9 to 2025.6.25
dependabot[bot] Jun 27, 2025
c3ff240
chore 🤖(deps): bump grpcio from 1.73.0 to 1.73.1
dependabot[bot] Jun 27, 2025
bc17cd5
Merge pull request #498 from dangeroustech/dependabot/uv/staging/yt-d…
biodrone Jun 30, 2025
abe5f13
chore 🤖(deps): bump yt-dlp from 2025.6.25 to 2025.6.30
dependabot[bot] Jul 1, 2025
bd63e94
Merge pull request #499 from dangeroustech/dependabot/uv/staging/grpc…
biodrone Jul 7, 2025
984601b
chore 🤖(deps): bump streamlink from 7.3.0 to 7.5.0
dependabot[bot] Jul 8, 2025
97cb6c2
Merge pull request #501 from dangeroustech/dependabot/uv/staging/stre…
biodrone Jul 9, 2025
c645c01
fix: --twitch--disable-ads is now the default
biodrone Jul 9, 2025
06fe436
Merge pull request #500 from dangeroustech/dependabot/uv/staging/yt-d…
biodrone Jul 11, 2025
a350cbc
chore 🤖(deps): bump curl-cffi from 0.11.4 to 0.12.0
dependabot[bot] Jul 11, 2025
2f024a1
Merge pull request #503 from dangeroustech/dependabot/uv/staging/curl…
biodrone Jul 19, 2025
fa52019
chore 🤖(deps): bump yt-dlp from 2025.6.30 to 2025.7.21
dependabot[bot] Jul 23, 2025
876dc2c
Merge pull request #504 from dangeroustech/dependabot/uv/staging/yt-d…
biodrone Jul 23, 2025
0fcd20f
chore 🤖(deps): bump grpcio from 1.73.1 to 1.74.0
dependabot[bot] Jul 25, 2025
5389eee
Merge pull request #505 from dangeroustech/dependabot/uv/staging/grpc…
biodrone Aug 5, 2025
8e2e32e
chore 🤖(deps): bump curl-cffi from 0.12.0 to 0.13.0
dependabot[bot] Aug 8, 2025
ab797e8
Merge pull request #506 from dangeroustech/dependabot/uv/staging/curl…
biodrone Aug 11, 2025
ef16d88
chore 🤖(deps): update trunk.yaml dependencies
biodrone Aug 11, 2025
908c30a
chore 🤖(gitignore): add .dccache to .gitignore
biodrone Aug 11, 2025
d816e98
fix: yt_dlp error handling bug that caused some plugins to always fail
biodrone Aug 11, 2025
e9cdc75
fix: update gRPC client connection method and increase timeout
biodrone Aug 11, 2025
8aa3642
chore: add go.work file for Go module management
biodrone Aug 11, 2025
a14c088
chore: add go.work.sum file for dependency management
biodrone Aug 11, 2025
1a1c85d
chore: remove go.work and go.work.sum files as they are no longer needed
biodrone Aug 11, 2025
8cd053e
chore: update Go version and dependencies in Dockerfile and go.mod
biodrone Aug 11, 2025
8947e7f
feat: enhance downloadStream function with retry logic and network re…
biodrone Aug 11, 2025
2046aaa
feat: add unit tests for moveFile function and enhance cross-device h…
biodrone Aug 11, 2025
9b9601f
feat: add unit tests for config reader and improve error handling
biodrone Aug 11, 2025
6f336bf
chore 🤖(deps): bump yt-dlp from 2025.7.21 to 2025.8.11
dependabot[bot] Aug 12, 2025
fb7ba73
Merge pull request #508 from dangeroustech/dependabot/uv/staging/yt-d…
biodrone Aug 13, 2025
4f70983
refactor: streamline downloadStream function and enhance logging
biodrone Aug 14, 2025
e358bbd
chore 🤖(deps): bump yt-dlp from 2025.8.11 to 2025.8.20
dependabot[bot] Aug 21, 2025
8a28341
docs: add FFmpeg resilience settings to README
biodrone Aug 24, 2025
80cd495
chore 🤖(deps): update trunk.yaml dependencies and CLI version
biodrone Aug 24, 2025
d45c340
refactor: improve logging format and streamline code readability in s…
biodrone Aug 24, 2025
30d79a5
refactor: improve code readability and consistency in configuration a…
biodrone Aug 24, 2025
e4f66f5
refactor: enhance error handling and logging in downloadStream, moveF…
biodrone Aug 24, 2025
2879e47
chore: pin su-exec version in Dockerfile.client to ensure compatibility
biodrone Aug 24, 2025
1c78826
Merge pull request #509 from dangeroustech/dependabot/uv/staging/yt-d…
biodrone Aug 24, 2025
ab7fb75
chore: implement non-root user and directory permissions in Dockerfiles
biodrone Aug 24, 2025
ba5199a
chore: add health checks and curl installation in Dockerfiles, implem…
biodrone Aug 24, 2025
71d9730
chore: add category parameter for Snyk SARIF file in deploy workflows
biodrone Aug 24, 2025
27c0b55
chore: update category parameter for Snyk SARIF file in deploy workfl…
biodrone Aug 24, 2025
1dafbcd
chore: update category parameter for Snyk SARIF file in deploy workfl…
biodrone Aug 24, 2025
4e38833
chore: rename Docker Scan to Snyk Scan and update scan parameters in …
biodrone Aug 24, 2025
bc00136
chore: update Snyk scan parameters in deploy workflows to include app…
biodrone Aug 24, 2025
edd43a3
chore: remove exclusion of /usr/local/go/** from Snyk scan parameters…
biodrone Aug 24, 2025
9ac837d
chore: update ffmpeg version in Dockerfile.client from 7.1.1 to 8.0
biodrone Aug 24, 2025
627c6b3
chore: add --sarif option to Snyk scan parameters in deploy workflows
biodrone Aug 24, 2025
2fdc5db
fix: update ownership and permissions for app directory and .venv in …
biodrone Aug 24, 2025
7d2cf50
refactor: enhance entrypoint scripts to handle user/group creation an…
biodrone Aug 24, 2025
fbfbff2
refactor: improve entrypoint scripts with debug information and adjus…
biodrone Aug 24, 2025
88bcbee
refactor: streamline entrypoint script by removing redundant ownershi…
biodrone Aug 24, 2025
90c0f04
Revert "refactor: enhance entrypoint scripts to handle user/group cre…
biodrone Aug 24, 2025
624be49
chore: permissions debug
biodrone Aug 24, 2025
047e290
fix: increase default FFMPEG reconnect delay from 5 to 15 seconds
biodrone Aug 24, 2025
f67994f
refactor: simplify entrypoint scripts by removing debug output and co…
biodrone Aug 24, 2025
fa09b48
chore 🤖(deps): bump yt-dlp from 2025.8.20 to 2025.8.27
dependabot[bot] Aug 28, 2025
0b461a5
Merge pull request #511 from dangeroustech/dependabot/uv/staging/yt-d…
biodrone Aug 30, 2025
1feb388
chore 🤖(deps): bump yt-dlp from 2025.8.27 to 2025.9.5
dependabot[bot] Sep 5, 2025
2a7c1e4
Merge pull request #512 from dangeroustech/dependabot/uv/staging/yt-d…
biodrone Sep 9, 2025
31f74d5
fix: update curl package version in Dockerfile.server
biodrone Sep 9, 2025
237605f
chore 🤖(deps): bump streamlink from 7.5.0 to 7.6.0
dependabot[bot] Sep 9, 2025
2a781f3
Merge pull request #513 from dangeroustech/dependabot/uv/staging/stre…
biodrone Sep 9, 2025
245001b
chore 🤖(deps): bump grpcio from 1.74.0 to 1.75.0
dependabot[bot] Sep 16, 2025
da31c91
Merge pull request #514 from dangeroustech/dependabot/uv/staging/grpc…
biodrone Sep 17, 2025
3addabb
chore 🤖(deps): bump grpcio from 1.75.0 to 1.75.1
dependabot[bot] Sep 26, 2025
4cf528a
chore 🤖(deps): bump yt-dlp from 2025.9.5 to 2025.9.26
dependabot[bot] Sep 26, 2025
e7a5c06
Merge pull request #516 from dangeroustech/dependabot/uv/staging/grpc…
biodrone Sep 28, 2025
d9998f8
fix: ensure user cleanup in downloadStream goroutine
biodrone Sep 28, 2025
1ee21c1
Merge pull request #517 from dangeroustech/dependabot/uv/staging/yt-d…
biodrone Sep 28, 2025
9d42c6e
Merge pull request #518 from dangeroustech/fix_list_popping_issue
biodrone Sep 28, 2025
296b3cb
fix: update curl version in Dockerfile.client from 8.14.1-r1 to 8.14.…
biodrone Oct 26, 2025
36b8e28
chore 🤖(deps): bump yt-dlp from 2025.9.26 to 2025.10.22
dependabot[bot] Oct 26, 2025
380a344
Merge pull request #522 from dangeroustech/dependabot/uv/staging/yt-d…
biodrone Oct 26, 2025
b8e1a86
chore 🤖(deps): bump grpcio from 1.75.1 to 1.76.0
dependabot[bot] Oct 26, 2025
617f446
Merge pull request #521 from dangeroustech/dependabot/uv/staging/grpc…
biodrone Oct 26, 2025
cf5b308
chore 🤖(docker): update Go version in Dockerfile.client from 1.24.6 t…
biodrone Nov 2, 2025
3df52bd
chore 🤖(deps): update Dependabot configuration and add GitHub Actions…
biodrone Nov 2, 2025
f25cc42
chore 🤖(ci): refine GitHub Actions validation workflow to improve act…
biodrone Nov 2, 2025
d6ef9e5
chore 🤖(deps): update Dependabot schedule to daily for GitHub Actions
biodrone Nov 2, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,25 @@ updates:
interval: daily
open-pull-requests-limit: 10
target-branch: staging
reviewers:
assignees:
- biodrone
labels:
- dependencies
commit-message:
prefix: chore 🤖
prefix-development: chore 🤖
include: scope
- package-ecosystem: github-actions
directory: /
schedule:
interval: daily
open-pull-requests-limit: 10
target-branch: staging
assignees:
- biodrone
labels:
- dependencies
- github-actions
commit-message:
prefix: chore 🤖
prefix-development: chore 🤖
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/deploy_master.yml
Original file line number Diff line number Diff line change
Expand Up @@ -104,14 +104,14 @@ jobs:
image: dangeroustech/streamdl:${{ matrix.component }}_stable
args: >-
--severity-threshold=critical
--file=Dockerfile.${{ matrix.component }}
--exclude-base-image-vulns
--policy-path=.snyk
--prune-repeated-subdependencies
--package-manager=dockerfile
--app-vulns
--sarif

- name: Upload result to GitHub Code Scanning
uses: github/codeql-action/upload-sarif@v3
continue-on-error: true
with:
sarif_file: snyk.sarif
category: ${{ matrix.component }}-master
10 changes: 6 additions & 4 deletions .github/workflows/deploy_staging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,26 +44,28 @@ jobs:
load: true
tags: streamdl:${{ matrix.component }}_local

- name: Docker Scan
id: docker_scan
- name: Snyk Scan
id: snyk_scan
uses: snyk/actions/docker@master
continue-on-error: true
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
with:
image: streamdl:${{ matrix.component }}_local
args: >-
--severity-threshold=medium
--file=Dockerfile.${{ matrix.component }}
--severity-threshold=critical
--exclude-base-image-vulns
--policy-path=.snyk
--app-vulns
--sarif

- name: Upload result to GitHub Code Scanning
id: snyk_results_upload
uses: github/codeql-action/upload-sarif@v3
continue-on-error: true
with:
sarif_file: snyk.sarif
category: ${{ matrix.component }}-staging-${{ github.event_name }}

- name: Dockerhub Push Staging
id: dockerhub_staging_push
Expand Down
41 changes: 41 additions & 0 deletions .github/workflows/update-actions.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Validate GitHub Actions

on:
schedule:
# Run weekly on Mondays at 9 AM UTC (Dependabot handles PRs daily, this validates)
- cron: 0 9 * * 1
workflow_dispatch: # Allow manual triggering
pull_request:
paths:
- .github/workflows/**

permissions:
contents: read

jobs:
validate-actions:
name: Validate Action Versions
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Check for pinned action versions
run: |
echo "Checking for actions using @master or @main tags..."
# Exclude snyk/actions/docker as it only has @master available
if grep -rh "uses:" .github/workflows/*.yml | grep -E "@master|@main" | grep -v "snyk/actions/docker"; then
echo "⚠️ Warning: Found actions using @master or @main tags"
echo "Consider pinning to specific versions for better security and reproducibility"
exit 1
else
echo "✅ All actions are using versioned tags (or approved exceptions)"
fi

- name: List all action versions
run: |
echo "## GitHub Actions in use:" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
grep -h "uses:" .github/workflows/*.yml | sort -u >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ Dockerfile
*.exe
streamdl
test/
.dccache
31 changes: 16 additions & 15 deletions .trunk/trunk.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,46 @@
# To learn more about the format of this file, see https://docs.trunk.io/reference/trunk-yaml
version: 0.1
cli:
version: 1.22.11
version: 1.25.0
# Trunk provides extensibility via plugins. (https://docs.trunk.io/plugins)
plugins:
sources:
- id: trunk
ref: v1.6.7
ref: v1.7.2
uri: https://github.com/trunk-io/plugins
# Many linters and tools depend on runtimes - configure them here. (https://docs.trunk.io/runtimes)
runtimes:
enabled:
- go@1.21.0
- node@18.20.5
- node@22.16.0
- python@3.10.8
- rust@1.82.0
# This is the section where you manage your linters. (https://docs.trunk.io/check/configuration)
lint:
enabled:
- golangci-lint2@2.4.0
- snyk@1.1295.0
- actionlint@1.7.7
- bandit@1.8.3
- bandit@1.8.6
- black@25.1.0
- checkov@3.2.386
- checkov@3.2.464
- git-diff-check
- gofmt@1.20.4
- golangci-lint@1.64.7
- golangci-lint@1.64.8
- hadolint@2.12.1-beta
- isort@6.0.1
- markdownlint@0.44.0
- markdownlint@0.45.0
- nixpkgs-fmt@1.3.0
- osv-scanner@2.0.0
- prettier@3.5.3
- ruff@0.11.0
- shellcheck@0.10.0
- osv-scanner@2.2.1
- prettier@3.6.2
- ruff@0.12.10
- shellcheck@0.11.0
- shfmt@3.6.0
- taplo@0.9.3
- taplo@0.10.0
- terrascan@1.19.1
- trivy@0.60.0
- trufflehog@3.88.17
- yamllint@1.36.2
- trivy@0.65.0
- trufflehog@3.90.5
- yamllint@1.37.1
actions:
disabled:
- trunk-announce
Expand Down
16 changes: 10 additions & 6 deletions Dockerfile.client
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
FROM mwader/static-ffmpeg:7.1.1 AS ffmpeg
FROM mwader/static-ffmpeg:8.0 AS ffmpeg

# Go Binary Builder
FROM golang:1.24.1-alpine AS go-build
FROM golang:1.25.3-alpine AS go-build
WORKDIR /app
COPY . .
RUN go get -v && \
go build -o streamdl

# Golang Protobuf Client and Logic
FROM golang:1.24.1-alpine AS client
FROM golang:1.25.3-alpine AS client

# Install su-exec for running as non-root
RUN apk add --no-cache su-exec
# Install su-exec and curl for running as non-root and health checks
RUN apk add --no-cache su-exec==0.2-r3 curl=8.14.1-r2

WORKDIR /app

Expand All @@ -25,5 +25,9 @@ COPY streamdl_client_entrypoint.sh /app/streamdl_client_entrypoint.sh
# Make entrypoint scripts executable
RUN chmod +x /app/entrypoint_client.sh /app/streamdl_client_entrypoint.sh

# HEALTHCHECK --interval=60s --timeout=15s --start-period=5s --retries=3 CMD curl --fail http://streamdl-client:8080/health || exit 1
# Add health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD curl --fail --max-time 5 --silent --output /dev/null http://localhost:8080/health || exit 1

# Entrypoint script handles user creation and switching
ENTRYPOINT ["/bin/sh", "/app/entrypoint_client.sh"]
10 changes: 7 additions & 3 deletions Dockerfile.server
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ RUN which uv
# Python Protobuf Server
FROM python:3.13-slim-bookworm AS server

# Install gosu for running as non-root
RUN apt-get update && apt-get install -y gosu && rm -rf /var/lib/apt/lists/*
# Install gosu and curl for running as non-root and health checks
RUN apt-get update && apt-get install -y --no-install-recommends gosu=1.14-1+b10 curl=7.88.1-10+deb12u14 && rm -rf /var/lib/apt/lists/*

WORKDIR /app

Expand All @@ -25,5 +25,9 @@ COPY streamdl_server_entrypoint.sh /app/streamdl_server_entrypoint.sh
RUN pip install --no-cache-dir uv==0.4.28 && uv sync && \
chmod +x /app/entrypoint_server.sh /app/streamdl_server_entrypoint.sh

# HEALTHCHECK --interval=60s --timeout=15s --start-period=5s --retries=3 CMD curl --fail http://streamdl-server:8080/health || exit 1
# Add health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD curl --fail --max-time 5 http://localhost:8080/health || exit 1

# Entrypoint script handles user creation and switching
ENTRYPOINT ["/bin/sh", "/app/entrypoint_server.sh"]
50 changes: 49 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,16 @@ Edit the Environment variables in `docker-compose.yml.example` to modify script

Otherwise, just rename it to `docker-compose.yml` and run `docker compose up -d`.

#### Directory Permissions
#### Security Best Practices

StreamDL containers follow Docker security best practices by running as a non-root user:

- **Default User**: Containers create a `streamdl` user (UID 1000, GID 1000) at build time
- **Runtime User Switching**: Supports dynamic UID/GID switching via `PUID`/`PGID` environment variables
- **User Tools**: Uses `su-exec` (client) and `gosu` (server) for secure user switching
- **Directory Permissions**: Working directories are created with proper ownership at build time

##### Directory Permissions

When using Docker, be aware of the following:

Expand Down Expand Up @@ -120,6 +129,45 @@ Some of these are also available as flags to the `streamdl` command, this is a #
| `PUID` | User ID that will own the files/directories created by the container (Docker only) | `1000` |
| `PGID` | Group ID that will own the files/directories created by the container (Docker only) | `1000` |

### User ID and Group ID Configuration

The `PUID` and `PGID` environment variables allow you to control what user and group ID the container runs as:

- **Default Behavior**: If not specified, containers run as UID 1000, GID 1000
- **Runtime Switching**: These values are applied at container startup, allowing you to match your host user's UID/GID
- **Permission Matching**: Set these to match your host user's UID/GID to avoid permission issues with mounted volumes

Example `.env` configuration:

```bash
PUID=1001
PGID=1001
```

To find your current user's UID/GID on Linux/macOS:

```bash
id -u # Shows your user ID
id -g # Shows your group ID
```

### FFmpeg Resilience Settings

The following environment variables control FFmpeg's reconnection behavior for more resilient stream downloading:

|| Variable | Description | Default |
|| -------------------- | ----------------------------------------------------------------------------------------------------------------- | -------- |
|| `FFMPEG_MAX_RETRIES` | Maximum number of FFmpeg retry attempts for transient failures | `5` |
|| `FFMPEG_RETRY_BASE_DELAY_SECONDS` | Base delay in seconds between FFmpeg retry attempts | `5` |
|| `FFMPEG_RECONNECT_DELAY_MAX` | Maximum delay in seconds for FFmpeg to wait before reconnecting | `30` |
|| `FFMPEG_RW_TIMEOUT_US` | FFmpeg read/write timeout in microseconds (30,000,000 = 30 seconds) | `30000000` |
|| `FFMPEG_RECONNECT_ON_NETWORK_ERROR` | Enable FFmpeg reconnection on network errors (1=enabled, 0=disabled) | `1` |
|| `FFMPEG_RECONNECT_ON_HTTP_ERROR` | Enable FFmpeg reconnection on HTTP errors (1=enabled, 0=disabled) | `1` |
|| `FFMPEG_HTTP_SEEKABLE` | Enable HTTP seeking for better resilience (1=enabled, 0=disabled) | `1` |
|| `FFMPEG_HTTP_PERSISTENT` | Keep HTTP connections alive (1=enabled, 0=disabled) | `1` |

These settings help prevent creating multiple small files when streams have temporary interruptions.

### Understanding UMASK

UMASK (User Mask) is a system setting that controls the default permissions for newly created files and directories.
Expand Down
16 changes: 14 additions & 2 deletions config_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@ import (
"os"

log "github.com/sirupsen/logrus"
yaml "gopkg.in/yaml.v3"
)

// fatalf allows tests to override fatal behavior. In production, it maps to log.Fatalf.
var fatalf = log.Fatalf

func check(e error) {
if e != nil {
log.Fatalf("%v", e)
panic(e)
fatalf("%v", e)
}
}

Expand All @@ -18,3 +21,12 @@ func readConfig(loc string) []byte {
check(err)
return dat
}

// parseConfig unmarshals YAML bytes into []Config.
func parseConfig(data []byte) ([]Config, error) {
var cfg []Config
if err := yaml.Unmarshal(data, &cfg); err != nil {
return nil, err
}
return cfg, nil
}
56 changes: 56 additions & 0 deletions config_reader_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package main

import (
"os"
"path/filepath"
"testing"
)

func TestReadConfig_ValidFile(t *testing.T) {
dir := t.TempDir()
cfg := filepath.Join(dir, "config.yml")
want := []byte("- site: test.example\n channels: []\n")
if err := os.WriteFile(cfg, want, 0644); err != nil {
t.Fatalf("write cfg: %v", err)
}

got := readConfig(cfg)
if string(got) != string(want) {
t.Fatalf("config mismatch: got %q want %q", string(got), string(want))
}
}

func TestReadConfig_MissingFile_Fatal(t *testing.T) {
// Stub fatalf to avoid os.Exit; instead record message
var called bool
oldFatal := fatalf
fatalf = func(format string, args ...interface{}) {
called = true
// Do not exit in tests
}
t.Cleanup(func() { fatalf = oldFatal })

_ = readConfig("/path/does/not/exist.yml")
if !called {
t.Fatalf("expected fatalf to be called for missing file")
}
}

func TestParseConfig_MalformedYAML(t *testing.T) {
dir := t.TempDir()
cfg := filepath.Join(dir, "bad.yml")
// channels should be a sequence, not a scalar
bad := []byte("- site: test.example\n channels: true\n")
if err := os.WriteFile(cfg, bad, 0644); err != nil {
t.Fatalf("write bad cfg: %v", err)
}

// Stub fatalf to no-op so readConfig won't exit on read
oldFatal := fatalf
fatalf = func(format string, args ...interface{}) {}
t.Cleanup(func() { fatalf = oldFatal })

if _, err := parseConfig(readConfig(cfg)); err == nil {
t.Fatalf("expected YAML unmarshal error for malformed config")
}
}
Loading
Loading