Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ LABEL build_version="Linuxserver.io version:- ${VERSION} Build-date:- ${BUILD_DA
LABEL maintainer="thelamer"

ENV TITLE="Telegram" \
NO_GAMEPAD=true
NO_GAMEPAD=true \
PIXELFLUX_WAYLAND=true

RUN \
echo "**** add icon ****" && \
Expand Down
3 changes: 2 additions & 1 deletion Dockerfile.aarch64
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ LABEL build_version="Linuxserver.io version:- ${VERSION} Build-date:- ${BUILD_DA
LABEL maintainer="thelamer"

ENV TITLE="Telegram" \
NO_GAMEPAD=true
NO_GAMEPAD=true \
PIXELFLUX_WAYLAND=true

RUN \
echo "**** add icon ****" && \
Expand Down
172 changes: 85 additions & 87 deletions Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ pipeline {
'''
script{
env.EXIT_STATUS = ''
env.CI_TEST_ATTEMPTED = ''
env.LS_RELEASE = sh(
script: '''docker run --rm quay.io/skopeo/stable:v1 inspect docker://ghcr.io/${LS_USER}/${CONTAINER_NAME}:latest 2>/dev/null | jq -r '.Labels.build_version' | awk '{print $3}' | grep '\\-ls' || : ''',
returnStdout: true).trim()
Expand Down Expand Up @@ -871,6 +872,7 @@ pipeline {
script{
env.CI_URL = 'https://ci-tests.linuxserver.io/' + env.IMAGE + '/' + env.META_TAG + '/index.html'
env.CI_JSON_URL = 'https://ci-tests.linuxserver.io/' + env.IMAGE + '/' + env.META_TAG + '/report.json'
env.CI_TEST_ATTEMPTED = 'true'
}
sh '''#! /bin/bash
set -e
Expand Down Expand Up @@ -1073,98 +1075,13 @@ EOF
) '''
}
}
// If this is a Pull request send the CI link as a comment on it
stage('Pull Request Comment') {
when {
not {environment name: 'CHANGE_ID', value: ''}
environment name: 'EXIT_STATUS', value: ''
}
steps {
sh '''#! /bin/bash
# Function to retrieve JSON data from URL
get_json() {
local url="$1"
local response=$(curl -s "$url")
if [ $? -ne 0 ]; then
echo "Failed to retrieve JSON data from $url"
return 1
fi
local json=$(echo "$response" | jq .)
if [ $? -ne 0 ]; then
echo "Failed to parse JSON data from $url"
return 1
fi
echo "$json"
}

build_table() {
local data="$1"

# Get the keys in the JSON data
local keys=$(echo "$data" | jq -r 'to_entries | map(.key) | .[]')

# Check if keys are empty
if [ -z "$keys" ]; then
echo "JSON report data does not contain any keys or the report does not exist."
return 1
fi

# Build table header
local header="| Tag | Passed |\\n| --- | --- |\\n"

# Loop through the JSON data to build the table rows
local rows=""
for build in $keys; do
local status=$(echo "$data" | jq -r ".[\\"$build\\"].test_success")
if [ "$status" = "true" ]; then
status="✅"
else
status="❌"
fi
local row="| "$build" | "$status" |\\n"
rows="${rows}${row}"
done

local table="${header}${rows}"
local escaped_table=$(echo "$table" | sed 's/\"/\\\\"/g')
echo "$escaped_table"
}

if [[ "${CI}" = "true" ]]; then
# Retrieve JSON data from URL
data=$(get_json "$CI_JSON_URL")
# Create table from JSON data
table=$(build_table "$data")
echo -e "$table"

curl -X POST -H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/$LS_USER/$LS_REPO/issues/$PULL_REQUEST/comments" \
-d "{\\"body\\": \\"I am a bot, here are the test results for this PR: \\n${CI_URL}\\n${SHELLCHECK_URL}\\n${table}\\"}"
else
curl -X POST -H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/$LS_USER/$LS_REPO/issues/$PULL_REQUEST/comments" \
-d "{\\"body\\": \\"I am a bot, here is the pushed image/manifest for this PR: \\n\\n\\`${GITHUBIMAGE}:${META_TAG}\\`\\"}"
fi
'''

}
}
}
/* ######################
Send status to Discord
Comment on PR and Send status to Discord
###################### */
post {
always {
sh '''#!/bin/bash
rm -rf /config/.ssh/id_sign
rm -rf /config/.ssh/id_sign.pub
git config --global --unset gpg.format
git config --global --unset user.signingkey
git config --global --unset commit.gpgsign
'''
script{
script {
env.JOB_DATE = sh(
script: '''date '+%Y-%m-%dT%H:%M:%S%:z' ''',
returnStdout: true).trim()
Expand Down Expand Up @@ -1207,6 +1124,87 @@ EOF
"username": "Jenkins"}' ${BUILDS_DISCORD} '''
}
}
script {
if (env.GITHUBIMAGE =~ /lspipepr/){
if (env.CI_TEST_ATTEMPTED == "true"){
sh '''#! /bin/bash
# Function to retrieve JSON data from URL
get_json() {
local url="$1"
local response=$(curl -s "$url")
if [ $? -ne 0 ]; then
echo "Failed to retrieve JSON data from $url"
return 1
fi
local json=$(echo "$response" | jq .)
if [ $? -ne 0 ]; then
echo "Failed to parse JSON data from $url"
return 1
fi
echo "$json"
}

build_table() {
local data="$1"

# Get the keys in the JSON data
local keys=$(echo "$data" | jq -r 'to_entries | map(.key) | .[]')

# Check if keys are empty
if [ -z "$keys" ]; then
echo "JSON report data does not contain any keys or the report does not exist."
return 1
fi

# Build table header
local header="| Tag | Passed |\\n| --- | --- |\\n"

# Loop through the JSON data to build the table rows
local rows=""
for build in $keys; do
local status=$(echo "$data" | jq -r ".[\\"$build\\"].test_success")
if [ "$status" = "true" ]; then
status="✅"
else
status="❌"
fi
local row="| "$build" | "$status" |\\n"
rows="${rows}${row}"
done

local table="${header}${rows}"
local escaped_table=$(echo "$table" | sed 's/\"/\\\\"/g')
echo "$escaped_table"
}

if [[ "${CI}" = "true" ]]; then
# Retrieve JSON data from URL
data=$(get_json "$CI_JSON_URL")
# Create table from JSON data
table=$(build_table "$data")
echo -e "$table"

curl -X POST -H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/$LS_USER/$LS_REPO/issues/$PULL_REQUEST/comments" \
-d "{\\"body\\": \\"I am a bot, here are the test results for this PR: \\n${CI_URL}\\n${SHELLCHECK_URL}\\n${table}\\"}"
else
curl -X POST -H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/$LS_USER/$LS_REPO/issues/$PULL_REQUEST/comments" \
-d "{\\"body\\": \\"I am a bot, here is the pushed image/manifest for this PR: \\n\\n\\`${GITHUBIMAGE}:${META_TAG}\\`\\"}"
fi
'''
}
}
}
sh '''#!/bin/bash
rm -rf /config/.ssh/id_sign
rm -rf /config/.ssh/id_sign.pub
git config --global --unset gpg.format
git config --global --unset user.signingkey
git config --global --unset commit.gpgsign
'''
}
cleanup {
sh '''#! /bin/bash
Expand Down
36 changes: 32 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,9 @@ To use hardware acceleration in Wayland mode, we distinguish between the card us
* `DRINODE`: The path to the GPU used for **Rendering** (EGL).
* `DRI_NODE`: The path to the GPU used for **Encoding** (VAAPI/NVENC).

If both variables point to the same device, the container will automatically enable **Zero Copy** encoding, significantly reducing CPU usage and latency.
If both variables point to the same device, the container will automatically enable **Zero Copy** encoding, significantly reducing CPU usage and latency. If they are set to different devices one will be used for **Rendering** and one for **Encoding** with a cpu readback.

You can also use the environment variable `AUTO_GPU=true`, with this set the first card detected in the container (IE `/dev/dri/renderD128`) will be used and configured for **Zero Copy**.

##### Intel & AMD (Open Source Drivers)

Expand All @@ -122,13 +124,34 @@ For Intel and AMD GPUs.

##### Nvidia (Proprietary Drivers)

**Note: Nvidia support is currently considered experimental, driver changes can break it at any time.**

**Note: Nvidia support is not available for Alpine-based images.**

**Note: Nvidia frames have issues with hardware decoders in Chromium browsers you need to navigate to `chrome://flags/#disable-accelerated-video-decode` and toggle it to `Disabled` for smooth playback**

**Prerequisites:**

1. **Driver:** Proprietary drivers **580 or higher** are required.
2. **Kernel Parameter:** Set `nvidia-drm.modeset=1` in your host bootloader (GRUB/systemd-boot).
3. **Initialization:** On headless systems, run `nvidia-modprobe --modeset` on the host (once per boot) to initialize the card.
1. **Driver:** Proprietary drivers **580 or higher** are required. **Crucially, you should install the driver using the `.run` file downloaded directly from the Nvidia website.**
* **Unraid:** Use the production branch from the Nvidia Driver Plugin.

2. **Kernel Parameter:** You must set `nvidia-drm.modeset=1 nvidia_drm.fbdev=1` in your host bootloader.
* **Standard Linux (GRUB):** Edit `/etc/default/grub` and add the parameter to your existing `GRUB_CMDLINE_LINUX_DEFAULT` line:

```text
GRUB_CMDLINE_LINUX_DEFAULT="<other existing options> nvidia-drm.modeset=1 nvidia_drm.fbdev=1"
```

Then apply the changes by running:

```bash
sudo update-grub
```

* **Unraid (Syslinux):** Edit the file `/boot/syslinux/syslinux.cfg` and add `nvidia-drm.modeset=1 nvidia_drm.fbdev=1` to the end of the `append` line for the Unraid OS boot entry.

3. **Hardware Initialization:** **On headless systems, the Nvidia video card requires a physical dummy plug inserted into the GPU so that DRM initializes properly.**

4. **Docker Runtime:** Configure the host docker daemon to use the Nvidia runtime:

```bash
Expand Down Expand Up @@ -157,6 +180,8 @@ services:
capabilities: [compute,video,graphics,utility]
```

* **Unraid:** Ensure you're properly setting the DRINODE/DRI_NODE and adding `--gpus all --runtime nvidia` to your extra parameters.

### SealSkin Compatibility

This container is compatible with [SealSkin](https://sealskin.app).
Expand All @@ -177,12 +202,14 @@ This container is based on [Docker Baseimage Selkies](https://github.com/linuxse
| Variable | Description |
| :----: | --- |
| PIXELFLUX_WAYLAND | **Experimental** If set to true the container will initialize in Wayland mode running [Smithay](https://github.com/Smithay/smithay) and Labwc while enabling zero copy encoding with a GPU |
| SELKIES_DESKTOP | If set to true and in Wayland mode, a simple panel will be initialized with labwc |
| CUSTOM_PORT | Internal port the container listens on for http if it needs to be swapped from the default `3000` |
| CUSTOM_HTTPS_PORT | Internal port the container listens on for https if it needs to be swapped from the default `3001` |
| CUSTOM_WS_PORT | Internal port the container listens on for websockets if it needs to be swapped from the default 8082 |
| CUSTOM_USER | HTTP Basic auth username, abc is default. |
| DRI_NODE | **Encoding GPU**: Enable VAAPI/NVENC stream encoding and use the specified device IE `/dev/dri/renderD128` |
| DRINODE | **Rendering GPU**: Specify which GPU to use for EGL/3D acceleration IE `/dev/dri/renderD129` |
| AUTO_GPU | If set to true and in Wayland mode, we will automatically use the first GPU available for encoding and rendering IE `/dev/dri/renderD128` |
| PASSWORD | HTTP Basic auth password, abc is default. If unset there will be no auth |
| SUBFOLDER | Subfolder for the application if running a subfolder reverse proxy, need both slashes IE `/subfolder/` |
| TITLE | The page title displayed on the web browser, default "Selkies" |
Expand Down Expand Up @@ -612,6 +639,7 @@ Once registered you can define the dockerfile to use with `-f Dockerfile.aarch64

## Versions

* **04.04.26:** - Make Wayland default disable with PIXELFLUX_WAYLAND=false.
* **21.03.26:** - Use Wayland ozone platform for chromium fixes scaling and acceleration.
* **28.12.25:** - Add Wayland init logic.
* **02.12.25:** - Initial Version.
1 change: 1 addition & 0 deletions readme-vars.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ init_diagram: |
"telegram:latest" <- Base Images
# changelog
changelogs:
- {date: "04.04.26:", desc: "Make Wayland default disable with PIXELFLUX_WAYLAND=false."}
- {date: "21.03.26:", desc: "Use Wayland ozone platform for chromium fixes scaling and acceleration."}
- {date: "28.12.25:", desc: "Add Wayland init logic."}
- {date: "02.12.25:", desc: "Initial Version."}