Compare commits
135 Commits
dev-kasmvn
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
23e5ec9fa4 | ||
|
|
e39756c3bf | ||
|
|
77fc0221e5 | ||
|
|
67e55c50af | ||
|
|
c3dc444a8f | ||
|
|
0ac3a94009 | ||
|
|
8dd20185a7 | ||
|
|
f0accf6102 | ||
|
|
14c770bce6 | ||
|
|
6db83d2a22 | ||
|
|
6199455ae7 | ||
|
|
0c4c669ab0 | ||
|
|
920bfa7f84 | ||
|
|
463274d800 | ||
|
|
0241c9f845 | ||
|
|
860451da74 | ||
|
|
b0ba3cfc8a | ||
|
|
77967f2845 | ||
|
|
ac9c4f29ca | ||
|
|
336a6284ec | ||
|
|
9cf971f68f | ||
|
|
47f6f7a176 | ||
|
|
28c19ed1b2 | ||
|
|
728acd0ba1 | ||
|
|
a2caa9f4ec | ||
|
|
9c20a0f1f5 | ||
|
|
f17d31d077 | ||
|
|
e701b8870f | ||
|
|
bd73b199d4 | ||
|
|
12a498e1eb | ||
|
|
63cfefa1fc | ||
|
|
c3941d1f0b | ||
|
|
6cc9f56155 | ||
|
|
a17fe91113 | ||
|
|
a5f189dbc3 | ||
|
|
8f32302c0f | ||
|
|
ca7521d765 | ||
|
|
c165e28f07 | ||
|
|
7f04d8df01 | ||
|
|
f4cad0aab0 | ||
|
|
12cc16459a | ||
|
|
c651034d13 | ||
|
|
93718e1855 | ||
|
|
5a1d20daf5 | ||
|
|
15512a485f | ||
|
|
eeca08ce38 | ||
|
|
96d318ebd0 | ||
|
|
8b11bca749 | ||
|
|
9d43f152b9 | ||
|
|
0dd343aea9 | ||
|
|
37f7280dba | ||
|
|
7552680a01 | ||
|
|
9a460b27e6 | ||
|
|
c452e67fd7 | ||
|
|
22cf7e5980 | ||
|
|
20c6b515ed | ||
|
|
ae88645245 | ||
|
|
868def8906 | ||
|
|
5cef857d34 | ||
|
|
b5cb3fb0db | ||
|
|
3867701a6b | ||
|
|
35722dfa84 | ||
|
|
acee2481c1 | ||
|
|
cc8bc1b02d | ||
|
|
cb751f5a80 | ||
|
|
aa1edd48e0 | ||
|
|
771c47d602 | ||
|
|
0981af0a17 | ||
|
|
608f772ccc | ||
|
|
60fa2363eb | ||
|
|
7513c19bfd | ||
|
|
e4cf09dcb0 | ||
|
|
3cce8f79f8 | ||
|
|
90510bd8ea | ||
|
|
c8d613da5b | ||
|
|
63137d43ec | ||
|
|
3faf8df134 | ||
|
|
c3480448ff | ||
|
|
e0dc046470 | ||
|
|
269e71a0db | ||
|
|
97613b227f | ||
|
|
39d4ce0a0c | ||
|
|
b7bb479635 | ||
|
|
b89e2f565d | ||
|
|
1b7873833c | ||
|
|
890b9d22d2 | ||
|
|
2f118e4a51 | ||
|
|
dd3f079d71 | ||
|
|
c925ff8c87 | ||
|
|
aea4d51159 | ||
|
|
1454b704a2 | ||
|
|
d899ebd965 | ||
|
|
b51036a697 | ||
|
|
8ad830d5e4 | ||
|
|
2c8f6150e9 | ||
|
|
6be269a3bb | ||
|
|
ee4fd33e72 | ||
|
|
c671ba85cc | ||
|
|
4f94568262 | ||
|
|
fed3000700 | ||
|
|
c731e2e0a0 | ||
|
|
02a94566b2 | ||
|
|
5837843aa2 | ||
|
|
ac7dc533e7 | ||
|
|
577d0ef299 | ||
|
|
ca5821774b | ||
|
|
edab557c20 | ||
|
|
0414726448 | ||
|
|
d2b4d2cae7 | ||
|
|
53af510b45 | ||
|
|
cfeb39c268 | ||
|
|
6913938585 | ||
|
|
9c3497d73a | ||
|
|
658b18a634 | ||
|
|
d386c282e6 | ||
|
|
af1c17fdfd | ||
|
|
b75b496283 | ||
|
|
659bde74f5 | ||
|
|
23c5df2996 | ||
|
|
9fe592672a | ||
|
|
932e15314a | ||
|
|
3be80a920e | ||
|
|
35de069bf1 | ||
|
|
8da0bd023d | ||
|
|
26b775f66e | ||
|
|
555bd8991d | ||
|
|
42ebc826b8 | ||
|
|
0b600108f7 | ||
|
|
8d43f93b55 | ||
|
|
f92fb55290 | ||
|
|
417ab4488b | ||
|
|
fc700e2200 | ||
|
|
df9423ccad | ||
|
|
68244060ff | ||
|
|
8c6051aec7 |
182
.github/workflows/build_ci.yml
vendored
182
.github/workflows/build_ci.yml
vendored
@@ -1,8 +1,7 @@
|
||||
---
|
||||
|
||||
name: Build and Deploy CI
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches: ['dev-**', 'pr-**', staging, master]
|
||||
tags: ['**']
|
||||
@@ -13,61 +12,74 @@ on:
|
||||
- cron: '30 2 * * 6'
|
||||
|
||||
jobs:
|
||||
|
||||
build_docker:
|
||||
|
||||
name: Build Docker Image
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
flavour: ['debian', 'arch']
|
||||
|
||||
steps:
|
||||
# Fetch shallow git repository
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
# ---
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Use QEMU to build
|
||||
- name: Set up QEMU
|
||||
if: success()
|
||||
id: qemu
|
||||
uses: docker/setup-qemu-action@v1
|
||||
# ---
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 #v3.8.0
|
||||
|
||||
# Use docker buildx to build the docker image
|
||||
- name: Build the Docker image
|
||||
uses: docker/setup-buildx-action@v1
|
||||
if: success()
|
||||
id: buildx
|
||||
with:
|
||||
version: latest
|
||||
|
||||
# Generate 'prepare' build arguments to be retrieved later on
|
||||
# ---
|
||||
- name: Prepare
|
||||
if: success()
|
||||
id: prepare
|
||||
run: |
|
||||
echo "GITHUB_REF:${GITHUB_REF}"
|
||||
echo "GITHUB_REPOSITORY:${GITHUB_REPOSITORY}"
|
||||
DOCKER_IMAGE=docker.io/josh5/steam-headless
|
||||
FLAVOUR=${{ matrix.flavour }}
|
||||
echo "FLAVOUR='${FLAVOUR}'"
|
||||
echo "GITHUB_REF='${GITHUB_REF}'"
|
||||
echo "GITHUB_REPOSITORY='${GITHUB_REPOSITORY}'"
|
||||
VERSION_TAG=${GITHUB_REF#refs/*/}
|
||||
SHA_SHORT="${GITHUB_SHA::7}"
|
||||
ORG=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]')
|
||||
BUILD_DATE="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
|
||||
|
||||
SERVICE_NAME=steam-headless
|
||||
DOCKER_HUB_IMAGE=docker.io/josh5/${SERVICE_NAME:?}
|
||||
GHCR_IMAGE=ghcr.io/${ORG:?}/${SERVICE_NAME:?}
|
||||
|
||||
DOCKER_TAGS=""
|
||||
if [[ ${VERSION_TAG%/merge} == 'master' ]]; then
|
||||
DOCKER_TAGS="${DOCKER_TAGS}${DOCKER_IMAGE}:latest,"
|
||||
elif [[ ${VERSION_TAG%/merge} == 'staging' ]]; then
|
||||
DOCKER_TAGS="${DOCKER_TAGS}${DOCKER_IMAGE}:staging,"
|
||||
elif [[ ${VERSION_TAG%/merge} =~ "dev-"* ]]; then
|
||||
DOCKER_TAGS="${DOCKER_TAGS}${DOCKER_IMAGE}:${VERSION_TAG%/merge},"
|
||||
if [[ ${GITHUB_REF} == refs/heads/master ]]; then
|
||||
if [[ ${FLAVOUR} == 'debian' ]]; then
|
||||
DOCKER_TAGS="${DOCKER_TAGS}${DOCKER_HUB_IMAGE}:latest,${GHCR_IMAGE}:latest,${GHCR_IMAGE}:stable,"
|
||||
fi
|
||||
if [[ ${GITHUB_REF} == refs/tags/* ]]; then
|
||||
DOCKER_TAGS="${DOCKER_TAGS}${DOCKER_HUB_IMAGE}:${FLAVOUR},${GHCR_IMAGE}:${FLAVOUR},"
|
||||
elif [[ ${GITHUB_REF} == refs/heads/staging ]]; then
|
||||
DOCKER_TAGS="${DOCKER_TAGS}${DOCKER_HUB_IMAGE}:${FLAVOUR}-staging,${GHCR_IMAGE}:${FLAVOUR}-staging,"
|
||||
elif [[ ${GITHUB_REF} == refs/heads/dev-* ]]; then
|
||||
DOCKER_TAGS="${DOCKER_TAGS}${DOCKER_HUB_IMAGE}:${FLAVOUR}-${VERSION_TAG},${GHCR_IMAGE}:${FLAVOUR}-${VERSION_TAG},"
|
||||
elif [[ ${GITHUB_REF} == refs/tags/* ]]; then
|
||||
VERSION=${GITHUB_REF#refs/tags/}
|
||||
if [[ ${VERSION} =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}[-\w]*$ ]]; then
|
||||
DOCKER_TAGS="${DOCKER_TAGS}${DOCKER_IMAGE}:${VERSION},"
|
||||
DOCKER_TAGS="${DOCKER_TAGS}${DOCKER_IMAGE}:latest,"
|
||||
fi
|
||||
DOCKER_TAGS="${DOCKER_TAGS}${DOCKER_HUB_IMAGE}:${FLAVOUR}-${VERSION},${GHCR_IMAGE}:${FLAVOUR}-${VERSION},"
|
||||
if [[ ${FLAVOUR} == 'debian' ]]; then
|
||||
DOCKER_TAGS="${DOCKER_TAGS}${DOCKER_HUB_IMAGE}:latest,${GHCR_IMAGE}:latest,"
|
||||
fi
|
||||
|
||||
echo "Build: [$(date +"%F %T")] [${GITHUB_REF_NAME}] [${GITHUB_SHA}]" > ./overlay/version.txt
|
||||
fi
|
||||
elif [[ ${GITHUB_REF} == refs/pull/* ]]; then
|
||||
PR_NUMBER=$(echo ${GITHUB_REF} | cut -d'/' -f3)
|
||||
# For PR builds, only tag the GHCR image.
|
||||
DOCKER_TAGS="${GHCR_IMAGE}:pr-${PR_NUMBER},"
|
||||
fi
|
||||
echo "DOCKER_TAGS='${DOCKER_TAGS}'"
|
||||
|
||||
echo "Build: [$(date +"%F %T")] [${GITHUB_REF_NAME}] [${GITHUB_SHA}] [${FLAVOUR}]" > ./overlay/version.txt
|
||||
|
||||
DOCKER_PUSH="true"
|
||||
if [[ ${DOCKER_IMAGE} != 'docker.io/josh5/steam-headless' ]]; then
|
||||
if [[ ${DOCKER_HUB_IMAGE} != 'docker.io/josh5/steam-headless' ]]; then
|
||||
DOCKER_PUSH="false"
|
||||
fi
|
||||
if [[ ${VERSION_TAG%/merge} =~ "pr-"* ]]; then
|
||||
@@ -76,53 +88,83 @@ jobs:
|
||||
if [[ ${VERSION_TAG%/merge} =~ ^[0-9]+$ ]]; then
|
||||
DOCKER_PUSH="false"
|
||||
fi
|
||||
if [[ "X${DOCKER_TAGS}" == "X" ]]; then
|
||||
DOCKER_PUSH="false"
|
||||
fi
|
||||
echo "DOCKER_PUSH='${DOCKER_PUSH}'"
|
||||
cat ./overlay/version.txt
|
||||
|
||||
echo ::set-output name=docker_image::${DOCKER_IMAGE}
|
||||
echo ::set-output name=docker_tags::$(echo ${DOCKER_TAGS} | sed 's/,$//')
|
||||
echo ::set-output name=docker_platforms::linux/amd64
|
||||
echo ::set-output name=docker_push::${DOCKER_PUSH}
|
||||
echo "docker_hub_image:${DOCKER_HUB_IMAGE:?}"
|
||||
echo "docker_hub_image=${DOCKER_HUB_IMAGE:?}" >> $GITHUB_OUTPUT
|
||||
|
||||
# Cache the build
|
||||
- name: Cache Docker layers
|
||||
uses: actions/cache@v2
|
||||
id: cache
|
||||
echo "ghcr_image:${GHCR_IMAGE:?}"
|
||||
echo "ghcr_image=${GHCR_IMAGE:?}" >> $GITHUB_OUTPUT
|
||||
|
||||
echo "sha_short:${SHA_SHORT:?}"
|
||||
echo "sha_short=${SHA_SHORT:?}" >> $GITHUB_OUTPUT
|
||||
|
||||
echo "service_name:${SERVICE_NAME:?}"
|
||||
echo "service_name=${SERVICE_NAME:?}" >> $GITHUB_OUTPUT
|
||||
|
||||
echo "docker_image:${DOCKER_HUB_IMAGE:?}"
|
||||
echo "docker_image=${DOCKER_HUB_IMAGE:?}" >> $GITHUB_OUTPUT
|
||||
|
||||
echo "docker_tags:$(echo ${DOCKER_TAGS} | sed 's/,$//')"
|
||||
echo "docker_tags=$(echo ${DOCKER_TAGS} | sed 's/,$//')" >> $GITHUB_OUTPUT
|
||||
|
||||
echo "docker_push:${DOCKER_PUSH:?}"
|
||||
echo "docker_push=${DOCKER_PUSH:?}" >> $GITHUB_OUTPUT
|
||||
|
||||
echo "docker_build_date:${BUILD_DATE:?}"
|
||||
echo "docker_build_date=${BUILD_DATE:?}" >> $GITHUB_OUTPUT
|
||||
|
||||
echo "docker_platforms=linux/amd64" >> $GITHUB_OUTPUT
|
||||
|
||||
# ---
|
||||
- name: Log into GHCR registry
|
||||
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567
|
||||
with:
|
||||
path: /tmp/.buildx-cache
|
||||
key: ${{ runner.os }}-buildx-${{ github.sha }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-buildx-
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# Login to Docker Hub
|
||||
- name: Login to Docker Hub
|
||||
# ---
|
||||
- name: Log into Docker Hub registry
|
||||
if: success() && (startsWith(github.ref, 'refs/heads/') || startsWith(github.ref, 'refs/tags/'))
|
||||
uses: docker/login-action@v1
|
||||
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 #v3.3.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
# Run docker build and push
|
||||
- name: Docker Build and Push
|
||||
# ---
|
||||
- name: Docker meta
|
||||
if: success()
|
||||
uses: docker/build-push-action@v2
|
||||
id: meta
|
||||
uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96 #v5.6.1
|
||||
with:
|
||||
images: |
|
||||
${{ steps.prepare.outputs.docker_image }}
|
||||
labels: |
|
||||
maintainer=Josh.5
|
||||
source.version=${{ steps.prepare.outputs.sha_short }}
|
||||
source.project=Steam Headless
|
||||
source.service=${{ steps.prepare.outputs.service_name }}
|
||||
org.opencontainers.image.title=${{ steps.prepare.outputs.service_name }}
|
||||
org.opencontainers.image.created=${{ steps.prepare.outputs.docker_build_date }}
|
||||
|
||||
# ---
|
||||
- name: Build Image
|
||||
if: success()
|
||||
uses: docker/build-push-action@b32b51a8eda65d6793cd0494a773d4f6bcef32dc #v6.11.0
|
||||
with:
|
||||
context: .
|
||||
file: Dockerfile
|
||||
pull: true
|
||||
file: Dockerfile.${{ matrix.flavour }}
|
||||
platforms: ${{ steps.prepare.outputs.docker_platforms }}
|
||||
pull: 'true'
|
||||
push: ${{ steps.prepare.outputs.docker_push }}
|
||||
tags: |
|
||||
${{ steps.prepare.outputs.docker_tags }}
|
||||
cache-from: type=local,src=/tmp/.buildx-cache
|
||||
cache-to: type=local,mode=max,dest=/tmp/.buildx-cache-new
|
||||
|
||||
# Keep only latest cache
|
||||
# https://github.com/docker/build-push-action/issues/252
|
||||
# https://github.com/moby/buildkit/issues/1896
|
||||
- name: Move cache
|
||||
if: always()
|
||||
run: |
|
||||
if [[ -e /tmp/.buildx-cache-new ]]; then
|
||||
echo "Cleaning up old cache..."
|
||||
rm -rf /tmp/.buildx-cache
|
||||
mv -v /tmp/.buildx-cache-new /tmp/.buildx-cache
|
||||
fi
|
||||
labels: |
|
||||
${{ steps.meta.outputs.labels }}
|
||||
cache-from: type=gha,scope=${{ steps.prepare.outputs.service_name }}-${{ matrix.flavour }}-main
|
||||
cache-to: type=gha,scope=${{ steps.prepare.outputs.service_name }}-${{ matrix.flavour }}-main,mode=max
|
||||
|
||||
501
Dockerfile.arch
501
Dockerfile.arch
@@ -34,6 +34,8 @@ RUN \
|
||||
&& \
|
||||
echo "**** Section cleanup ****" \
|
||||
&& pacman -Scc --noconfirm \
|
||||
&& rm -fr /var/lib/pacman/sync/* \
|
||||
&& rm -fr /var/cache/pacman/pkg/* \
|
||||
&& \
|
||||
echo
|
||||
|
||||
@@ -41,21 +43,34 @@ RUN \
|
||||
RUN \
|
||||
echo "**** Install tools ****" \
|
||||
&& pacman -Syu --noconfirm --needed \
|
||||
base-devel \
|
||||
bash \
|
||||
bash-completion \
|
||||
curl \
|
||||
docbook-xml \
|
||||
docbook-xsl \
|
||||
fakeroot \
|
||||
p7zip \
|
||||
patch \
|
||||
git \
|
||||
jq \
|
||||
less \
|
||||
locate \
|
||||
man-db \
|
||||
nano \
|
||||
net-tools \
|
||||
pciutils \
|
||||
pkg-config \
|
||||
procps \
|
||||
psmisc \
|
||||
psutils \
|
||||
rsync \
|
||||
screen \
|
||||
sudo \
|
||||
unzip \
|
||||
vim \
|
||||
wget \
|
||||
xmlstarlet \
|
||||
xz \
|
||||
&& \
|
||||
echo "**** Install python ****" \
|
||||
@@ -67,6 +82,44 @@ RUN \
|
||||
&& \
|
||||
echo "**** Section cleanup ****" \
|
||||
&& pacman -Scc --noconfirm \
|
||||
&& rm -fr /var/lib/pacman/sync/* \
|
||||
&& rm -fr /var/cache/pacman/pkg/* \
|
||||
&& \
|
||||
echo
|
||||
|
||||
# Configure default user and set user env
|
||||
ENV \
|
||||
PUID=99 \
|
||||
PGID=100 \
|
||||
UMASK=000 \
|
||||
USER="default" \
|
||||
USER_PASSWORD="password" \
|
||||
USER_HOME="/home/default" \
|
||||
TZ="Pacific/Auckland" \
|
||||
USER_LOCALES="en_US.UTF-8 UTF-8"
|
||||
RUN \
|
||||
echo "**** Configure default user '${USER}' ****" \
|
||||
&& mkdir -p \
|
||||
${USER_HOME} \
|
||||
&& useradd -d ${USER_HOME} -s /bin/bash ${USER} \
|
||||
&& chown -R ${USER} \
|
||||
${USER_HOME} \
|
||||
&& echo "${USER} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers \
|
||||
&& \
|
||||
echo
|
||||
|
||||
# Install yay
|
||||
RUN \
|
||||
echo "**** Install Yay ****" \
|
||||
&& pacman -Sy \
|
||||
&& su - default -c 'git clone https://aur.archlinux.org/yay.git /tmp/yay && cd /tmp/yay && makepkg --noconfirm --syncdeps --install' \
|
||||
&& \
|
||||
echo "**** Section cleanup ****" \
|
||||
&& pacman -Scc --noconfirm \
|
||||
&& rm -fr /home/default/.cache/yay \
|
||||
&& rm -fr /var/lib/pacman/sync/* \
|
||||
&& rm -fr /var/cache/pacman/pkg/* \
|
||||
&& rm -rf /tmp/yay* \
|
||||
&& \
|
||||
echo
|
||||
|
||||
@@ -78,48 +131,38 @@ RUN \
|
||||
&& \
|
||||
echo "**** Section cleanup ****" \
|
||||
&& pacman -Scc --noconfirm \
|
||||
&& rm -fr /var/lib/pacman/sync/* \
|
||||
&& rm -fr /var/cache/pacman/pkg/* \
|
||||
&& \
|
||||
echo
|
||||
|
||||
# XFS requirements
|
||||
# Install mscorefonts
|
||||
RUN \
|
||||
echo "**** Install XFS requirements ****" \
|
||||
&& pacman -Syu --noconfirm --needed \
|
||||
xfsdump \
|
||||
xfsprogs \
|
||||
&& \
|
||||
echo "**** Section cleanup ****" \
|
||||
&& pacman -Scc --noconfirm \
|
||||
&& \
|
||||
echo
|
||||
|
||||
# Install mesa requirements
|
||||
RUN \
|
||||
echo "**** Install mesa and vulkan requirements ****" \
|
||||
&& pacman -Syu --noconfirm --needed \
|
||||
glu \
|
||||
libva-mesa-driver \
|
||||
mesa-utils \
|
||||
mesa-vdpau \
|
||||
opencl-mesa \
|
||||
pciutils \
|
||||
vulkan-mesa-layers \
|
||||
echo "**** Install ms fonts ****" \
|
||||
&& su - default -c "yay -Syu --noconfirm --needed ttf-msfonts" \
|
||||
&& \
|
||||
echo "**** Section cleanup ****" \
|
||||
&& pacman -Scc --noconfirm \
|
||||
&& rm -fr /home/default/.cache/yay \
|
||||
&& rm -fr /var/lib/pacman/sync/* \
|
||||
&& rm -fr /var/cache/pacman/pkg/* \
|
||||
&& rm -rf /tmp/yay* \
|
||||
&& \
|
||||
echo
|
||||
|
||||
# Install X Server requirements
|
||||
# TODO: Remove doubles
|
||||
# TODO: Things that are not required
|
||||
ENV \
|
||||
XORG_SOCKET_DIR="/tmp/.X11-unix" \
|
||||
XDG_RUNTIME_DIR="/tmp/.X11-unix/run" \
|
||||
XDG_SESSION_TYPE="x11" \
|
||||
FORCE_X11_DUMMY_CONFIG="false"
|
||||
RUN \
|
||||
echo "**** Install X Server requirements ****" \
|
||||
&& pacman -Syu --noconfirm --needed \
|
||||
avahi \
|
||||
dbus \
|
||||
lib32-fontconfig \
|
||||
ttf-liberation \
|
||||
fuse2 \
|
||||
x11vnc \
|
||||
xorg \
|
||||
xorg-apps \
|
||||
@@ -139,94 +182,115 @@ RUN \
|
||||
xorg-xrandr \
|
||||
xorg-xsetroot \
|
||||
xorg-xwininfo \
|
||||
xf86-input-evdev \
|
||||
xterm \
|
||||
gamescope \
|
||||
&& \
|
||||
echo "**** Section cleanup ****" \
|
||||
&& pacman -Scc --noconfirm \
|
||||
&& rm -fr /var/lib/pacman/sync/* \
|
||||
&& rm -fr /var/cache/pacman/pkg/* \
|
||||
&& \
|
||||
echo
|
||||
|
||||
# pacman -Syu --noconfirm --needed \
|
||||
# xorg-server \
|
||||
# xorg-server-xephyr \
|
||||
# xorg-xwininfo \
|
||||
# xorg-xhost \
|
||||
# xorg-xinit \
|
||||
# xorg-xinput \
|
||||
# xorg-xrandr \
|
||||
# xorg-xprop \
|
||||
# xorg-xkill \
|
||||
# xorg-xbacklight \
|
||||
# xorg-xsetroot
|
||||
# s
|
||||
# pacman -Syu --noconfirm --needed autorandr xdg-desktop-portal xdg-desktop-portal-gtk wmctrl xbindkeys xdotool xautolock
|
||||
#
|
||||
#
|
||||
# pacman -Syu --noconfirm --needed gestures
|
||||
# pacman -Syu --noconfirm --needed numlockx
|
||||
#
|
||||
# echo 'Server = https://mirror.fsmg.org.nz/archlinux/$repo/os/$arch' >> /etc/pacman.d/mirrorlist
|
||||
#
|
||||
# Server = https://mirror.pkgbuild.com/$repo/os/$arch
|
||||
# Server = https://mirror.rackspace.com/archlinux/$repo/os/$arch
|
||||
# Server = https://mirror.leaseweb.net/archlinux/$repo/os/$arch
|
||||
|
||||
# Install audio requirements
|
||||
ENV \
|
||||
PULSE_SOCKET_DIR="/tmp/pulse" \
|
||||
PULSE_SERVER="unix:/tmp/pulse/pulse-socket"
|
||||
RUN \
|
||||
echo "**** Install X Server requirements ****" \
|
||||
&& pacman -Syu --noconfirm --needed \
|
||||
alsa-utils \
|
||||
pavucontrol \
|
||||
pulseaudio \
|
||||
pulseaudio-alsa \
|
||||
&& \
|
||||
echo "**** Section cleanup ****" \
|
||||
&& pacman -Scc --noconfirm \
|
||||
&& rm -fr /var/lib/pacman/sync/* \
|
||||
&& rm -fr /var/cache/pacman/pkg/* \
|
||||
&& \
|
||||
echo
|
||||
|
||||
# Install openssh server
|
||||
# Install desktop environment
|
||||
# TODO: Install equivelent of 'msttcorefonts' and 'fonts-vlgothic'
|
||||
RUN \
|
||||
echo "**** Install openssh server ****" \
|
||||
echo "**** Install desktop environment ****" \
|
||||
&& pacman -Syu --noconfirm --needed \
|
||||
openssh \
|
||||
&& echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config \
|
||||
gedit \
|
||||
xfce4 \
|
||||
xfce4-goodies \
|
||||
xfce4-terminal \
|
||||
ttf-liberation \
|
||||
xdg-user-dirs \
|
||||
xdg-utils \
|
||||
imagemagick \
|
||||
&& \
|
||||
echo "**** Install WoL Manager requirements ****" \
|
||||
&& pacman -Syu --noconfirm --needed \
|
||||
tcpdump \
|
||||
xprintidle \
|
||||
&& \
|
||||
echo "**** Section cleanup ****" \
|
||||
&& pacman -Scc --noconfirm \
|
||||
&& rm -fr /var/lib/pacman/sync/* \
|
||||
&& rm -fr /var/cache/pacman/pkg/* \
|
||||
&& \
|
||||
echo
|
||||
|
||||
# Install noVNC
|
||||
# TODO: Add nginx
|
||||
ARG NOVNC_VERSION=1.2.0
|
||||
# Add support for flatpaks
|
||||
ENV \
|
||||
XDG_DATA_DIRS="/home/default/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share/:/usr/share/"
|
||||
RUN \
|
||||
echo "**** Fetch noVNC ****" \
|
||||
&& cd /tmp \
|
||||
&& wget -O /tmp/novnc.tar.gz https://github.com/novnc/noVNC/archive/v${NOVNC_VERSION}.tar.gz \
|
||||
echo "**** Install flatpak support ****" \
|
||||
&& pacman -Syu --noconfirm --needed \
|
||||
flatpak \
|
||||
xdg-desktop-portal-gtk \
|
||||
gnome-software \
|
||||
&& \
|
||||
echo "**** Extract noVNC ****" \
|
||||
&& cd /tmp \
|
||||
&& tar -xvf /tmp/novnc.tar.gz \
|
||||
&& \
|
||||
echo "**** Configure noVNC ****" \
|
||||
&& cd /tmp/noVNC-${NOVNC_VERSION} \
|
||||
&& sed -i 's/credentials: { password: password } });/credentials: { password: password },\n wsProtocols: ["'"binary"'"] });/g' app/ui.js \
|
||||
&& mkdir -p /opt \
|
||||
&& rm -rf /opt/noVNC \
|
||||
&& cd /opt \
|
||||
&& mv -f /tmp/noVNC-${NOVNC_VERSION} /opt/noVNC \
|
||||
&& cd /opt/noVNC \
|
||||
&& ln -s vnc.html index.html \
|
||||
&& chmod -R 755 /opt/noVNC \
|
||||
&& \
|
||||
echo "**** Modify noVNC title ****" \
|
||||
&& sed -i '/ document.title =/c\ document.title = "Steam Headless - noVNC";' \
|
||||
/opt/noVNC/app/ui.js \
|
||||
echo "**** Configure flatpak ****" \
|
||||
&& chmod u-s /usr/bin/bwrap \
|
||||
&& flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo \
|
||||
&& su - default -c "flatpak remote-add --if-not-exists --user flathub https://flathub.org/repo/flathub.flatpakrepo" \
|
||||
&& \
|
||||
echo "**** Section cleanup ****" \
|
||||
&& rm -rf \
|
||||
/tmp/noVNC* \
|
||||
/tmp/novnc.tar.gz
|
||||
&& pacman -Scc --noconfirm \
|
||||
&& rm -fr /var/lib/pacman/sync/* \
|
||||
&& rm -fr /var/cache/pacman/pkg/* \
|
||||
&& \
|
||||
echo
|
||||
|
||||
# TODO: Deprecate neko
|
||||
# Install Neko server
|
||||
COPY --from=m1k1o/neko:base /usr/bin/neko /usr/bin/neko
|
||||
COPY --from=m1k1o/neko:base /var/www /var/www
|
||||
|
||||
# Install Web Frontend
|
||||
ARG FRONTEND_VERSION=a8eb92f
|
||||
RUN \
|
||||
echo "**** Fetch Web Frontend ****" \
|
||||
&& mkdir -p /opt \
|
||||
&& cd /opt \
|
||||
&& rm -rf /opt/frontend \
|
||||
&& git clone https://github.com/Steam-Headless/frontend.git --branch master /opt/frontend \
|
||||
&& cd /opt/frontend \
|
||||
&& git checkout ${FRONTEND_VERSION} 2> /dev/null \
|
||||
&& git submodule init \
|
||||
&& git submodule update --depth 1 --recursive \
|
||||
&& rm -rf /opt/frontend/.git \
|
||||
&& \
|
||||
echo "**** Configure Web Frontend ****" \
|
||||
&& echo '<!DOCTYPE html>' > /opt/frontend/index.html \
|
||||
&& echo '<html><head><meta http-equiv="refresh" content="0;url=./web/"></head><body><p>If you are not redirected, <a href="./web/">click here</a>.</p></body></html>' >> /opt/frontend/index.html \
|
||||
&& chmod -R 755 /opt/frontend \
|
||||
&& convert /opt/frontend/web/images/icons/novnc-ios-180.png -resize "128x128" /tmp/steam-headless.png \
|
||||
&& xdg-icon-resource install --novendor --size 128 /tmp/steam-headless.png \
|
||||
&& \
|
||||
echo "**** Section cleanup ****" \
|
||||
&& rm -f /tmp/steam-headless.png
|
||||
|
||||
# Install Websockify
|
||||
ARG WEBSOCKETIFY_VERSION=0.10.0
|
||||
ARG WEBSOCKETIFY_VERSION=0.11.0
|
||||
RUN \
|
||||
echo "**** Fetch Websockify ****" \
|
||||
&& cd /tmp \
|
||||
@@ -242,180 +306,201 @@ RUN \
|
||||
&& \
|
||||
echo "**** Install Websockify to noVNC path ****" \
|
||||
&& cd /tmp \
|
||||
&& mkdir -p /opt/noVNC/utils \
|
||||
&& mv -v /tmp/websockify-${WEBSOCKETIFY_VERSION} /opt/noVNC/utils/websockify \
|
||||
&& \
|
||||
echo "**** Section cleanup ****" \
|
||||
&& rm -rf \
|
||||
/tmp/websockify-* \
|
||||
/tmp/websockify.tar.gz
|
||||
/tmp/websockify.tar.gz \
|
||||
&& \
|
||||
echo
|
||||
|
||||
# Install firefox
|
||||
# TODO: MOve under de
|
||||
# Setup browser audio streaming deps
|
||||
RUN \
|
||||
echo "**** Install firefox ****" \
|
||||
echo "**** Install audio streaming deps ****" \
|
||||
&& pacman -Syu --noconfirm --needed \
|
||||
bzip2 \
|
||||
gst-libav \
|
||||
gst-plugins-bad \
|
||||
gst-plugins-base \
|
||||
gst-plugins-good \
|
||||
gst-plugins-ugly \
|
||||
&& \
|
||||
#echo "**** Fetch ucspi-tcp ****" \
|
||||
# && mkdir -p /tmp/ucspi-tcp-0.88 \
|
||||
# && cd /tmp \
|
||||
# #&& wget -O /tmp/ucspi-tcp.tar.gz https://github.com/trafficgate/ucspi-tcp/archive/refs/heads/master.tar.gz \
|
||||
# && wget -O /tmp/ucspi-tcp.tar.gz http://cr.yp.to/ucspi-tcp/ucspi-tcp-0.88.tar.gz \
|
||||
# && cd /tmp/ucspi-tcp-0.88 \
|
||||
# && tar -xvf /tmp/ucspi-tcp.tar.gz --strip-components=1 \
|
||||
#&& \
|
||||
#echo "**** Build and install ucspi-tcp ****" \
|
||||
# && wget -O /tmp/ucspi-tcp-0.88/ucspi-tcp-0.88.errno.patch https://git.alpinelinux.org/aports/plain/testing/ucspi-tcp/ucspi-tcp-0.88.errno.patch \
|
||||
# && wget -O /tmp/ucspi-tcp-0.88/ucspi-tcp-0.88.a_record.patch https://git.alpinelinux.org/aports/plain/testing/ucspi-tcp/ucspi-tcp-0.88.a_record.patch \
|
||||
# && patch -p1 --input=ucspi-tcp-0.88.errno.patch \
|
||||
# && patch -p1 --input=ucspi-tcp-0.88.a_record.patch \
|
||||
# && sed -i 's|^/usr/local|/usr|' /tmp/ucspi-tcp-0.88/conf-home \
|
||||
# && make \
|
||||
# && for f in tcpserver tcprules tcprulescheck argv0 recordio tcpclient *\@ tcpcat mconnect mconnect-io addcr delcr fixcrio rblsmtpd; do \
|
||||
# cp $f /usr/bin/$f; \
|
||||
# done \
|
||||
#&& \
|
||||
echo "**** Section cleanup ****" \
|
||||
&& pacman -Scc --noconfirm \
|
||||
&& rm -fr /var/lib/pacman/sync/* \
|
||||
&& rm -fr /var/cache/pacman/pkg/* \
|
||||
&& \
|
||||
echo
|
||||
|
||||
# Setup video streaming deps
|
||||
RUN \
|
||||
echo "**** Install video streaming deps ****" \
|
||||
&& pacman -Syu --noconfirm --needed \
|
||||
libva \
|
||||
libva-mesa-driver \
|
||||
libva-intel-driver \
|
||||
&& \
|
||||
echo "**** Section cleanup ****" \
|
||||
&& pacman -Scc --noconfirm \
|
||||
&& rm -fr /var/lib/pacman/sync/* \
|
||||
&& rm -fr /var/cache/pacman/pkg/* \
|
||||
&& \
|
||||
echo
|
||||
|
||||
# Install tools for monitoring hardware
|
||||
RUN \
|
||||
echo "**** Install audio streaming deps ****" \
|
||||
&& pacman -Syu --noconfirm --needed \
|
||||
#cpu-x \
|
||||
htop \
|
||||
libva-utils \
|
||||
vdpauinfo \
|
||||
&& \
|
||||
echo "**** Section cleanup ****" \
|
||||
&& pacman -Scc --noconfirm \
|
||||
&& rm -fr /var/lib/pacman/sync/* \
|
||||
&& rm -fr /var/cache/pacman/pkg/* \
|
||||
&& \
|
||||
echo
|
||||
|
||||
# Install Sunshine
|
||||
RUN \
|
||||
echo "**** Install stable sunshine ****" \
|
||||
&& su - default -c "yay -Syu --noconfirm --needed miniupnpc sunshine-bin" \
|
||||
&& setcap cap_sys_admin+p $(readlink -f $(which sunshine)) \
|
||||
&& \
|
||||
echo "**** Section cleanup ****" \
|
||||
&& pacman -Scc --noconfirm \
|
||||
&& rm -fr /home/default/.cache/yay \
|
||||
&& rm -fr /var/lib/pacman/sync/* \
|
||||
&& rm -fr /var/cache/pacman/pkg/* \
|
||||
&& rm -rf /tmp/yay* \
|
||||
&& \
|
||||
echo
|
||||
|
||||
# Install Firefox
|
||||
RUN \
|
||||
echo "**** Install Firefox ****" \
|
||||
&& pacman -Syu --noconfirm --needed \
|
||||
firefox \
|
||||
&& \
|
||||
echo "**** Section cleanup ****" \
|
||||
&& pacman -Scc --noconfirm \
|
||||
&& rm -fr /var/lib/pacman/sync/* \
|
||||
&& rm -fr /var/cache/pacman/pkg/* \
|
||||
&& \
|
||||
echo
|
||||
|
||||
# # Install Steam
|
||||
# RUN \
|
||||
# echo "**** Install steam ****" \
|
||||
# && pacman -Syu --noconfirm --needed \
|
||||
# lib32-vulkan-icd-loader
|
||||
# steam \
|
||||
# vulkan-icd-loader \
|
||||
# && \
|
||||
# echo "**** Section cleanup ****" \
|
||||
# && pacman -Scc --noconfirm \
|
||||
# && \
|
||||
# echo
|
||||
|
||||
# Install desktop environment
|
||||
# Install Steam
|
||||
RUN \
|
||||
echo "**** Install desktop environment ****" \
|
||||
echo "**** Install Steam ****" \
|
||||
&& pacman -Syu --noconfirm --needed \
|
||||
gedit \
|
||||
xfce4 \
|
||||
xfce4-terminal \
|
||||
steam \
|
||||
&& \
|
||||
echo "**** Section cleanup ****" \
|
||||
&& pacman -Scc --noconfirm \
|
||||
&& rm -fr /var/lib/pacman/sync/* \
|
||||
&& rm -fr /var/cache/pacman/pkg/* \
|
||||
&& \
|
||||
echo
|
||||
|
||||
|
||||
# Add support for flatpaks
|
||||
# Various other tools
|
||||
ARG DUMB_INIT_VERSION=1.2.5
|
||||
ARG DUMB_UDEV_VERSION=64d1427
|
||||
RUN \
|
||||
echo "**** Install flatpak support ****" \
|
||||
&& pacman -Syu --noconfirm --needed \
|
||||
flatpak \
|
||||
xdg-desktop-portal-gtk \
|
||||
echo "**** Install dumb-init ****" \
|
||||
&& wget --no-check-certificate --no-cookies --quiet \
|
||||
-O /usr/bin/dumb-init \
|
||||
https://github.com/Yelp/dumb-init/releases/download/v${DUMB_INIT_VERSION}/dumb-init_${DUMB_INIT_VERSION}_x86_64 \
|
||||
&& chmod +x /usr/bin/dumb-init \
|
||||
&& \
|
||||
echo "**** Install dumb-udev ****" \
|
||||
&& python3 -m pip install \
|
||||
--break-system-packages \
|
||||
--pre \
|
||||
--upgrade \
|
||||
--no-cache-dir \
|
||||
git+https://github.com/Steam-Headless/dumb-udev.git@${DUMB_UDEV_VERSION} \
|
||||
&& \
|
||||
echo
|
||||
|
||||
# Install Protonup replacement
|
||||
RUN \
|
||||
echo "**** Install PorotonUP ****" \
|
||||
&& su - default -c "yay -Sy --noconfirm --needed --overwrite \"/usr/bin/normalizer\" protonup-qt" \
|
||||
&& \
|
||||
echo "**** Section cleanup ****" \
|
||||
&& pacman -Scc --noconfirm \
|
||||
&& rm -fr /home/default/.cache/yay \
|
||||
&& rm -fr /var/lib/pacman/sync/* \
|
||||
&& rm -fr /var/cache/pacman/pkg/* \
|
||||
&& rm -rf /tmp/yay* \
|
||||
&& \
|
||||
echo
|
||||
|
||||
|
||||
# TODO Append to tools
|
||||
RUN \
|
||||
echo "**** Install flatpak support ****" \
|
||||
&& pacman -Syu --noconfirm --needed \
|
||||
patch \
|
||||
&& \
|
||||
echo "**** Section cleanup ****" \
|
||||
&& pacman -Scc --noconfirm \
|
||||
&& \
|
||||
echo
|
||||
|
||||
|
||||
|
||||
# # Install desktop environment
|
||||
# RUN \
|
||||
# echo "**** Install desktop environment ****" \
|
||||
# && pacman -Syu --noconfirm --needed \
|
||||
# kde-system-meta \
|
||||
# konsole \
|
||||
# plasma-desktop \
|
||||
# && \
|
||||
# echo "**** Section cleanup ****" \
|
||||
# && pacman -Scc --noconfirm \
|
||||
# && \
|
||||
# echo
|
||||
|
||||
# # Install desktop environment
|
||||
# RUN \
|
||||
# echo "**** Install desktop environment ****" \
|
||||
# && pacman -Syu --noconfirm --needed \
|
||||
# cinnamon \
|
||||
# polkit-gnome \
|
||||
# gnome-terminal \
|
||||
# && \
|
||||
# echo "**** Section cleanup ****" \
|
||||
# && pacman -Scc --noconfirm \
|
||||
# && \
|
||||
# echo
|
||||
|
||||
# # Setup browser audio streaming deps
|
||||
# RUN \
|
||||
# echo "**** Update apt database ****" \
|
||||
# && apt-get update \
|
||||
# && \
|
||||
# echo "**** Install audio streaming deps ****" \
|
||||
# && apt-get install -y --no-install-recommends \
|
||||
# bzip2 \
|
||||
# gstreamer1.0-alsa \
|
||||
# gstreamer1.0-gl \
|
||||
# gstreamer1.0-gtk3 \
|
||||
# gstreamer1.0-libav \
|
||||
# gstreamer1.0-plugins-base \
|
||||
# gstreamer1.0-plugins-good \
|
||||
# gstreamer1.0-pulseaudio \
|
||||
# gstreamer1.0-qt5 \
|
||||
# gstreamer1.0-tools \
|
||||
# gstreamer1.0-x \
|
||||
# libgstreamer1.0-0 \
|
||||
# libncursesw5 \
|
||||
# libopenal1 \
|
||||
# libsdl-image1.2 \
|
||||
# libsdl-ttf2.0-0 \
|
||||
# libsdl1.2debian \
|
||||
# libsndfile1 \
|
||||
# ucspi-tcp \
|
||||
# && \
|
||||
# echo "**** Section cleanup ****" \
|
||||
# && apt-get clean autoclean -y \
|
||||
# && apt-get autoremove -y \
|
||||
# && rm -rf \
|
||||
# /var/lib/apt/lists/* \
|
||||
# /var/tmp/* \
|
||||
# /tmp/* \
|
||||
# && \
|
||||
# echo
|
||||
|
||||
# Configure default user and set env
|
||||
ENV \
|
||||
USER="default" \
|
||||
USER_PASSWORD="password" \
|
||||
USER_HOME="/home/default" \
|
||||
TZ="Pacific/Auckland" \
|
||||
USER_LOCALES="en_US.UTF-8 UTF-8"
|
||||
RUN \
|
||||
echo "**** Configure default user '${USER}' ****" \
|
||||
&& mkdir -p \
|
||||
${USER_HOME} \
|
||||
&& useradd -d ${USER_HOME} -s /bin/bash ${USER} \
|
||||
&& chown -R ${USER} \
|
||||
${USER_HOME} \
|
||||
&& echo "${USER} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
|
||||
|
||||
# Add FS overlay
|
||||
COPY overlay /
|
||||
|
||||
# Tweaks as flatpak issue isn't sorted
|
||||
RUN \
|
||||
echo "**** Tweaks for Arch ****" \
|
||||
&& sed -i d /usr/bin/install_firefox.sh \
|
||||
&& sed -i d /usr/bin/install_protonup.sh \
|
||||
&& sed -i d /templates/home_directory_template/.local/share/xfce4/helpers/custom-WebBrowser.desktop \
|
||||
&& \
|
||||
echo
|
||||
|
||||
# Set display environment variables
|
||||
ENV \
|
||||
DISPLAY_CDEPTH="24" \
|
||||
DISPLAY_REFRESH="60" \
|
||||
DISPLAY_REFRESH="120" \
|
||||
DISPLAY_SIZEH="900" \
|
||||
DISPLAY_SIZEW="1600" \
|
||||
DISPLAY_VIDEO_PORT="DFP" \
|
||||
DISPLAY=":55" \
|
||||
DISPLAY=":55"
|
||||
ENV \
|
||||
NVIDIA_DRIVER_CAPABILITIES="all" \
|
||||
NVIDIA_VISIBLE_DEVICES="all"
|
||||
|
||||
# Set container configuration environment variables
|
||||
# APPIMAGE_EXTRACT_AND_RUN="0"
|
||||
ENV \
|
||||
MODE="primary" \
|
||||
ENABLE_VNC_AUDIO="true"
|
||||
WEB_UI_MODE="vnc" \
|
||||
ENABLE_VNC_AUDIO="true" \
|
||||
NEKO_PASSWORD=neko \
|
||||
NEKO_PASSWORD_ADMIN=admin \
|
||||
ENABLE_STEAM="true" \
|
||||
STEAM_ARGS="-silent" \
|
||||
ENABLE_SUNSHINE="true" \
|
||||
ENABLE_EVDEV_INPUTS="true" \
|
||||
ENABLE_WOL_POWER_MANAGER="false"
|
||||
|
||||
# Configure required ports
|
||||
ENV \
|
||||
PORT_SSH="" \
|
||||
PORT_NOVNC_WEB="8083"
|
||||
PORT_NOVNC_WEB="8083" \
|
||||
NEKO_NAT1TO1=""
|
||||
|
||||
# Expose the required ports
|
||||
EXPOSE 8083
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
FROM debian:bullseye-slim
|
||||
FROM debian:bookworm-slim
|
||||
LABEL maintainer="Josh.5 <jsunnex@gmail.com>"
|
||||
|
||||
# Update package repos
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
RUN \
|
||||
echo "**** Update apt database ****" \
|
||||
&& sed -i '/^.*main/ s/$/ contrib non-free/' /etc/apt/sources.list \
|
||||
&& sed -i '/^Components: main/ s/$/ contrib non-free/' /etc/apt/sources.list.d/debian.sources \
|
||||
&& \
|
||||
echo
|
||||
|
||||
@@ -70,6 +70,7 @@ RUN \
|
||||
mlocate \
|
||||
nano \
|
||||
net-tools \
|
||||
p7zip-full \
|
||||
patch \
|
||||
pciutils \
|
||||
pkg-config \
|
||||
@@ -82,6 +83,7 @@ RUN \
|
||||
unzip \
|
||||
vim \
|
||||
wget \
|
||||
xmlstarlet \
|
||||
xz-utils \
|
||||
&& \
|
||||
echo "**** Install python ****" \
|
||||
@@ -90,6 +92,7 @@ RUN \
|
||||
python3-numpy \
|
||||
python3-pip \
|
||||
python3-setuptools \
|
||||
python3-venv \
|
||||
&& \
|
||||
echo "**** Section cleanup ****" \
|
||||
&& apt-get clean autoclean -y \
|
||||
@@ -101,6 +104,27 @@ RUN \
|
||||
&& \
|
||||
echo
|
||||
|
||||
# Configure default user and set user env
|
||||
ENV \
|
||||
PUID=99 \
|
||||
PGID=100 \
|
||||
UMASK=000 \
|
||||
USER="default" \
|
||||
USER_PASSWORD="password" \
|
||||
USER_HOME="/home/default" \
|
||||
TZ="Pacific/Auckland" \
|
||||
USER_LOCALES="en_US.UTF-8 UTF-8"
|
||||
RUN \
|
||||
echo "**** Configure default user '${USER}' ****" \
|
||||
&& mkdir -p \
|
||||
${USER_HOME} \
|
||||
&& useradd -d ${USER_HOME} -s /bin/bash ${USER} \
|
||||
&& chown -R ${USER} \
|
||||
${USER_HOME} \
|
||||
&& echo "${USER} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers \
|
||||
&& \
|
||||
echo
|
||||
|
||||
# Install supervisor
|
||||
RUN \
|
||||
echo "**** Update apt database ****" \
|
||||
@@ -120,48 +144,13 @@ RUN \
|
||||
&& \
|
||||
echo
|
||||
|
||||
# Install mesa and vulkan requirements
|
||||
RUN \
|
||||
echo "**** Update apt database ****" \
|
||||
&& dpkg --add-architecture i386 \
|
||||
&& apt-get update \
|
||||
&& \
|
||||
echo "**** Install mesa requirements ****" \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
libgl1-mesa-dri \
|
||||
libgl1-mesa-glx \
|
||||
libgles2-mesa \
|
||||
libglu1-mesa \
|
||||
mesa-utils \
|
||||
mesa-utils-extra \
|
||||
&& \
|
||||
echo "**** Install vulkan requirements ****" \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
libvulkan1 \
|
||||
libvulkan1:i386 \
|
||||
mesa-vulkan-drivers \
|
||||
mesa-vulkan-drivers:i386 \
|
||||
vulkan-tools \
|
||||
&& \
|
||||
echo "**** Install desktop requirements ****" \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
libdbus-1-3 \
|
||||
libegl1 \
|
||||
libgtk-3-0 \
|
||||
libgtk2.0-0 \
|
||||
libsdl2-2.0-0 \
|
||||
&& \
|
||||
echo "**** Section cleanup ****" \
|
||||
&& apt-get clean autoclean -y \
|
||||
&& apt-get autoremove -y \
|
||||
&& rm -rf \
|
||||
/var/lib/apt/lists/* \
|
||||
/var/tmp/* \
|
||||
/tmp/* \
|
||||
&& \
|
||||
echo
|
||||
|
||||
# Install X Server requirements
|
||||
# TODO: Refine this list of packages to only what is required.
|
||||
ENV \
|
||||
XORG_SOCKET_DIR="/tmp/.X11-unix" \
|
||||
XDG_RUNTIME_DIR="/tmp/.X11-unix/run" \
|
||||
XDG_SESSION_TYPE="x11" \
|
||||
FORCE_X11_DUMMY_CONFIG="false"
|
||||
RUN \
|
||||
echo "**** Update apt database ****" \
|
||||
&& apt-get update \
|
||||
@@ -173,6 +162,7 @@ RUN \
|
||||
libxcomposite-dev \
|
||||
libxcursor1 \
|
||||
wmctrl \
|
||||
libfuse2 \
|
||||
x11-utils \
|
||||
x11-xfs-utils \
|
||||
x11-xkb-utils \
|
||||
@@ -181,6 +171,7 @@ RUN \
|
||||
xauth \
|
||||
xbindkeys \
|
||||
xclip \
|
||||
xcvt \
|
||||
xdotool \
|
||||
xfishtank \
|
||||
xfonts-base \
|
||||
@@ -192,7 +183,6 @@ RUN \
|
||||
xserver-xorg-legacy \
|
||||
xserver-xorg-video-all \
|
||||
xserver-xorg-video-dummy \
|
||||
xvfb \
|
||||
&& \
|
||||
echo "**** Section cleanup ****" \
|
||||
&& apt-get clean autoclean -y \
|
||||
@@ -205,11 +195,14 @@ RUN \
|
||||
echo
|
||||
|
||||
# Install audio requirements
|
||||
ENV \
|
||||
PULSE_SOCKET_DIR="/tmp/pulse" \
|
||||
PULSE_SERVER="unix:/tmp/pulse/pulse-socket"
|
||||
RUN \
|
||||
echo "**** Update apt database ****" \
|
||||
&& apt-get update \
|
||||
&& \
|
||||
echo "**** Install X Server requirements ****" \
|
||||
echo "**** Install pulseaudio requirements ****" \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
pulseaudio \
|
||||
alsa-utils \
|
||||
@@ -227,17 +220,28 @@ RUN \
|
||||
echo
|
||||
|
||||
# Install desktop environment
|
||||
# TODO: Specify all needed packages and add '--no-install-recommends'
|
||||
RUN \
|
||||
echo "**** Update apt database ****" \
|
||||
&& apt-get update \
|
||||
&& \
|
||||
echo "**** Install desktop requirements ****" \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
libdbus-1-3 \
|
||||
libegl1 \
|
||||
libgtk-3-0 \
|
||||
libgtk2.0-0 \
|
||||
libsdl2-2.0-0 \
|
||||
&& \
|
||||
echo "**** Install desktop environment ****" \
|
||||
&& apt-get install -y \
|
||||
xfce4 \
|
||||
xfce4-terminal \
|
||||
msttcorefonts \
|
||||
fonts-vlgothic \
|
||||
gedit \
|
||||
imagemagick \
|
||||
msttcorefonts \
|
||||
xdg-utils \
|
||||
xfce4 \
|
||||
xfce4-terminal \
|
||||
# Delete these as they are not needed at all
|
||||
&& rm -f \
|
||||
/usr/share/applications/software-properties-drivers.desktop \
|
||||
@@ -247,17 +251,26 @@ RUN \
|
||||
&& sed -i '/[Desktop Entry]/a\NoDisplay=true' /usr/share/applications/xfce4-accessibility-settings.desktop \
|
||||
&& sed -i '/[Desktop Entry]/a\NoDisplay=true' /usr/share/applications/xfce4-color-settings.desktop \
|
||||
&& sed -i '/[Desktop Entry]/a\NoDisplay=true' /usr/share/applications/xfce4-mail-reader.desktop \
|
||||
&& sed -i '/[Desktop Entry]/a\NoDisplay=true' /usr/share/applications/xfce4-web-browser.desktop \
|
||||
&& sed -i '/[Desktop Entry]/a\NoDisplay=true' /usr/share/applications/vim.desktop \
|
||||
&& sed -i '/[Desktop Entry]/a\NoDisplay=true' /usr/share/applications/thunar-settings.desktop \
|
||||
&& sed -i '/[Desktop Entry]/a\NoDisplay=true' /usr/share/applications/thunar.desktop \
|
||||
&& sed -i '/[Desktop Entry]/a\NoDisplay=true' /usr/share/applications/pavucontrol.desktop \
|
||||
&& sed -i '/[Desktop Entry]/a\NoDisplay=true' /usr/share/applications/debian-uxterm.desktop \
|
||||
&& sed -i '/[Desktop Entry]/a\NoDisplay=true' /usr/share/applications/x11vnc.desktop \
|
||||
&& sed -i '/[Desktop Entry]/a\NoDisplay=true' /usr/share/applications/display-im6.q16.desktop \
|
||||
# These are named specifically for Debain
|
||||
&& sed -i '/[Desktop Entry]/a\NoDisplay=true' /usr/share/applications/debian-xterm.desktop \
|
||||
&& sed -i '/[Desktop Entry]/a\NoDisplay=true' /usr/share/applications/debian-uxterm.desktop \
|
||||
# Force these apps to be "System" Apps rather than "Categories=System;Utility;Core;GTK;Filesystem;"
|
||||
&& sed -i 's/^Categories=.*$/Categories=System;/' /usr/share/applications/xfce4-appfinder.desktop \
|
||||
&& sed -i 's/^Categories=.*$/Categories=System;/' /usr/share/applications/thunar-bulk-rename.desktop \
|
||||
&& sed -i 's/^Categories=.*$/Categories=System;/' /usr/share/applications/org.gnome.gedit.desktop \
|
||||
&& \
|
||||
echo "**** Install WoL Manager requirements ****" \
|
||||
&& apt-get install -y \
|
||||
tcpdump \
|
||||
xprintidle \
|
||||
&& \
|
||||
echo "**** Section cleanup ****" \
|
||||
&& apt-get clean autoclean -y \
|
||||
&& apt-get autoremove -y \
|
||||
@@ -269,23 +282,20 @@ RUN \
|
||||
echo
|
||||
|
||||
# Add support for flatpaks
|
||||
ENV \
|
||||
XDG_DATA_DIRS="/home/default/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share/:/usr/share/"
|
||||
RUN \
|
||||
echo "**** Update apt database ****" \
|
||||
&& apt-get update \
|
||||
&& \
|
||||
echo "**** Install flatpak support ****" \
|
||||
&& apt-get install -y \
|
||||
bridge-utils \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
flatpak \
|
||||
gnome-software-plugin-flatpak \
|
||||
libpam-cgfs \
|
||||
libvirt0 \
|
||||
lxc \
|
||||
uidmap \
|
||||
&& \
|
||||
echo "**** Configure flatpak ****" \
|
||||
&& chmod u+s /usr/bin/bwrap \
|
||||
&& flatpak remote-add flathub https://flathub.org/repo/flathub.flatpakrepo \
|
||||
&& dpkg-statoverride --update --add root root 0755 /usr/bin/bwrap \
|
||||
&& \
|
||||
echo "**** Section cleanup ****" \
|
||||
&& apt-get clean autoclean -y \
|
||||
@@ -297,98 +307,55 @@ RUN \
|
||||
&& \
|
||||
echo
|
||||
|
||||
# Setup dind
|
||||
# Ref:
|
||||
# - https://github.com/docker-library/docker/blob/master/20.10/dind/Dockerfile
|
||||
# - https://docs.nvidia.com/ai-enterprise/deployment-guide/dg-docker.html
|
||||
ARG DOCKER_VERSION=20.10.18
|
||||
ARG DOCKER_COMPOSE_VERSION=v2.11.2
|
||||
# Install Web Frontend
|
||||
ARG NODE_VERSION="v20"
|
||||
ARG FRONTEND_VERSION=a8eb92f
|
||||
RUN \
|
||||
echo "**** Fetch Docker static binary package ****" \
|
||||
&& cd /tmp \
|
||||
&& wget -O /tmp/docker-${DOCKER_VERSION}.tgz \
|
||||
https://download.docker.com/linux/static/stable/x86_64/docker-${DOCKER_VERSION}.tgz \
|
||||
echo "**** Install Node ${NODE_VERSION} ****" \
|
||||
&& mkdir -p /tmp/nodejs \
|
||||
&& rm -rf /opt/nodejs \
|
||||
&& wget -qO /tmp/nodejs/nodejs.tar.xz \
|
||||
"https://nodejs.org/dist/latest-${NODE_VERSION:?}.x/node-$(wget -qO- https://nodejs.org/dist/latest-${NODE_VERSION:?}.x/ | sed -nE 's|.*>node-(.*)-linux-x64\.tar.xz</a>.*|\1|p')-linux-x64.tar.xz" \
|
||||
&& tar -xJf /tmp/nodejs/nodejs.tar.xz -C /tmp/nodejs --strip-components=1 \
|
||||
&& mv /tmp/nodejs /opt/nodejs \
|
||||
&& ln -sf /opt/nodejs/bin/node /usr/local/bin/node \
|
||||
&& ln -sf /opt/nodejs/bin/npm /usr/local/bin/npm \
|
||||
&& ln -sf /opt/nodejs/bin/npx /usr/local/bin/npx \
|
||||
&& \
|
||||
echo "**** Extract static binaries ****" \
|
||||
&& mkdir -p /usr/local/bin \
|
||||
&& tar --extract \
|
||||
--file /tmp/docker-${DOCKER_VERSION}.tgz \
|
||||
--strip-components 1 \
|
||||
--directory /usr/local/bin/ \
|
||||
--no-same-owner \
|
||||
&& \
|
||||
echo "**** Install docker-compose ****" \
|
||||
&& wget -O /usr/local/bin/docker-compose "https://github.com/docker/compose/releases/download/$DOCKER_COMPOSE_VERSION/docker-compose-Linux-x86_64" \
|
||||
&& chmod +x /usr/local/bin/docker-compose \
|
||||
&& \
|
||||
echo "**** Install nvidia runtime ****" \
|
||||
&& distribution=$(. /etc/os-release;echo $ID$VERSION_ID) \
|
||||
&& curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | apt-key add - \
|
||||
&& curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | tee /etc/apt/sources.list.d/nvidia-docker.list \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y \
|
||||
nvidia-container-toolkit \
|
||||
&& \
|
||||
echo "**** Section cleanup ****" \
|
||||
&& apt-get clean autoclean -y \
|
||||
&& apt-get autoremove -y \
|
||||
&& rm -rf \
|
||||
/var/lib/apt/lists/* \
|
||||
/var/tmp/* \
|
||||
/tmp/* \
|
||||
&& \
|
||||
echo
|
||||
VOLUME /var/lib/docker
|
||||
|
||||
# TODO: Deprecate neko and noVNC for KasmVNC
|
||||
# Install Neko server
|
||||
COPY --from=m1k1o/neko:base /usr/bin/neko /usr/bin/neko
|
||||
COPY --from=m1k1o/neko:base /var/www /var/www
|
||||
|
||||
# Install noVNC
|
||||
ARG NOVNC_VERSION=1.2.0
|
||||
RUN \
|
||||
echo "**** Fetch noVNC ****" \
|
||||
&& cd /tmp \
|
||||
&& wget -O /tmp/novnc.tar.gz https://github.com/novnc/noVNC/archive/v${NOVNC_VERSION}.tar.gz \
|
||||
&& \
|
||||
echo "**** Extract noVNC ****" \
|
||||
&& cd /tmp \
|
||||
&& tar -xvf /tmp/novnc.tar.gz \
|
||||
&& \
|
||||
echo "**** Configure noVNC ****" \
|
||||
&& cd /tmp/noVNC-${NOVNC_VERSION} \
|
||||
&& sed -i 's/credentials: { password: password } });/credentials: { password: password },\n wsProtocols: ["'"binary"'"] });/g' app/ui.js \
|
||||
echo "**** Fetch Web Frontend ****" \
|
||||
&& mkdir -p /opt \
|
||||
&& rm -rf /opt/noVNC \
|
||||
&& cd /opt \
|
||||
&& mv -f /tmp/noVNC-${NOVNC_VERSION} /opt/noVNC \
|
||||
&& cd /opt/noVNC \
|
||||
&& ln -s vnc.html index.html \
|
||||
&& chmod -R 755 /opt/noVNC \
|
||||
&& rm -rf /opt/frontend \
|
||||
&& git clone https://github.com/Steam-Headless/frontend.git --branch master /opt/frontend \
|
||||
&& cd /opt/frontend \
|
||||
&& git checkout ${FRONTEND_VERSION} 2> /dev/null \
|
||||
&& git submodule init \
|
||||
&& git submodule update --depth 1 --recursive \
|
||||
&& rm -rf /opt/frontend/.git \
|
||||
&& \
|
||||
echo "**** Modify noVNC title ****" \
|
||||
&& sed -i '/ document.title =/c\ document.title = "Steam Headless - noVNC";' \
|
||||
/opt/noVNC/app/ui.js \
|
||||
echo "**** Configure Web Frontend ****" \
|
||||
&& echo '<!DOCTYPE html>' > /opt/frontend/index.html \
|
||||
&& echo '<html><head><meta http-equiv="refresh" content="0;url=./web/"></head><body><p>If you are not redirected, <a href="./web/">click here</a>.</p></body></html>' >> /opt/frontend/index.html \
|
||||
&& chmod -R 755 /opt/frontend \
|
||||
&& convert /opt/frontend/web/images/icons/novnc-ios-180.png -resize "128x128" /tmp/steam-headless.png \
|
||||
&& xdg-icon-resource install --novendor --size 128 /tmp/steam-headless.png \
|
||||
&& \
|
||||
echo "**** Section cleanup ****" \
|
||||
&& rm -f /tmp/steam-headless.png
|
||||
|
||||
# Install Websockify
|
||||
ARG WEBSOCKETIFY_VERSION=0.11.0
|
||||
RUN \
|
||||
echo "**** Update apt database ****" \
|
||||
&& apt-get update \
|
||||
&& \
|
||||
echo "**** Install nginx support ****" \
|
||||
echo "**** Install Websockify dependencies ****" \
|
||||
&& apt-get install -y \
|
||||
nginx \
|
||||
python3-numpy \
|
||||
python3-requests \
|
||||
python3-jwcrypto \
|
||||
python3-redis \
|
||||
&& \
|
||||
echo "**** Section cleanup ****" \
|
||||
&& apt-get clean autoclean -y \
|
||||
&& apt-get autoremove -y \
|
||||
&& rm -rf \
|
||||
/var/lib/apt/lists/* \
|
||||
/tmp/noVNC* \
|
||||
/tmp/novnc.tar.gz
|
||||
|
||||
# Install Websockify
|
||||
ARG WEBSOCKETIFY_VERSION=0.10.0
|
||||
RUN \
|
||||
echo "**** Fetch Websockify ****" \
|
||||
&& cd /tmp \
|
||||
&& wget -O /tmp/websockify.tar.gz https://github.com/novnc/websockify/archive/v${WEBSOCKETIFY_VERSION}.tar.gz \
|
||||
@@ -397,16 +364,15 @@ RUN \
|
||||
&& cd /tmp \
|
||||
&& tar -xvf /tmp/websockify.tar.gz \
|
||||
&& \
|
||||
echo "**** Install Websockify to main ****" \
|
||||
&& cd /tmp/websockify-${WEBSOCKETIFY_VERSION} \
|
||||
&& python3 ./setup.py install \
|
||||
&& \
|
||||
echo "**** Install Websockify to noVNC path ****" \
|
||||
echo "**** Install Websockify to Web Frontend path ****" \
|
||||
&& cd /tmp \
|
||||
&& mv -v /tmp/websockify-${WEBSOCKETIFY_VERSION} /opt/noVNC/utils/websockify \
|
||||
&& mv -v /tmp/websockify-${WEBSOCKETIFY_VERSION} /opt/frontend/utils/websockify \
|
||||
&& \
|
||||
echo "**** Section cleanup ****" \
|
||||
&& apt-get clean autoclean -y \
|
||||
&& apt-get autoremove -y \
|
||||
&& rm -rf \
|
||||
/var/lib/apt/lists/* \
|
||||
/tmp/websockify-* \
|
||||
/tmp/websockify.tar.gz
|
||||
|
||||
@@ -460,6 +426,26 @@ RUN \
|
||||
intel-media-va-driver-non-free \
|
||||
i965-va-driver-shaders \
|
||||
libva2 \
|
||||
&& \
|
||||
echo "**** Section cleanup ****" \
|
||||
&& apt-get clean autoclean -y \
|
||||
&& apt-get autoremove -y \
|
||||
&& rm -rf \
|
||||
/var/lib/apt/lists/* \
|
||||
/var/tmp/* \
|
||||
/tmp/* \
|
||||
&& \
|
||||
echo
|
||||
|
||||
# Install tools for monitoring hardware
|
||||
RUN \
|
||||
echo "**** Update apt database ****" \
|
||||
&& apt-get update \
|
||||
&& \
|
||||
echo "**** Install useful HW monitoring tools ****" \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
cpu-x \
|
||||
htop \
|
||||
vainfo \
|
||||
vdpauinfo \
|
||||
&& \
|
||||
@@ -473,25 +459,74 @@ RUN \
|
||||
&& \
|
||||
echo
|
||||
|
||||
|
||||
# Configure default user and set env
|
||||
ENV \
|
||||
PUID=99 \
|
||||
PGID=100 \
|
||||
UMASK=000 \
|
||||
USER="default" \
|
||||
USER_PASSWORD="password" \
|
||||
USER_HOME="/home/default" \
|
||||
TZ="Pacific/Auckland" \
|
||||
USER_LOCALES="en_US.UTF-8 UTF-8"
|
||||
# Install Steam
|
||||
RUN \
|
||||
echo "**** Configure default user '${USER}' ****" \
|
||||
&& mkdir -p \
|
||||
${USER_HOME} \
|
||||
&& useradd -d ${USER_HOME} -s /bin/bash ${USER} \
|
||||
&& chown -R ${USER} \
|
||||
${USER_HOME} \
|
||||
&& echo "${USER} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers \
|
||||
echo "**** Update apt database ****" \
|
||||
&& dpkg --add-architecture i386 \
|
||||
&& apt-get update \
|
||||
&& \
|
||||
echo "**** Install Steam ****" \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
steam-installer \
|
||||
gamescope \
|
||||
&& ln -sf /usr/games/steam /usr/bin/steam \
|
||||
&& \
|
||||
echo "**** Section cleanup ****" \
|
||||
&& apt-get clean autoclean -y \
|
||||
&& apt-get autoremove -y \
|
||||
&& rm -rf \
|
||||
/var/lib/apt/lists/* \
|
||||
/var/tmp/* \
|
||||
/tmp/* \
|
||||
&& \
|
||||
echo
|
||||
|
||||
# Install Sunshine
|
||||
COPY --from=lizardbyte/sunshine:v2025.122.141614-debian-bookworm /sunshine.deb /usr/src/sunshine.deb
|
||||
RUN \
|
||||
echo "**** Update apt database ****" \
|
||||
&& apt-get update \
|
||||
&& \
|
||||
echo "**** Install Sunshine requirements ****" \
|
||||
&& apt-get install -y \
|
||||
va-driver-all \
|
||||
&& \
|
||||
echo "**** Install Sunshine ****" \
|
||||
&& apt-get install -y \
|
||||
/usr/src/sunshine.deb \
|
||||
&& \
|
||||
echo "**** Section cleanup ****" \
|
||||
&& apt-get clean autoclean -y \
|
||||
&& apt-get autoremove -y \
|
||||
&& rm -rf \
|
||||
/var/lib/apt/lists/* \
|
||||
/var/tmp/* \
|
||||
/tmp/* \
|
||||
&& \
|
||||
echo
|
||||
|
||||
# TODO: Deprecate neko
|
||||
# Install Neko server
|
||||
COPY --from=m1k1o/neko:base /usr/bin/neko /usr/bin/neko
|
||||
COPY --from=m1k1o/neko:base /var/www /var/www
|
||||
|
||||
# Various other tools
|
||||
ARG DUMB_INIT_VERSION=1.2.5
|
||||
ARG DUMB_UDEV_VERSION=64d1427
|
||||
RUN \
|
||||
echo "**** Install dumb-init ****" \
|
||||
&& wget --no-check-certificate --no-cookies --quiet \
|
||||
-O /usr/bin/dumb-init \
|
||||
https://github.com/Yelp/dumb-init/releases/download/v${DUMB_INIT_VERSION}/dumb-init_${DUMB_INIT_VERSION}_x86_64 \
|
||||
&& chmod +x /usr/bin/dumb-init \
|
||||
&& \
|
||||
echo "**** Install dumb-udev ****" \
|
||||
&& python3 -m pip install \
|
||||
--break-system-packages \
|
||||
--pre \
|
||||
--upgrade \
|
||||
--no-cache-dir \
|
||||
git+https://github.com/Steam-Headless/dumb-udev.git@${DUMB_UDEV_VERSION} \
|
||||
&& \
|
||||
echo
|
||||
|
||||
@@ -505,31 +540,30 @@ ENV \
|
||||
DISPLAY_SIZEH="900" \
|
||||
DISPLAY_SIZEW="1600" \
|
||||
DISPLAY_VIDEO_PORT="DFP" \
|
||||
DISPLAY=":55" \
|
||||
NVIDIA_DRIVER_CAPABILITIES="all" \
|
||||
NVIDIA_VISIBLE_DEVICES="all" \
|
||||
XORG_SOCKET_DIR="/tmp/.X11-unix" \
|
||||
XDG_RUNTIME_DIR="/tmp/.X11-unix/run" \
|
||||
XDG_DATA_DIRS="/home/default/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share/:/usr/share/"
|
||||
|
||||
# Set pulseaudio environment variables
|
||||
DISPLAY=":55"
|
||||
ENV \
|
||||
PULSE_SOCKET_DIR="/tmp/pulse" \
|
||||
PULSE_SERVER="unix:/tmp/pulse/pulse-socket"
|
||||
NVIDIA_DRIVER_CAPABILITIES="all" \
|
||||
NVIDIA_VISIBLE_DEVICES="all"
|
||||
|
||||
# Set container configuration environment variables
|
||||
# TODO: Set the default WEBUI_USER & WEBUI_PASS after release of SHUI
|
||||
ENV \
|
||||
MODE="primary" \
|
||||
WEB_UI_MODE="vnc" \
|
||||
ENABLE_VNC_AUDIO="true" \
|
||||
NEKO_PASSWORD=neko \
|
||||
NEKO_PASSWORD_ADMIN=admin \
|
||||
ENABLE_SUNSHINE="false" \
|
||||
ENABLE_EVDEV_INPUTS="false"
|
||||
ENABLE_STEAM="true" \
|
||||
STEAM_ARGS="-silent" \
|
||||
WEBUI_USER="" \
|
||||
WEBUI_PASS="" \
|
||||
ENABLE_SUNSHINE="true" \
|
||||
ENABLE_EVDEV_INPUTS="true" \
|
||||
ENABLE_WOL_POWER_MANAGER="false" \
|
||||
ENABLE_SID="false"
|
||||
|
||||
# Configure required ports
|
||||
ENV \
|
||||
PORT_SSH="" \
|
||||
PORT_NOVNC_WEB="8083" \
|
||||
NEKO_NAT1TO1=""
|
||||
|
||||
18
README.md
18
README.md
@@ -2,14 +2,22 @@
|
||||
|
||||

|
||||
|
||||
Play your games in the browser with audio. Connect another device and use it with Steam Remote Play. Easily deploy a Steam Docker instance in seconds.
|
||||
Remote Game Streaming Server.
|
||||
|
||||
Play your games either in the browser with audio or via Steam Link or Moonlight. Play from another Steam Client with Steam Remote Play.
|
||||
|
||||
Easily deploy a Steam Docker instance in seconds.
|
||||
|
||||
## Features:
|
||||
- NVIDIA GPU support
|
||||
- AMD GPU support
|
||||
- Steam Client configured for running on Linux with Proton
|
||||
- Moonlight compatible server for easy remote desktop streaming
|
||||
- Easy installation of EmeDeck, Heroic and Lutris via Flatpak
|
||||
- Full video/audio noVNC web access to a Xfce4 Desktop
|
||||
- NVIDIA, AMD and Intel GPU support
|
||||
- Full controller support
|
||||
- Support for Flatpak and Appimage installation
|
||||
- Root access
|
||||
|
||||
- Based on Debian Bookworm
|
||||
|
||||
---
|
||||
## Notes:
|
||||
@@ -18,6 +26,8 @@ Play your games in the browser with audio. Connect another device and use it wit
|
||||
If you wish to install additional applications, you can generate a script inside the `~/init.d` directory ending with ".sh".
|
||||
This will be executed on the container startup.
|
||||
|
||||
Also, you can install applications using the WebUI under **Applications > System > Software**. There you can install other game launchers like Lutris, Heroic or EmuDeck.
|
||||
|
||||
### STORAGE PATHS:
|
||||
Everything that you wish to save in this container should be stored in the home directory or a docker container mount that you have specified.
|
||||
All files that are store outside your home directory are not persistent and will be wiped if there is an update of the container or you change something in the template.
|
||||
|
||||
@@ -1,136 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
###
|
||||
# File: run.sh
|
||||
# Project: docker-steamos
|
||||
# File Created: Saturday, 8th January 2022 2:34:23 pm
|
||||
# Author: Josh.5 (jsunnex@gmail.com)
|
||||
# -----
|
||||
# Last Modified: Tuesday, 8th February 2022 8:00:29 am
|
||||
# Modified By: Console and webGui login account (jsunnex@gmail.com)
|
||||
###
|
||||
|
||||
script_path=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd );
|
||||
project_base_path=$(realpath ${script_path}/..);
|
||||
|
||||
|
||||
# Parse params
|
||||
additional_docker_params=""
|
||||
container_name="steam"
|
||||
tag="develop"
|
||||
for ARG in ${@}; do
|
||||
case ${ARG} in
|
||||
*primary)
|
||||
primary="true";
|
||||
;;
|
||||
*nvidia)
|
||||
nvidia="true";
|
||||
;;
|
||||
*fb)
|
||||
framebuffer="true";
|
||||
;;
|
||||
*br0)
|
||||
network="br0";
|
||||
;;
|
||||
stop)
|
||||
script_mode="stop"
|
||||
;;
|
||||
tail)
|
||||
script_mode="tail"
|
||||
;;
|
||||
user)
|
||||
script_mode="user"
|
||||
;;
|
||||
root)
|
||||
script_mode="root"
|
||||
;;
|
||||
*arch)
|
||||
tag="arch";
|
||||
;;
|
||||
*debian)
|
||||
tag="debian";
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
done
|
||||
if [[ "${primary}" == "true" ]]; then
|
||||
container_name="${container_name}-p"
|
||||
additional_docker_params="${additional_docker_params} -e MODE=primary"
|
||||
hostx="false"
|
||||
elif [[ "${framebuffer}" == "true" ]]; then
|
||||
# TODO: Enable xvfb
|
||||
container_name="${container_name}-fb"
|
||||
additional_docker_params="${additional_docker_params} -e MODE=framebuffer"
|
||||
else
|
||||
container_name="${container_name}-s"
|
||||
additional_docker_params="${additional_docker_params} -e MODE=secondary"
|
||||
fi
|
||||
if [[ "${nvidia}" == "true" ]]; then
|
||||
container_name="${container_name}-hw"
|
||||
additional_docker_params="${additional_docker_params} --runtime=nvidia"
|
||||
fi
|
||||
if [[ "${network}" == "br0" ]]; then
|
||||
additional_docker_params="${additional_docker_params} --network=br0 --ip='192.168.1.208'"
|
||||
else
|
||||
additional_docker_params="${additional_docker_params} --network=host"
|
||||
fi
|
||||
if [[ -e /dev/dri ]]; then
|
||||
additional_docker_params="${additional_docker_params} --device=/dev/dri"
|
||||
fi
|
||||
|
||||
|
||||
# If a mode was given, run that instead
|
||||
if [[ "${script_mode}" == "stop" ]]; then
|
||||
docker stop ${container_name}
|
||||
docker rm ${container_name}
|
||||
exit $?
|
||||
elif [[ "${script_mode}" == "tail" ]]; then
|
||||
docker logs -f ${container_name}
|
||||
exit $?
|
||||
elif [[ "${script_mode}" == "user" ]]; then
|
||||
docker exec -ti --user default ${container_name} bash
|
||||
exit $?
|
||||
elif [[ "${script_mode}" == "root" ]]; then
|
||||
docker exec -ti --user 0 ${container_name} bash
|
||||
exit $?
|
||||
fi
|
||||
|
||||
|
||||
# Stop previous instance
|
||||
docker stop ${container_name}
|
||||
docker rm ${container_name}
|
||||
sleep 1
|
||||
|
||||
|
||||
# Run
|
||||
cmd="docker run -d --name='${container_name}' \
|
||||
--privileged=true \
|
||||
-e PUID='99' \
|
||||
-e PGID='100' \
|
||||
-e UMASK='000' \
|
||||
-e USER_PASSWORD='password' \
|
||||
-e USER='default' \
|
||||
-e USER_HOME='/home/default' \
|
||||
-e TZ='Pacific/Auckland' \
|
||||
-e USER_LOCALES='en_US.UTF-8 UTF-8' \
|
||||
-e DISPLAY_CDEPTH='24' \
|
||||
-e DISPLAY_REFRESH='60' \
|
||||
-e DISPLAY_SIZEH='720' \
|
||||
-e DISPLAY_SIZEW='1280' \
|
||||
-e DISPLAY_VIDEO_PORT='DFP' \
|
||||
-e DISPLAY=':55' \
|
||||
-e NVIDIA_DRIVER_CAPABILITIES='all' \
|
||||
-e NVIDIA_VISIBLE_DEVICES='all' \
|
||||
-e ENABLE_VNC_AUDIO='false' \
|
||||
-v '${project_base_path}/config/home/default-${container_name}':'/home/default':'rw' \
|
||||
-v '/tmp/.X11-unix/':'/tmp/.X11-unix/':'rw' \
|
||||
-v '/dev/input':'/dev/input':'ro' \
|
||||
--hostname='${container_name}' \
|
||||
--add-host=${container_name}:127.0.0.1 \
|
||||
--shm-size=2G \
|
||||
${additional_docker_params} \
|
||||
josh5/steam-headless:${tag}"
|
||||
echo ${cmd}
|
||||
bash -c "${cmd}"
|
||||
|
||||
docker logs -f ${container_name}
|
||||
@@ -5,19 +5,20 @@
|
||||
# |____/ \__, |___/\__\___|_| |_| |_|
|
||||
# |___/
|
||||
#
|
||||
NAME='SteamHeadless'
|
||||
TZ='Pacific/Auckland'
|
||||
USER_LOCALES='en_US.UTF-8 UTF-8'
|
||||
DISPLAY=':55'
|
||||
SHM_SIZE='2G'
|
||||
|
||||
## DOCKER_RUNTIME:
|
||||
## Options: ['runc', 'nvidia']
|
||||
## Description: The name of an implementation of OCI Runtime Spec
|
||||
## Available runtimes are listed when you run `docker info`.
|
||||
## Your system may have other options available. As a simple rule, if you are
|
||||
## using an NVIDIA GPU, set this to 'nvidia' for anything else, set this to 'runc'.
|
||||
DOCKER_RUNTIME='runc'
|
||||
NAME=SteamHeadless
|
||||
TZ=Pacific/Auckland
|
||||
USER_LOCALES=en_US.UTF-8 UTF-8
|
||||
DISPLAY=:55
|
||||
SHM_SIZE=2G
|
||||
## HOME_DIR:
|
||||
## Description: The path to the home directory on your host. Mounts to `/home/default` inside the container.
|
||||
HOME_DIR=/opt/container-data/steam-headless/home
|
||||
## SHARED_SOCKETS_DIR:
|
||||
## Description: Shared sockets such as pulse audio and X11.
|
||||
SHARED_SOCKETS_DIR=/opt/container-data/steam-headless/sockets
|
||||
## GAMES_DIR:
|
||||
## Description: The path to the games directory on your host. Mounts to `/mnt/games` inside the container.
|
||||
GAMES_DIR=/mnt/games
|
||||
|
||||
# ____ __ _ _ _ _
|
||||
# | _ \ ___ / _| __ _ _ _| | |_ | | | |___ ___ _ __
|
||||
@@ -26,10 +27,24 @@ DOCKER_RUNTIME='runc'
|
||||
# |____/ \___|_| \__,_|\__,_|_|\__| \___/|___/\___|_|
|
||||
#
|
||||
#
|
||||
PUID='1000'
|
||||
PGID='1000'
|
||||
UMASK='000'
|
||||
USER_PASSWORD='password'
|
||||
PUID=1000
|
||||
PGID=1000
|
||||
UMASK=000
|
||||
USER_PASSWORD=password
|
||||
|
||||
# __ __ _
|
||||
# | \/ | ___ __| | ___
|
||||
# | |\/| |/ _ \ / _` |/ _ \
|
||||
# | | | | (_) | (_| | __/
|
||||
# |_| |_|\___/ \__,_|\___|
|
||||
#
|
||||
#
|
||||
## MODE:
|
||||
## Options: ['primary', 'secondary']
|
||||
## Description: Steam Headless containers can run in a secondary mode that will only start
|
||||
## a Steam process that will then use the X server of either the host or another
|
||||
## Steam Headless container running in 'primary' mode.
|
||||
MODE=primary
|
||||
|
||||
# ____ _
|
||||
# / ___| ___ _ ____ _(_) ___ ___ ___
|
||||
@@ -38,54 +53,74 @@ USER_PASSWORD='password'
|
||||
# |____/ \___|_| \_/ |_|\___\___||___/
|
||||
#
|
||||
#
|
||||
# Mode
|
||||
## MODE:
|
||||
## Options: ['primary', 'secondary']
|
||||
## Description: Steam Headless containers can run in a secondary mode that will only start
|
||||
## a Steam process that will then use the X server of either the host or another
|
||||
## Steam Headless container running in 'primary' mode.
|
||||
MODE='primary'
|
||||
|
||||
# Web UI
|
||||
## WEB_UI_MODE:
|
||||
## Options: ['vnc', 'neko', 'none']
|
||||
## Description: Configures the WebUI to use for accessing the virtual desktop.
|
||||
WEB_UI_MODE='vnc'
|
||||
## Supported Modes: ['primary']
|
||||
WEB_UI_MODE=vnc
|
||||
## ENABLE_VNC_AUDIO:
|
||||
## Options: ['true', 'false']
|
||||
## Description: Enables audio over for the VNC Web UI if 'WEB_UI_MODE' is set to 'vnc'.
|
||||
ENABLE_VNC_AUDIO='true'
|
||||
ENABLE_VNC_AUDIO=true
|
||||
## PORT_NOVNC_WEB:
|
||||
## Description: Configure the port to use for the WebUI.
|
||||
PORT_NOVNC_WEB='8083'
|
||||
PORT_NOVNC_WEB=8083
|
||||
## NEKO_NAT1TO1:
|
||||
## Description: Configure nat1to1 for the neko WebUI if it is enabled by setting 'WEB_UI_MODE' to 'neko'. This will need to be the IP address of the host.
|
||||
NEKO_NAT1TO1=''
|
||||
## Description: Configure nat1to1 for the neko WebUI if it is enabled by setting 'WEB_UI_MODE' to 'neko'.
|
||||
## This will need to be the IP address of the host.
|
||||
NEKO_NAT1TO1=
|
||||
|
||||
# Steam
|
||||
## ENABLE_STEAM:
|
||||
## Options: ['true', 'false']
|
||||
## Description: Enable Steam to run on start. This will also cause steam to restart automatically if closed.
|
||||
## Supported Modes: ['primary', 'secondary']
|
||||
ENABLE_STEAM=true
|
||||
## STEAM_ARGS:
|
||||
## Description: Additional steam execution arguments.
|
||||
STEAM_ARGS=-silent
|
||||
|
||||
# Sunshine
|
||||
## ENABLE_SUNSHINE:
|
||||
## Options: ['true', 'false']
|
||||
## Description: Enable Sunshine streaming service.
|
||||
ENABLE_SUNSHINE='false'
|
||||
## Supported Modes: ['primary']
|
||||
ENABLE_SUNSHINE=false
|
||||
## SUNSHINE_USER:
|
||||
## Description: Set the Sunshine service username.
|
||||
#SUNSHINE_USER='admin'
|
||||
SUNSHINE_USER=admin
|
||||
## SUNSHINE_PASS:
|
||||
## Description: Set the Sunshine service password.
|
||||
#SUNSHINE_PASS='admin'
|
||||
SUNSHINE_PASS=admin
|
||||
|
||||
# Xorg
|
||||
## ENABLE_EVDEV_INPUTS:
|
||||
## Options: ['true', 'false']
|
||||
## Description: Enable Keyboard and Mouse Passthrough. This will configure the Xorg server to catch all evdev events for Keyboard, Mouse, etc.
|
||||
ENABLE_EVDEV_INPUTS='true'
|
||||
## Available Options: ['true', 'false']
|
||||
## Description: Enable Keyboard and Mouse Passthrough. This will configure the Xorg server to catch all
|
||||
## evdev events for Keyboard, Mouse, etc.
|
||||
## Supported Modes: ['primary']
|
||||
ENABLE_EVDEV_INPUTS=true
|
||||
## FORCE_X11_DUMMY_CONFIG:
|
||||
## Available Options: ['true', 'false']
|
||||
## Description: Forces the installation of xorg.dummy.conf. This should be used when your output device does not have a monitor connected.
|
||||
## Supported Modes: ['primary']
|
||||
FORCE_X11_DUMMY_CONFIG=false
|
||||
|
||||
# Nvidia specific config (not required for non Nvidia GPUs)
|
||||
## NVIDIA_DRIVER_CAPABILITIES:
|
||||
## Options: ['all', 'compute', 'compat32', 'graphics', 'utility', 'video', 'display']
|
||||
## Description: Controls which driver libraries/binaries will be mounted inside the container.
|
||||
NVIDIA_DRIVER_CAPABILITIES='all'
|
||||
## Supported Modes: ['primary', 'secondary']
|
||||
NVIDIA_DRIVER_CAPABILITIES=all
|
||||
## NVIDIA_DRIVER_CAPABILITIES:
|
||||
## Options: ['all', 'none', '<GPU UUID>']
|
||||
## Available Options: ['all', 'none', '<GPU UUID>']
|
||||
## Description: Controls which GPUs will be made accessible inside the container.
|
||||
NVIDIA_VISIBLE_DEVICES='all'
|
||||
## Supported Modes: ['primary', 'secondary']
|
||||
NVIDIA_VISIBLE_DEVICES=all
|
||||
## NVIDIA_DRIVER_VERSION:
|
||||
## Description: Specify a driver version to force installation.
|
||||
## Not meant to be used if nvidia container toolkit is installed.
|
||||
## Detect current host driver installed with `nvidia-smi 2> /dev/null | grep NVIDIA-SMI | cut -d ' ' -f3`
|
||||
## Supported Modes: ['primary', 'secondary']
|
||||
NVIDIA_DRIVER_VERSION=
|
||||
|
||||
76
docs/compose-files/docker-compose.amd+intel.privileged.yml
Normal file
76
docs/compose-files/docker-compose.amd+intel.privileged.yml
Normal file
@@ -0,0 +1,76 @@
|
||||
---
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
steam-headless:
|
||||
image: josh5/steam-headless:latest
|
||||
restart: unless-stopped
|
||||
## NOTE: This config uses privileged to access to host to be able to access the required devices
|
||||
privileged: true
|
||||
shm_size: ${SHM_SIZE}
|
||||
ipc: host # Could also be set to 'shareable'
|
||||
ulimits:
|
||||
nofile:
|
||||
soft: 1024
|
||||
hard: 524288
|
||||
|
||||
# NETWORK:
|
||||
## NOTE: With this configuration, if we do not use the host network, then physical device input
|
||||
## is not possible and your USB connected controllers will not work in steam games.
|
||||
network_mode: host
|
||||
hostname: ${NAME}
|
||||
extra_hosts:
|
||||
- "${NAME}:127.0.0.1"
|
||||
|
||||
# ENVIRONMENT:
|
||||
## Read all config variables from the .env file
|
||||
environment:
|
||||
# System
|
||||
- TZ=${TZ}
|
||||
- USER_LOCALES=${USER_LOCALES}
|
||||
- DISPLAY=${DISPLAY}
|
||||
# User
|
||||
- PUID=${PUID}
|
||||
- PGID=${PGID}
|
||||
- UMASK=${UMASK}
|
||||
- USER_PASSWORD=${USER_PASSWORD}
|
||||
# Mode
|
||||
- MODE=${MODE}
|
||||
# Web UI
|
||||
- WEB_UI_MODE=${WEB_UI_MODE}
|
||||
- ENABLE_VNC_AUDIO=${ENABLE_VNC_AUDIO}
|
||||
- PORT_NOVNC_WEB=${PORT_NOVNC_WEB}
|
||||
- NEKO_NAT1TO1=${NEKO_NAT1TO1}
|
||||
# Steam
|
||||
- ENABLE_STEAM=${ENABLE_STEAM}
|
||||
- STEAM_ARGS=${STEAM_ARGS}
|
||||
# Sunshine
|
||||
- ENABLE_SUNSHINE=${ENABLE_SUNSHINE}
|
||||
- SUNSHINE_USER=${SUNSHINE_USER}
|
||||
- SUNSHINE_PASS=${SUNSHINE_PASS}
|
||||
# Xorg
|
||||
- ENABLE_EVDEV_INPUTS=${ENABLE_EVDEV_INPUTS}
|
||||
- FORCE_X11_DUMMY_CONFIG=${FORCE_X11_DUMMY_CONFIG}
|
||||
# Nvidia specific config
|
||||
- NVIDIA_DRIVER_CAPABILITIES=${NVIDIA_DRIVER_CAPABILITIES}
|
||||
- NVIDIA_VISIBLE_DEVICES=${NVIDIA_VISIBLE_DEVICES}
|
||||
- NVIDIA_DRIVER_VERSION=${NVIDIA_DRIVER_VERSION}
|
||||
|
||||
# VOLUMES:
|
||||
volumes:
|
||||
# The location of your home directory.
|
||||
- ${HOME_DIR}/:/home/default/:rw
|
||||
|
||||
# The location where all games should be installed.
|
||||
# This path needs to be set as a library path in Steam after logging in.
|
||||
# Otherwise, Steam will store games in the home directory above.
|
||||
- ${GAMES_DIR}/:/mnt/games/:rw
|
||||
|
||||
# The Xorg socket.
|
||||
- ${SHARED_SOCKETS_DIR}/.X11-unix/:/tmp/.X11-unix/:rw
|
||||
|
||||
# Pulse audio socket.
|
||||
- ${SHARED_SOCKETS_DIR}/pulse/:/tmp/pulse/:rw
|
||||
|
||||
# Input devices used for mouse and joypad support inside the container.
|
||||
- /dev/input/:/dev/input/:ro
|
||||
92
docs/compose-files/docker-compose.amd+intel.yml
Normal file
92
docs/compose-files/docker-compose.amd+intel.yml
Normal file
@@ -0,0 +1,92 @@
|
||||
---
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
steam-headless:
|
||||
image: josh5/steam-headless:latest
|
||||
restart: unless-stopped
|
||||
shm_size: ${SHM_SIZE}
|
||||
ipc: host # Could also be set to 'shareable'
|
||||
ulimits:
|
||||
nofile:
|
||||
soft: 1024
|
||||
hard: 524288
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
- SYS_ADMIN
|
||||
- SYS_NICE
|
||||
security_opt:
|
||||
- seccomp:unconfined
|
||||
- apparmor:unconfined
|
||||
|
||||
# NETWORK:
|
||||
## NOTE: With this configuration, if we do not use the host network, then physical device input
|
||||
## is not possible and your USB connected controllers will not work in steam games.
|
||||
network_mode: host
|
||||
hostname: ${NAME}
|
||||
extra_hosts:
|
||||
- "${NAME}:127.0.0.1"
|
||||
|
||||
# ENVIRONMENT:
|
||||
## Read all config variables from the .env file
|
||||
environment:
|
||||
# System
|
||||
- TZ=${TZ}
|
||||
- USER_LOCALES=${USER_LOCALES}
|
||||
- DISPLAY=${DISPLAY}
|
||||
# User
|
||||
- PUID=${PUID}
|
||||
- PGID=${PGID}
|
||||
- UMASK=${UMASK}
|
||||
- USER_PASSWORD=${USER_PASSWORD}
|
||||
# Mode
|
||||
- MODE=${MODE}
|
||||
# Web UI
|
||||
- WEB_UI_MODE=${WEB_UI_MODE}
|
||||
- ENABLE_VNC_AUDIO=${ENABLE_VNC_AUDIO}
|
||||
- PORT_NOVNC_WEB=${PORT_NOVNC_WEB}
|
||||
- NEKO_NAT1TO1=${NEKO_NAT1TO1}
|
||||
# Steam
|
||||
- ENABLE_STEAM=${ENABLE_STEAM}
|
||||
- STEAM_ARGS=${STEAM_ARGS}
|
||||
# Sunshine
|
||||
- ENABLE_SUNSHINE=${ENABLE_SUNSHINE}
|
||||
- SUNSHINE_USER=${SUNSHINE_USER}
|
||||
- SUNSHINE_PASS=${SUNSHINE_PASS}
|
||||
# Xorg
|
||||
- ENABLE_EVDEV_INPUTS=${ENABLE_EVDEV_INPUTS}
|
||||
- FORCE_X11_DUMMY_CONFIG=${FORCE_X11_DUMMY_CONFIG}
|
||||
# Nvidia specific config
|
||||
- NVIDIA_DRIVER_CAPABILITIES=${NVIDIA_DRIVER_CAPABILITIES}
|
||||
- NVIDIA_VISIBLE_DEVICES=${NVIDIA_VISIBLE_DEVICES}
|
||||
- NVIDIA_DRIVER_VERSION=${NVIDIA_DRIVER_VERSION}
|
||||
|
||||
# DEVICES:
|
||||
devices:
|
||||
# Use the host fuse device [REQUIRED].
|
||||
- /dev/fuse
|
||||
# Add the host uinput device [REQUIRED].
|
||||
- /dev/uinput
|
||||
# Add AMD/Intel HW accelerated video encoding/decoding devices [REQUIRED].
|
||||
# NOTE: See documentation for determining which devices to configure here if you have multiple GPUs
|
||||
- /dev/dri/card1
|
||||
- /dev/dri/renderD128
|
||||
# Ensure container access to devices 13:*
|
||||
device_cgroup_rules:
|
||||
- 'c 13:* rmw'
|
||||
|
||||
# VOLUMES:
|
||||
volumes:
|
||||
# The location of your home directory.
|
||||
- ${HOME_DIR}/:/home/default/:rw
|
||||
|
||||
# The location where all games should be installed.
|
||||
# This path needs to be set as a library path in Steam after logging in.
|
||||
# Otherwise, Steam will store games in the home directory above.
|
||||
- ${GAMES_DIR}/:/mnt/games/:rw
|
||||
|
||||
# The Xorg socket.
|
||||
- ${SHARED_SOCKETS_DIR}/.X11-unix/:/tmp/.X11-unix/:rw
|
||||
|
||||
# Pulse audio socket.
|
||||
- ${SHARED_SOCKETS_DIR}/pulse/:/tmp/pulse/:rw
|
||||
@@ -1,50 +0,0 @@
|
||||
---
|
||||
services:
|
||||
steam-headless:
|
||||
image: josh5/steam-headless:latest
|
||||
restart: unless-stopped
|
||||
runtime: ${DOCKER_RUNTIME}
|
||||
## NOTE: Requires privileged access to host to be able to access the required devices
|
||||
privileged: true
|
||||
shm_size: ${SHM_SIZE}
|
||||
ipc: host # Could also be set to 'shareable'
|
||||
ulimits:
|
||||
nofile:
|
||||
soft: 1024
|
||||
hard: 524288
|
||||
|
||||
# NETWORK:
|
||||
## NOTE: Steam headless always requires the use of the host network.
|
||||
## If we do not use the host network, then device input is not possible
|
||||
## and your controllers will not work in steam games.
|
||||
network_mode: host
|
||||
hostname: ${NAME}
|
||||
extra_hosts:
|
||||
- "${NAME}:127.0.0.1"
|
||||
|
||||
# ENVIRONMENT:
|
||||
## Read all config variables from the .env file
|
||||
env_file: .env
|
||||
|
||||
# VOLUMES:
|
||||
volumes:
|
||||
# The location of your home directory.
|
||||
- /opt/container-data/steam-headless/home/:/home/default/:rw
|
||||
# The location where all games should be installed.
|
||||
# This path needs to be set as a library path in Steam after logging in.
|
||||
# Otherwise, Steam will store games in the home directory above.
|
||||
- /mnt/games/:/mnt/games/:rw
|
||||
# Input devices used for mouse and joypad support inside the container.
|
||||
- /dev/input/:/dev/input/:ro
|
||||
# The Xorg socket. This will be shared with other containers so they can access the X server.
|
||||
- /opt/container-data/steam-headless/.X11-unix/:/tmp/.X11-unix/:rw
|
||||
# Pulse audio socket. This will be shared with other containers so they can access the audio sink.
|
||||
- /opt/container-data/steam-headless/pulse/:/tmp/pulse/:rw
|
||||
# Store dind var files in a volume
|
||||
- steam-headless-var-lib-docker:/var/lib/docker/:rw
|
||||
# Store flatpak var files in a volume
|
||||
- steam-headless-var-lib-flatpak:/var/lib/flatpak/:rw
|
||||
|
||||
volumes:
|
||||
steam-headless-var-lib-docker:
|
||||
steam-headless-var-lib-flatpak:
|
||||
79
docs/compose-files/docker-compose.nvidia.privileged.yml
Normal file
79
docs/compose-files/docker-compose.nvidia.privileged.yml
Normal file
@@ -0,0 +1,79 @@
|
||||
---
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
steam-headless:
|
||||
image: josh5/steam-headless:latest
|
||||
restart: unless-stopped
|
||||
## NOTE: This config uses privileged to access to host to be able to access the required devices
|
||||
privileged: true
|
||||
shm_size: ${SHM_SIZE}
|
||||
ipc: host # Could also be set to 'shareable'
|
||||
ulimits:
|
||||
nofile:
|
||||
soft: 1024
|
||||
hard: 524288
|
||||
|
||||
# GPU PASSTHROUGH
|
||||
runtime: nvidia
|
||||
|
||||
# NETWORK:
|
||||
## NOTE: With this configuration, if we do not use the host network, then physical device input
|
||||
## is not possible and your USB connected controllers will not work in steam games.
|
||||
network_mode: host
|
||||
hostname: ${NAME}
|
||||
extra_hosts:
|
||||
- "${NAME}:127.0.0.1"
|
||||
|
||||
# ENVIRONMENT:
|
||||
## Read all config variables from the .env file
|
||||
environment:
|
||||
# System
|
||||
- TZ=${TZ}
|
||||
- USER_LOCALES=${USER_LOCALES}
|
||||
- DISPLAY=${DISPLAY}
|
||||
# User
|
||||
- PUID=${PUID}
|
||||
- PGID=${PGID}
|
||||
- UMASK=${UMASK}
|
||||
- USER_PASSWORD=${USER_PASSWORD}
|
||||
# Mode
|
||||
- MODE=${MODE}
|
||||
# Web UI
|
||||
- WEB_UI_MODE=${WEB_UI_MODE}
|
||||
- ENABLE_VNC_AUDIO=${ENABLE_VNC_AUDIO}
|
||||
- PORT_NOVNC_WEB=${PORT_NOVNC_WEB}
|
||||
- NEKO_NAT1TO1=${NEKO_NAT1TO1}
|
||||
# Steam
|
||||
- ENABLE_STEAM=${ENABLE_STEAM}
|
||||
- STEAM_ARGS=${STEAM_ARGS}
|
||||
# Sunshine
|
||||
- ENABLE_SUNSHINE=${ENABLE_SUNSHINE}
|
||||
- SUNSHINE_USER=${SUNSHINE_USER}
|
||||
- SUNSHINE_PASS=${SUNSHINE_PASS}
|
||||
# Xorg
|
||||
- ENABLE_EVDEV_INPUTS=${ENABLE_EVDEV_INPUTS}
|
||||
- FORCE_X11_DUMMY_CONFIG=${FORCE_X11_DUMMY_CONFIG}
|
||||
# Nvidia specific config
|
||||
- NVIDIA_DRIVER_CAPABILITIES=${NVIDIA_DRIVER_CAPABILITIES}
|
||||
- NVIDIA_VISIBLE_DEVICES=${NVIDIA_VISIBLE_DEVICES}
|
||||
- NVIDIA_DRIVER_VERSION=${NVIDIA_DRIVER_VERSION}
|
||||
|
||||
# VOLUMES:
|
||||
volumes:
|
||||
# The location of your home directory.
|
||||
- ${HOME_DIR}/:/home/default/:rw
|
||||
|
||||
# The location where all games should be installed.
|
||||
# This path needs to be set as a library path in Steam after logging in.
|
||||
# Otherwise, Steam will store games in the home directory above.
|
||||
- ${GAMES_DIR}/:/mnt/games/:rw
|
||||
|
||||
# The Xorg socket.
|
||||
- ${SHARED_SOCKETS_DIR}/.X11-unix/:/tmp/.X11-unix/:rw
|
||||
|
||||
# Pulse audio socket.
|
||||
- ${SHARED_SOCKETS_DIR}/pulse/:/tmp/pulse/:rw
|
||||
|
||||
# Input devices used for mouse and joypad support inside the container.
|
||||
- /dev/input/:/dev/input/:ro
|
||||
101
docs/compose-files/docker-compose.nvidia.yml
Normal file
101
docs/compose-files/docker-compose.nvidia.yml
Normal file
@@ -0,0 +1,101 @@
|
||||
---
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
steam-headless:
|
||||
image: josh5/steam-headless:latest
|
||||
restart: unless-stopped
|
||||
shm_size: ${SHM_SIZE}
|
||||
ipc: host # Could also be set to 'shareable'
|
||||
ulimits:
|
||||
nofile:
|
||||
soft: 1024
|
||||
hard: 524288
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
- SYS_ADMIN
|
||||
- SYS_NICE
|
||||
security_opt:
|
||||
- seccomp:unconfined
|
||||
- apparmor:unconfined
|
||||
|
||||
# GPU PASSTHROUGH
|
||||
runtime: nvidia
|
||||
|
||||
# NETWORK:
|
||||
## NOTE: With this configuration, if we do not use the host network, then physical device input
|
||||
## is not possible and your USB connected controllers will not work in steam games.
|
||||
network_mode: host
|
||||
hostname: ${NAME}
|
||||
extra_hosts:
|
||||
- "${NAME}:127.0.0.1"
|
||||
|
||||
# ENVIRONMENT:
|
||||
## Read all config variables from the .env file
|
||||
environment:
|
||||
# System
|
||||
- TZ=${TZ}
|
||||
- USER_LOCALES=${USER_LOCALES}
|
||||
- DISPLAY=${DISPLAY}
|
||||
# User
|
||||
- PUID=${PUID}
|
||||
- PGID=${PGID}
|
||||
- UMASK=${UMASK}
|
||||
- USER_PASSWORD=${USER_PASSWORD}
|
||||
# Mode
|
||||
- MODE=${MODE}
|
||||
# Web UI
|
||||
- WEB_UI_MODE=${WEB_UI_MODE}
|
||||
- ENABLE_VNC_AUDIO=${ENABLE_VNC_AUDIO}
|
||||
- PORT_NOVNC_WEB=${PORT_NOVNC_WEB}
|
||||
- NEKO_NAT1TO1=${NEKO_NAT1TO1}
|
||||
# Steam
|
||||
- ENABLE_STEAM=${ENABLE_STEAM}
|
||||
- STEAM_ARGS=${STEAM_ARGS}
|
||||
# Sunshine
|
||||
- ENABLE_SUNSHINE=${ENABLE_SUNSHINE}
|
||||
- SUNSHINE_USER=${SUNSHINE_USER}
|
||||
- SUNSHINE_PASS=${SUNSHINE_PASS}
|
||||
# Xorg
|
||||
- ENABLE_EVDEV_INPUTS=${ENABLE_EVDEV_INPUTS}
|
||||
- FORCE_X11_DUMMY_CONFIG=${FORCE_X11_DUMMY_CONFIG}
|
||||
# Nvidia specific config
|
||||
- NVIDIA_DRIVER_CAPABILITIES=${NVIDIA_DRIVER_CAPABILITIES}
|
||||
- NVIDIA_VISIBLE_DEVICES=${NVIDIA_VISIBLE_DEVICES}
|
||||
- NVIDIA_DRIVER_VERSION=${NVIDIA_DRIVER_VERSION}
|
||||
|
||||
# DEVICES:
|
||||
devices:
|
||||
# Use the host fuse device [REQUIRED].
|
||||
- /dev/fuse
|
||||
# Add the host uinput device [REQUIRED].
|
||||
- /dev/uinput
|
||||
# Add NVIDIA HW accelerated devices [OPTIONAL].
|
||||
# NOTE: If you use the nvidia container toolkit, this is not needed.
|
||||
# Installing the nvidia container toolkit is the recommended method for running this container
|
||||
#- /dev/nvidia0
|
||||
#- /dev/nvidiactl
|
||||
#- /dev/nvidia-modeset
|
||||
#- /dev/nvidia-uvm
|
||||
#- /dev/nvidia-uvm-tools
|
||||
#- /dev/nvidia-caps/nvidia-cap1
|
||||
#- /dev/nvidia-caps/nvidia-cap2
|
||||
# Ensure container access to devices 13:*
|
||||
device_cgroup_rules:
|
||||
- 'c 13:* rmw'
|
||||
|
||||
# VOLUMES:
|
||||
volumes:
|
||||
# The location of your home directory.
|
||||
- ${HOME_DIR}/:/home/default/:rw
|
||||
|
||||
# The location where all games should be installed.
|
||||
# This path needs to be set as a library path in Steam after logging in.
|
||||
# Otherwise, Steam will store games in the home directory above.
|
||||
- ${GAMES_DIR}/:/mnt/games/:rw
|
||||
|
||||
# The Xorg socket.
|
||||
- ${SHARED_SOCKETS_DIR}/.X11-unix/:/tmp/.X11-unix/:rw
|
||||
|
||||
# Pulse audio socket.
|
||||
- ${SHARED_SOCKETS_DIR}/pulse/:/tmp/pulse/:rw
|
||||
@@ -9,7 +9,7 @@ Follow these instructions to configure a docker-compose.yml for your system.
|
||||
> Depending on how you have installed this, the commands to execute docker compose may vary.
|
||||
|
||||
|
||||
## PREPARE DIRECTORY:
|
||||
## PREPARE DIRECTORIES:
|
||||
|
||||
> __Warning__
|
||||
>
|
||||
@@ -18,24 +18,78 @@ Follow these instructions to configure a docker-compose.yml for your system.
|
||||
> If you do run these commands as root, you may need to manually fix the permissions and ownership after.
|
||||
|
||||
Create a directory for your service:
|
||||
```
|
||||
```shell
|
||||
sudo mkdir -p /opt/container-services/steam-headless
|
||||
sudo chown -R $(id -u):$(id -g) /opt/container-services/steam-headless
|
||||
```
|
||||
|
||||
Create a directory for your service config data:
|
||||
```
|
||||
```shell
|
||||
sudo mkdir -p /opt/container-data/steam-headless/{home,.X11-unix,pulse}
|
||||
sudo chown -R $(id -u):$(id -g) /opt/container-data/steam-headless
|
||||
```
|
||||
|
||||
(Optional) Create a directory for your game install location:
|
||||
```shell
|
||||
sudo mkdir /mnt/games
|
||||
sudo chmod -R 777 /mnt/games
|
||||
sudo chown -R $(id -u):$(id -g) /mnt/games
|
||||
```
|
||||
|
||||
Create a Steam Headless `/opt/container-services/steam-headless/docker-compose.yml` file.
|
||||
|
||||
Populate this file with the contents of the default [Docker Compose File](./compose-files/docker-compose.default.yml).
|
||||
Populate this file with the contents of the default Docker Compose File
|
||||
|
||||
### AMD/Intel:
|
||||
- [AMD and Intel GPUs](./compose-files/docker-compose.amd+intel.yml).
|
||||
- [Privileged AMD and Intel GPUs Docker Compose Template](./compose-files/docker-compose.amd+intel.privileged.yml) (grants full access to host devices).
|
||||
|
||||
#### Multipl AMD or Intel GPUs
|
||||
|
||||
If you have multiple AMD or Intel GPUs and you wish to isolate them, then follow these steps to determine the card to passthrough in the docker compose file. This requires that you do not use the privileged compose template.
|
||||
1) List the PCI devices and get their IDs `lspci | grep -E 'VGA|3D'`
|
||||
```
|
||||
00:02.0 VGA compatible controller: Intel Corporation TigerLake-LP GT2 [Iris Xe Graphics] (rev 01)
|
||||
06:00.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] Cezanne [Radeon Vega Series / Radeon Vega Mobile Series] (rev c6)
|
||||
```
|
||||
In this example, the Intel GPU has an ID of `00:02.0` and the AMD GPU has an ID of `06:00.0`.
|
||||
|
||||
2) Discover which `/dev/dri/card*` and `/dev/dri/renderD12*` references the `00:02.0` Intel GPU (or whatever your output was). To do this, run the commands `ls -la /sys/class/drm/card*` and `ls -l /sys/class/drm/renderD*`.
|
||||
```
|
||||
lrwxrwxrwx. 1 root root 0 May 8 15:44 /sys/class/drm/card1 -> ../../devices/pci0000:00/0000:00:02.0/drm/card1
|
||||
lrwxrwxrwx. 1 root root 0 May 8 15:44 /sys/class/drm/card1-DP-1 -> ../../devices/pci0000:00/0000:00:02.0/drm/card1/card1-DP-1
|
||||
lrwxrwxrwx. 1 root root 0 May 8 15:44 /sys/class/drm/card1-DP-2 -> ../../devices/pci0000:00/0000:00:02.0/drm/card1/card1-DP-2
|
||||
lrwxrwxrwx. 1 root root 0 May 8 15:44 /sys/class/drm/card1-DP-3 -> ../../devices/pci0000:00/0000:00:02.0/drm/card1/card1-DP-3
|
||||
lrwxrwxrwx. 1 root root 0 May 8 15:44 /sys/class/drm/card1-DP-4 -> ../../devices/pci0000:00/0000:00:02.0/drm/card1/card1-DP-4
|
||||
```
|
||||
```
|
||||
lrwxrwxrwx. 1 root root 0 May 8 15:44 /sys/class/drm/renderD128 -> ../../devices/pci0000:00/0000:00:02.0/drm/renderD128
|
||||
lrwxrwxrwx. 1 root root 0 May 8 15:44 /sys/class/drm/renderD129 -> ../../devices/pci0000:00/0000:06:00.0/drm/renderD129
|
||||
```
|
||||
|
||||
From this example output we can see that the Intel GPU is `/dev/dri/card1` and `/dev/dri/renderD128`.
|
||||
|
||||
### NVIDIA:
|
||||
- [NVIDIA GPUs Docker Compose Template](./compose-files/docker-compose.nvidia.yml).
|
||||
- [Privileged NVIDIA GPUs Docker Compose Template](./compose-files/docker-compose.nvidia.yml) (grants full access to host devices).
|
||||
|
||||
## CONFIGURE ENV:
|
||||
|
||||
Create a Steam Headless `/opt/container-services/steam-headless/.env` file with the contents found in this example [Environment File](./compose-files/.env).
|
||||
|
||||
Edit these variables as required.
|
||||
|
||||
## EXECUTE:
|
||||
|
||||
Navigate to your compose location and execute it.
|
||||
```shell
|
||||
cd /opt/container-services/steam-headless
|
||||
sudo docker-compose up -d --force-recreate
|
||||
```
|
||||
|
||||
After container executes successfully, navigate to your docker host URL in your browser on port 8083 and click connect.
|
||||
`http://<host-ip>:8083/`
|
||||

|
||||
|
||||
## Troubleshooting
|
||||
[Troubleshooting Docs](./troubleshooting.md)
|
||||
|
||||
BIN
docs/images/disk_write_error.png
Normal file
BIN
docs/images/disk_write_error.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 30 KiB |
BIN
docs/images/web_connect.png
Normal file
BIN
docs/images/web_connect.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.2 MiB |
25
docs/k8s-files/pvc.yaml
Normal file
25
docs/k8s-files/pvc.yaml
Normal file
@@ -0,0 +1,25 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: games
|
||||
spec:
|
||||
storageClassName: ssd #Adjust your storageclass as needed
|
||||
volumeMode: Filesystem
|
||||
resources:
|
||||
requests:
|
||||
storage: 400Gi
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: home
|
||||
spec:
|
||||
volumeMode: Filesystem
|
||||
storageClassName: nvme-replicated #Adjust your storageclass as needed
|
||||
resources:
|
||||
requests:
|
||||
storage: 50Gi
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
96
docs/k8s-files/statefulset.yaml
Normal file
96
docs/k8s-files/statefulset.yaml
Normal file
@@ -0,0 +1,96 @@
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
name: steam-headless
|
||||
spec:
|
||||
serviceName: "steam-headless"
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: steam-headless
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: steam-headless
|
||||
spec:
|
||||
hostNetwork: true
|
||||
securityContext:
|
||||
fsGroup: 1000
|
||||
containers:
|
||||
- name: steam-headless
|
||||
securityContext:
|
||||
privileged: true
|
||||
image: josh5/steam-headless:latest
|
||||
resources: #Change CPU and Memory below
|
||||
requests:
|
||||
memory: "24G"
|
||||
cpu: "6"
|
||||
limits:
|
||||
memory: "24G"
|
||||
cpu: "6"
|
||||
nvidia.com/gpu: 1 #If you're using a nvidia GPU, add it here
|
||||
volumeMounts:
|
||||
- name: home-dir
|
||||
mountPath: /home/default/
|
||||
- name: games-dir
|
||||
mountPath: /mnt/games/
|
||||
- name: input-devices
|
||||
mountPath: /dev/input/
|
||||
- name: dshm
|
||||
mountPath: /dev/shm
|
||||
env: #Environmental Vars
|
||||
- name: NAME
|
||||
value: 'SteamHeadless'
|
||||
- name: TZ
|
||||
value: 'America/New_York'
|
||||
- name: USER_LOCALES
|
||||
value: 'en_US.UTF-8 UTF-8'
|
||||
- name: DISPLAY
|
||||
value: ':55'
|
||||
- name: SHM_SIZE
|
||||
value: '2G'
|
||||
- name: DOCKER_RUNTIME
|
||||
value: 'nvidia'
|
||||
- name: PUID
|
||||
value: '1000'
|
||||
- name: PGID
|
||||
value: '1000'
|
||||
- name: UMASK
|
||||
value: '000'
|
||||
- name: USER_PASSWORD
|
||||
value: 'password' #changeme
|
||||
- name: MODE
|
||||
value: 'primary'
|
||||
- name: WEB_UI_MODE
|
||||
value: 'none'
|
||||
- name: ENABLE_VNC_AUDIO
|
||||
value: 'false'
|
||||
- name: PORT_NOVNC_WEB
|
||||
value: '8083'
|
||||
- name: NEKO_NAT1TO1
|
||||
value: ''
|
||||
- name: ENABLE_SUNSHINE
|
||||
value: 'true'
|
||||
- name: SUNSHINE_USER
|
||||
value: 'sam'
|
||||
- name: SUNSHINE_PASS
|
||||
value: 'password'
|
||||
- name: ENABLE_EVDEV_INPUTS
|
||||
value: 'true'
|
||||
- name: NVIDIA_DRIVER_CAPABILITIES
|
||||
value: 'all'
|
||||
- name: NVIDIA_VISIBLE_DEVICES
|
||||
value: 'all'
|
||||
volumes:
|
||||
- name: home-dir
|
||||
persistentVolumeClaim:
|
||||
claimName: home
|
||||
- name: games-dir
|
||||
persistentVolumeClaim:
|
||||
claimName: games
|
||||
- name: input-devices
|
||||
hostPath:
|
||||
path: /dev/input/
|
||||
- name: dshm
|
||||
emptyDir:
|
||||
medium: Memory
|
||||
16
docs/k8s.md
Normal file
16
docs/k8s.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# Kubernetes
|
||||
|
||||
Have a cluster at home and want to add steam headless to it?
|
||||
|
||||
Requirements
|
||||
- NVIDIA Device plugin (if using nvidia GPU) https://github.com/NVIDIA/k8s-device-plugin
|
||||
- A storageclass
|
||||
|
||||
Tasks
|
||||
1. Configure the statefulset to your liking. Things to note:
|
||||
- CPU & Memory
|
||||
- Env vars (see compose-files/.env for documentation)
|
||||
2. Change the PVC to your liking. Things to note:
|
||||
- Storage Class
|
||||
- Size
|
||||
3. Deploy it: `kubectl create -f k8s-files/*`
|
||||
30
docs/troubleshooting.md
Normal file
30
docs/troubleshooting.md
Normal file
@@ -0,0 +1,30 @@
|
||||
## Flatpaks not working
|
||||
|
||||
Steam runs with Flatpak. These Flatpaks are instlled into the `default` user's home directory so they persist between container updates. Sometimes Flatpaks can get into a knot between major Steam Headless updates. In such cases, it may not work correctly. To fix this, just delete the Flatpak runtime in your `default` user's home directory a restart the container.
|
||||
|
||||
1) Stop the container.
|
||||
2) Delete the directory `<SteamHeadless Home>/.local/share/flatpak`
|
||||
3) Re-create the container. Don't just restart it. This will trigger an update of the required Flatpak runtimes in the home directory.
|
||||
4) Reinstall any missing Flatpaks from the Software app.
|
||||
|
||||
Once your Flatpak refresh is complete, everything should work correctly and your configuration for each application should have remained intact.
|
||||
|
||||
## An error occurred while installing <game>: "disk write error"
|
||||
|
||||

|
||||
|
||||
1) Stop the container
|
||||
2) Verify your mounted /mnt/games volume is owned by the executing UID/GID, and 777 permissions are set.
|
||||
3) Verify the `steamapps` directory exists within the library location.
|
||||
|
||||
> __Note__
|
||||
>
|
||||
> The directory in the below commands are the default /mnt/games library locations installed upon first execution of this container.
|
||||
>
|
||||
> Depending on how you have installed this, the directory path may vary.
|
||||
|
||||
```shell
|
||||
sudo mkdir /mnt/games/GameLibrary/SteamLibrary/steamapps
|
||||
sudo chmod -R 777 /mnt/games
|
||||
sudo chown -R $(id -u):$(id -g) /mnt/games
|
||||
```
|
||||
@@ -1,22 +1,57 @@
|
||||
# Ubuntu Server
|
||||
# Ubuntu Server Setup
|
||||
|
||||
Follow these instructions to install Steam Headless on Ubuntu Server.
|
||||
Use these instructions to install **Steam Headless** on an Ubuntu Server system.
|
||||
|
||||
> __Note__
|
||||
> ⚠️ **Note**
|
||||
>
|
||||
> This assumes that your Ubuntu Server has not be configured to run any desktop environment!
|
||||
>
|
||||
> This will not work with Ubuntu Desktop.
|
||||
> These steps assume you are running a minimal **Ubuntu Server** installation **without any desktop environment**.
|
||||
> This setup **will not work** on Ubuntu Desktop.
|
||||
|
||||
---
|
||||
|
||||
## INSTALL NVIDIA DRIVER:
|
||||
|
||||
Although you're on a server system, using the `-server` variant of the NVIDIA driver can cause compatibility issues.
|
||||
Instead, install the standard driver **without recommended extras**:
|
||||
|
||||
```bash
|
||||
apt install --no-install-recommends nvidia-driver-570
|
||||
```
|
||||
|
||||
> 🔍 Feel free to `570` with the latest available version.
|
||||
|
||||
To find the latest version of the standard (non-`-server`, non-`-open`) drivers, run:
|
||||
|
||||
```bash
|
||||
apt-cache search ^nvidia-driver- | awk '{print $1}' | grep -vE '(-server|-open)' | xargs -n1 apt-cache policy | awk '/^nvidia-driver-/{driver=$1} /Candidate:/ {print driver, $2}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## INSTALL DOCKER:
|
||||
|
||||
Install docker-ce to your Ubuntu server following the [official instrctions](https://docs.docker.com/engine/install/ubuntu/).
|
||||
Install `docker-ce` on your Ubuntu server by following the [official Docker instructions](https://docs.docker.com/engine/install/ubuntu/).
|
||||
|
||||
Ensure you install the `docker-compose-plugin` mentioned within these instructions
|
||||
Make sure you also install the `docker-compose-plugin` as noted in the Docker documentation.
|
||||
|
||||
---
|
||||
|
||||
## INSTALL NVIDIA CONTAINER TOOLKIT
|
||||
|
||||
To enable GPU support inside Docker containers, install the [NVIDIA Container Toolkit](https://github.com/NVIDIA/nvidia-container-toolkit?tab=readme-ov-file).
|
||||
|
||||
Follow the [APT-based installation steps](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html#installing-with-apt) provided in the official documentation.
|
||||
|
||||
Once installed, configure Docker to use the NVIDIA runtime by default:
|
||||
|
||||
```bash
|
||||
sudo nvidia-ctk runtime configure --runtime=docker
|
||||
```
|
||||
|
||||
> 💡 You *can* also run the container without the NVIDIA runtime by manually uncommenting the `/dev/nvidia*` device entries in the Compose file — but this approach is **not recommended**.
|
||||
|
||||
---
|
||||
|
||||
## CONFIGURE DOCKER COMPOSE:
|
||||
|
||||
Once you have installed docker, follow the [Compose Files](./docker-compose.md) section and select the right configuration file for your hardware.
|
||||
|
||||
After installing Docker, proceed to the [Compose Files](./docker-compose.md) section and select the appropriate configuration for your hardware setup.
|
||||
|
||||
@@ -22,44 +22,71 @@ if [[ -f /version.txt ]]; then
|
||||
cat /version.txt
|
||||
fi
|
||||
|
||||
function print_header {
|
||||
# Magenta
|
||||
echo -e "\e[35m**** ${@} ****\e[0m"
|
||||
}
|
||||
|
||||
function print_step_header {
|
||||
# Cyan
|
||||
echo -e "\e[36m - ${@}\e[0m"
|
||||
}
|
||||
|
||||
function print_warning {
|
||||
# Yellow
|
||||
echo -e "\e[33mWARNING: ${@}\e[0m"
|
||||
}
|
||||
|
||||
function print_error {
|
||||
# Red
|
||||
echo -e "\e[31mERROR: ${@}\e[0m"
|
||||
}
|
||||
|
||||
function print_note {
|
||||
# Cyan
|
||||
echo -e "\e[36mNOTE: ${@}\e[0m"
|
||||
}
|
||||
|
||||
# Execute all container init scripts
|
||||
for init_script in /etc/cont-init.d/*.sh ; do
|
||||
echo
|
||||
echo "[ ${init_script}: executing... ]"
|
||||
sed -i 's/\r$//' "${init_script}"
|
||||
source "${init_script}"
|
||||
echo -e "\e[34m[ ${init_script:?}: executing... ]\e[0m"
|
||||
sed -i 's/\r$//' "${init_script:?}"
|
||||
source "${init_script:?}"
|
||||
done
|
||||
touch /tmp/.first-run-init-scripts
|
||||
|
||||
# Execute any user generated init scripts
|
||||
mkdir -p ${USER_HOME}/init.d
|
||||
chown -R ${USER} ${USER_HOME}/init.d
|
||||
for user_init_script in ${USER_HOME}/init.d/*.sh ; do
|
||||
mkdir -p ${USER_HOME:?}/init.d
|
||||
chown -R ${USER:?} ${USER_HOME:?}/init.d
|
||||
for user_init_script in ${USER_HOME:?}/init.d/*.sh ; do
|
||||
|
||||
# Check that a file was found
|
||||
# (If no files exist in this directory, then user_init_script will be empty)
|
||||
if [[ -e "${user_init_script}" ]]; then
|
||||
if [[ -e "${user_init_script:?}" ]]; then
|
||||
|
||||
echo
|
||||
echo "[ USER:${user_init_script}: executing... ]"
|
||||
sed -i 's/\r$//' "${user_init_script}"
|
||||
echo -e "\e[34m[ USER:${user_init_script:?}: executing... ]\e[0m"
|
||||
sed -i 's/\r$//' "$(readlink -e "${user_init_script:?}")"
|
||||
|
||||
# Execute user script in sub process.
|
||||
# This way if it is messed up, we dont get caught in an init loop
|
||||
chmod +x "${user_init_script}"
|
||||
cat "${user_init_script}" | bash
|
||||
# Execute user script in sub process with 'set +e'.
|
||||
# This way if it is messed up, we dont get caught in an init loop.
|
||||
chmod +x "${user_init_script:?}"
|
||||
(
|
||||
set +e
|
||||
"${user_init_script:?}" || echo -e "\e[31mERROR: \e[33mFailed to execute user script '${user_init_script:?}'\e[0m"
|
||||
)
|
||||
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
# Ensure all scripts are executable
|
||||
chmod a+rwx /opt/scripts/*.sh
|
||||
touch /tmp/.first-run-user-init-scripts
|
||||
|
||||
# Start supervisord
|
||||
echo
|
||||
echo "**** Starting supervisord ****";
|
||||
echo "Logging all root services to '/var/log/supervisor/'"
|
||||
echo "Logging all user services to '/home/${USER}/.cache/log/'"
|
||||
print_header "Starting supervisord";
|
||||
print_step_header "Logging all root services to '/var/log/supervisor/'"
|
||||
print_step_header "Logging all user services to '/home/${USER:?}/.cache/log/'"
|
||||
echo
|
||||
mkdir -p /var/log/supervisor
|
||||
chmod a+rw /var/log/supervisor
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
# File Created: Friday, 12th January 2022 8:54:01 am
|
||||
# Author: Josh.5 (jsunnex@gmail.com)
|
||||
# -----
|
||||
# Last Modified: Tuesday, 4th October 2022 11:27:10 am
|
||||
# Modified By: Josh.5 (jsunnex@gmail.com)
|
||||
# Last Modified: Monday, 10th July 2023 5:56:17 pm
|
||||
# Modified By: Console and webGui login account (jsunnex@gmail.com)
|
||||
###
|
||||
|
||||
PUID=${PUID:-99}
|
||||
@@ -14,18 +14,21 @@ PGID=${PGID:-100}
|
||||
UMASK=${UMASK:-000}
|
||||
USER_PASSWORD=${USER_PASSWORD:-password}
|
||||
|
||||
echo "**** Configure default user ****"
|
||||
print_header "Configure default user"
|
||||
|
||||
echo "Setting default user uid=${PUID}(${USER}) gid=${PGID}(${USER})"
|
||||
print_step_header "Setting default user uid=${PUID}(${USER}) gid=${PGID}(${USER})"
|
||||
usermod -o -u "${PUID}" ${USER}
|
||||
groupmod -o -g "${PGID}" ${USER}
|
||||
|
||||
|
||||
echo "Adding default user to video, audio, input and pulse groups"
|
||||
usermod -a -G video,audio,input,pulse ${USER}
|
||||
|
||||
|
||||
echo "Adding default user to any additional required device groups"
|
||||
print_step_header "Adding default user to any additional required device groups"
|
||||
additional_groups=( video audio input pulse )
|
||||
for group_name in "${additional_groups[@]}"; do
|
||||
if [ $(getent group ${group_name:?}) ]; then
|
||||
print_step_header "Adding user '${USER}' to group: '${group_name}'"
|
||||
usermod -aG ${group_name:?} ${USER}
|
||||
fi
|
||||
done
|
||||
device_nodes=( /dev/uinput /dev/input/event* /dev/dri/* )
|
||||
added_groups=""
|
||||
for dev in "${device_nodes[@]}"; do
|
||||
@@ -51,20 +54,20 @@ for dev in "${device_nodes[@]}"; do
|
||||
|
||||
# Add group to user
|
||||
if [[ "${added_groups}" != *"${dev_group}"* ]]; then
|
||||
echo "Adding user '${USER}' to group: '${dev_group}' for device: ${dev}"
|
||||
usermod -a -G ${dev_group} ${USER}
|
||||
print_step_header "Adding user '${USER}' to group: '${dev_group}' for device: ${dev}"
|
||||
usermod -aG ${dev_group} ${USER}
|
||||
added_groups=" ${added_groups} ${dev_group} "
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
echo "Setting umask to ${UMASK}";
|
||||
print_step_header "Setting umask to ${UMASK}";
|
||||
umask ${UMASK}
|
||||
|
||||
|
||||
# TODO: Move this to its own 'display' init script. It does not really belong here
|
||||
# Configure the 'XDG_RUNTIME_DIR' path
|
||||
echo "Create the user XDG_RUNTIME_DIR path '${XDG_RUNTIME_DIR}'"
|
||||
print_step_header "Create the user XDG_RUNTIME_DIR path '${XDG_RUNTIME_DIR}'"
|
||||
mkdir -p ${XDG_RUNTIME_DIR}
|
||||
# Ensure it is owned by the 'default' user
|
||||
chown -R ${PUID}:${PGID} ${XDG_RUNTIME_DIR}
|
||||
@@ -76,27 +79,20 @@ ln -sf /usr/share/backgrounds/steam.jpg /etc/alternatives/desktop-background
|
||||
chmod a+r /etc/alternatives/desktop-background
|
||||
|
||||
|
||||
# Setup home directory and permissions
|
||||
echo "Adding default home directory template"
|
||||
mkdir -p ${USER_HOME}
|
||||
chown -R ${PUID}:${PGID} /etc/home_directory_template
|
||||
rsync -aq --ignore-existing /etc/home_directory_template/ ${USER_HOME}/
|
||||
|
||||
|
||||
# Setup services log path
|
||||
echo "Setting ownership of all log files in '${USER_HOME}/.cache/log'"
|
||||
print_step_header "Setting ownership of all log files in '${USER_HOME}/.cache/log'"
|
||||
mkdir -p "${USER_HOME}/.cache/log"
|
||||
chown -R ${PUID}:${PGID} "${USER_HOME}/.cache/log"
|
||||
|
||||
|
||||
# Set the root and user password
|
||||
echo "Setting root password"
|
||||
print_step_header "Setting root password"
|
||||
echo "root:${USER_PASSWORD}" | chpasswd
|
||||
echo "Setting user password"
|
||||
print_step_header "Setting user password"
|
||||
echo "${USER}:${USER_PASSWORD}" | chpasswd
|
||||
|
||||
# Set root XDG_RUNTIME_DIR path
|
||||
mkdir -p /tmp/runtime-root
|
||||
chown root:root /tmp/runtime-root
|
||||
|
||||
echo "DONE"
|
||||
echo -e "\e[34mDONE\e[0m"
|
||||
17
overlay/etc/cont-init.d/11-setup_sysctl_values.sh
Normal file
17
overlay/etc/cont-init.d/11-setup_sysctl_values.sh
Normal file
@@ -0,0 +1,17 @@
|
||||
|
||||
# Configure kernel parameters
|
||||
print_header "Configure some system kernel parameters"
|
||||
|
||||
|
||||
if [ "$(cat /proc/sys/vm/max_map_count)" -ge 524288 ]; then
|
||||
if [ -w "/proc/sys/vm/max_map_count" ]; then
|
||||
print_step_header "Setting the maximum number of memory map areas a process can create to 524288"
|
||||
echo 524288 > /proc/sys/vm/max_map_count
|
||||
else
|
||||
print_warning "Unable to set vm.max_map_count on unprivileged container"
|
||||
fi
|
||||
else
|
||||
print_step_header "The vm.max_map_count is already greater than '524288'"
|
||||
fi
|
||||
|
||||
echo -e "\e[34mDONE\e[0m"
|
||||
@@ -1,21 +0,0 @@
|
||||
|
||||
echo "**** Configure SSH server ****"
|
||||
|
||||
if [[ "X${PORT_SSH:-}" != "X" ]]; then
|
||||
# Generate new SSH host keys if they dont exist
|
||||
if [[ ! -f /etc/ssh/ssh_host_rsa_key ]]; then
|
||||
echo "**** Generating SSH keys ****";
|
||||
/usr/bin/ssh-keygen -A
|
||||
fi
|
||||
mkdir -p /run/sshd
|
||||
chmod 744 /run/sshd
|
||||
|
||||
echo "Set port to '${PORT_SSH}'"
|
||||
sed -i "s|^# Port 22.*$|Port ${PORT_SSH}|" /etc/ssh/ssh_config
|
||||
else
|
||||
echo "Disable SSH server"
|
||||
# Disable supervisord script
|
||||
sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/sshd.ini
|
||||
fi
|
||||
|
||||
echo "DONE"
|
||||
@@ -1,12 +1,14 @@
|
||||
|
||||
# Configure dbus
|
||||
echo "**** Configure container dbus ****";
|
||||
print_header "Configure container dbus"
|
||||
|
||||
if ([ "${MODE}" != "s" ] && [ "${MODE}" != "secondary" ]); then
|
||||
if [[ "${HOST_DBUS}" == "true" ]]; then
|
||||
echo "Container configured to use the host dbus";
|
||||
print_step_header "Container configured to use the host dbus";
|
||||
# Disable supervisord script
|
||||
sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/dbus.ini
|
||||
else
|
||||
echo "Container configured to run its own dbus";
|
||||
print_step_header "Container configured to run its own dbus";
|
||||
# Enable supervisord script
|
||||
sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/dbus.ini
|
||||
# Configure dbus to run as USER
|
||||
@@ -22,5 +24,9 @@ else
|
||||
# Remove old lockfiles
|
||||
find /var/run/dbus -name "pid" -exec rm -f {} \;
|
||||
fi
|
||||
else
|
||||
print_step_header "Dbus service not available when container is run in 'secondary' mode."
|
||||
sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/dbus.ini
|
||||
fi
|
||||
|
||||
echo "DONE"
|
||||
echo -e "\e[34mDONE\e[0m"
|
||||
|
||||
@@ -1,46 +1,51 @@
|
||||
#!/usr/bin/env bash
|
||||
###
|
||||
# File: 30-configure_udev.sh
|
||||
# Project: cont-init.d
|
||||
# File Created: Friday, 12th January 2022 8:54:01 am
|
||||
# Author: Josh.5 (jsunnex@gmail.com)
|
||||
# -----
|
||||
# Last Modified: Tuesday, 4th October 2022 11:20:48 am
|
||||
# Modified By: Josh.5 (jsunnex@gmail.com)
|
||||
###
|
||||
|
||||
# Running udev only works in privileged container
|
||||
# Source: https://github.com/balena-io-playground/balena-base-images/
|
||||
tmp_mount='/tmp/privileged_test'
|
||||
mkdir -p "${tmp_mount}"
|
||||
if mount -t devtmpfs none "${tmp_mount}" &> /dev/null; then
|
||||
is_privileged=true
|
||||
umount "${tmp_mount}"
|
||||
else
|
||||
is_privileged=false
|
||||
fi
|
||||
rm -rf "${tmp_mount}"
|
||||
# Configure dbus
|
||||
print_header "Configure udevd"
|
||||
|
||||
|
||||
if [[ "${is_privileged}" == "true" ]]; then
|
||||
echo "**** Configure container to run udev management ****";
|
||||
# Since this container may also be run with CAP_SYS_ADMIN, ensure we can actually execute "udevadm trigger"
|
||||
run_dumb_udev="false"
|
||||
if [ ! -w /sys ]; then
|
||||
# Disable supervisord script since we are not able to write to sysfs
|
||||
print_step_header "Disable udevd - /sys is mounted RO"
|
||||
sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/udev.ini
|
||||
run_dumb_udev="true"
|
||||
elif [ ! -d /run/udev ]; then
|
||||
# Disable supervisord script since we are not able to write to udev/data path
|
||||
print_step_header "Disable udevd - /run/udev does not exist"
|
||||
sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/udev.ini
|
||||
run_dumb_udev="true"
|
||||
elif [ ! -w /run/udev ]; then
|
||||
# Disable supervisord script since we are not able to write to udev/data path
|
||||
print_step_header "Disable udevd - /run/udev is mounted RO"
|
||||
sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/udev.ini
|
||||
run_dumb_udev="false"
|
||||
elif udevadm trigger &> /dev/null; then
|
||||
print_step_header "Configure container to run udev management"
|
||||
# Enable supervisord script
|
||||
sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/udev.ini
|
||||
# Make startup script executable
|
||||
chmod +x /usr/bin/start-udev.sh
|
||||
# Configure udev permissions
|
||||
if [[ -f /lib/udev/rules.d/60-steam-input.rules ]]; then
|
||||
sed -i 's/MODE="0660"/MODE="0666"/' /lib/udev/rules.d/60-steam-input.rules
|
||||
fi
|
||||
run_dumb_udev="false"
|
||||
else
|
||||
# Disable supervisord script
|
||||
# Disable supervisord script since we are not able to execute "udevadm trigger"
|
||||
print_step_header "Disable udev service due to privilege restrictions"
|
||||
sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/udev.ini
|
||||
run_dumb_udev="true"
|
||||
fi
|
||||
|
||||
if [ "${run_dumb_udev}" = "true" ]; then
|
||||
# Enable dumb-udev instead of udevd
|
||||
print_step_header "Enable dumb-udev service"
|
||||
sed -i 's|^command.*=.*$|command=start-dumb-udev.sh|' /etc/supervisor.d/udev.ini
|
||||
sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/udev.ini
|
||||
fi
|
||||
|
||||
|
||||
if [[ -e /dev/uinput ]]; then
|
||||
echo "**** Ensure the default user has permission to r/w on input devices ****";
|
||||
print_step_header "Ensure the default user has permission to r/w on input devices"
|
||||
chmod 0666 /dev/uinput
|
||||
fi
|
||||
|
||||
echo "DONE"
|
||||
echo -e "\e[34mDONE\e[0m"
|
||||
|
||||
@@ -1,19 +1,22 @@
|
||||
|
||||
# Configure dbus
|
||||
print_header "Configure local"
|
||||
|
||||
current_local=$(head -n 1 /etc/locale.gen)
|
||||
user_local=$(echo ${USER_LOCALES} | cut -d ' ' -f 1)
|
||||
|
||||
if [ "${current_local}" != "${USER_LOCALES}" ]; then
|
||||
echo "**** Configuring Locales to ${USER_LOCALES} ****";
|
||||
print_step_header "Configuring Locales to ${USER_LOCALES}"
|
||||
rm /etc/locale.gen
|
||||
echo -e "${USER_LOCALES}\nen_US.UTF-8 UTF-8" > "/etc/locale.gen"
|
||||
export LANGUAGE="${user_local}"
|
||||
export LANG="${user_local}"
|
||||
export LC_ALL="${user_local}" 2> /dev/null
|
||||
sleep 2
|
||||
sleep 0.5
|
||||
locale-gen
|
||||
update-locale LC_ALL="${user_local}"
|
||||
else
|
||||
echo "**** Locales already set correctly to ${USER_LOCALES} ****";
|
||||
print_step_header "Locales already set correctly to ${USER_LOCALES}"
|
||||
fi
|
||||
|
||||
echo "DONE"
|
||||
echo -e "\e[34mDONE\e[0m"
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
|
||||
echo "**** Configure pulseaudio ****"
|
||||
# Configure dbus
|
||||
print_header "Configure pulseaudio"
|
||||
|
||||
# Always enable the pulseaudio service
|
||||
print_step_header "Enable pulseaudio service."
|
||||
sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/pulseaudio.ini
|
||||
|
||||
if [ "${MODE}" == "s" ] | [ "${MODE}" == "secondary" ]; then
|
||||
echo "Configure pulseaudio as simple dummy audio"
|
||||
print_step_header "Configure pulseaudio as simple dummy audio"
|
||||
sed -i 's|^; autospawn.*$|autospawn = no|' /etc/pulse/client.conf
|
||||
sed -i 's|^; daemon-binary.*$|daemon-binary = /bin/true|' /etc/pulse/client.conf
|
||||
|
||||
sed -i 's|^; flat-volumes.*$|flat-volumes = yes|' /etc/pulse/daemon.conf
|
||||
else
|
||||
echo "Configure pulseaudio to pipe audio to a socket"
|
||||
print_step_header "Configure pulseaudio to pipe audio to a socket"
|
||||
|
||||
# Ensure pulseaudio directories have the correct permissions
|
||||
mkdir -p \
|
||||
@@ -33,4 +38,4 @@ else
|
||||
fi
|
||||
chown -R ${USER} /etc/pulse
|
||||
|
||||
echo "DONE"
|
||||
echo -e "\e[34mDONE\e[0m"
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
|
||||
# Fech NVIDIA GPU device (if one exists)
|
||||
if [ "${NVIDIA_VISIBLE_DEVICES:-}" == "all" ]; then
|
||||
if [ "${NVIDIA_VISIBLE_DEVICES:-}" = "all" ]; then
|
||||
export gpu_select=$(nvidia-smi --format=csv --query-gpu=uuid 2>/dev/null | sed -n 2p)
|
||||
elif [ -z "${NVIDIA_VISIBLE_DEVICES:-}" ]; then
|
||||
elif [ "${NVIDIA_VISIBLE_DEVICES:-}X" = "X" ]; then
|
||||
export gpu_select=$(nvidia-smi --format=csv --query-gpu=uuid 2>/dev/null | sed -n 2p)
|
||||
else
|
||||
export gpu_select=$(nvidia-smi --format=csv --id=$(echo "$NVIDIA_VISIBLE_DEVICES" | cut -d ',' -f1) --query-gpu=uuid | sed -n 2p)
|
||||
if [ -z "$gpu_select" ]; then
|
||||
if [ "${gpu_select:-}X" = "X" ]; then
|
||||
export gpu_select=$(nvidia-smi --format=csv --query-gpu=uuid 2>/dev/null | sed -n 2p)
|
||||
fi
|
||||
fi
|
||||
|
||||
# NVIDIA Params
|
||||
export nvidia_pci_address="$(nvidia-smi --format=csv --query-gpu=pci.bus_id --id="${gpu_select}" 2> /dev/null | sed -n 2p | cut -d ':' -f2,3)"
|
||||
export nvidia_gpu_name=$(nvidia-smi --format=csv --query-gpu=name --id="${gpu_select}" 2> /dev/null | sed -n 2p)
|
||||
if [ "X${gpu_select:-}" != "X" ]; then
|
||||
export nvidia_pci_address="$(nvidia-smi --format=csv --query-gpu=pci.bus_id --id="${gpu_select:?}" 2>/dev/null | sed -n 2p | cut -d ':' -f2,3)"
|
||||
export nvidia_gpu_name=$(nvidia-smi --format=csv --query-gpu=name --id="${gpu_select:?}" 2>/dev/null | sed -n 2p)
|
||||
export nvidia_host_driver_version="$(nvidia-smi 2>/dev/null | grep NVIDIA-SMI | cut -d ' ' -f3)"
|
||||
fi
|
||||
|
||||
# Intel params
|
||||
# This figures out if it's an intel CPU with integrated GPU
|
||||
@@ -27,41 +29,58 @@ export amd_cpu_model="$(lscpu | grep 'Model name:' | grep -i amd | cut -d':' -f2
|
||||
export amd_gpu_model="$(lspci | grep -i vga | grep -i amd)"
|
||||
|
||||
function download_driver {
|
||||
mkdir -p ${USER_HOME}/Downloads
|
||||
chown -R ${USER} ${USER_HOME}/Downloads
|
||||
local driver_url
|
||||
local stripped_version
|
||||
|
||||
if [[ ! -f "${USER_HOME}/Downloads/NVIDIA_${nvidia_host_driver_version}.run" ]]; then
|
||||
echo "Downloading driver v${nvidia_host_driver_version}"
|
||||
wget -q --show-progress --progress=bar:force:noscroll \
|
||||
mkdir -p "${USER_HOME:?}/Downloads"
|
||||
chown -R ${USER:?} "${USER_HOME:?}/Downloads"
|
||||
|
||||
if [[ ! -f "${USER_HOME:?}/Downloads/NVIDIA_${nvidia_host_driver_version:?}.run" ]]; then
|
||||
print_step_header "Downloading driver v${nvidia_host_driver_version:?}"
|
||||
|
||||
# Try downloading from a list of NVIDIA driver hosting servers
|
||||
stripped_version="${nvidia_host_driver_version#v}" # Strip 'v' if present
|
||||
declare -a sources=(
|
||||
"https://download.nvidia.com/XFree86/Linux-x86_64/${nvidia_host_driver_version}/NVIDIA-Linux-x86_64-${nvidia_host_driver_version}.run"
|
||||
"https://us.download.nvidia.com/XFree86/Linux-x86_64/${nvidia_host_driver_version}/NVIDIA-Linux-x86_64-${nvidia_host_driver_version}.run"
|
||||
"https://github.com/flathub/org.freedesktop.Platform.GL.nvidia/releases/download/cuda/NVIDIA-Linux-x86_64-${stripped_version}.run"
|
||||
)
|
||||
|
||||
for driver_url in "${sources[@]}"; do
|
||||
if wget -q --show-progress --progress=bar:force:noscroll \
|
||||
-O /tmp/NVIDIA.run \
|
||||
http://download.nvidia.com/XFree86/Linux-x86_64/${nvidia_host_driver_version}/NVIDIA-Linux-x86_64-${nvidia_host_driver_version}.run
|
||||
[[ $? -gt 0 ]] && echo "Error downloading driver. Exit!" && return 1
|
||||
"${driver_url:?}"; then
|
||||
mv /tmp/NVIDIA.run "${USER_HOME:?}/Downloads/NVIDIA_${nvidia_host_driver_version:?}.run"
|
||||
return 0
|
||||
mv /tmp/NVIDIA.run "${USER_HOME:?}/Downloads/NVIDIA_${nvidia_host_driver_version:?}.run"
|
||||
return 0
|
||||
else
|
||||
print_warning "Download failed from: ${driver_url}"
|
||||
fi
|
||||
done
|
||||
|
||||
mv /tmp/NVIDIA.run ${USER_HOME}/Downloads/NVIDIA_${nvidia_host_driver_version}.run
|
||||
print_note "Visit https://download.nvidia.com/XFree86/Linux-x86_64/ in a browser and find the closest match to version '${nvidia_host_driver_version:?}', then set that version in the NVIDIA_DRIVER_VERSION environment variable."
|
||||
print_error "Unable to download driver from any source. Exit!"
|
||||
sleep 10
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
function install_nvidia_driver {
|
||||
# Check here if the currently installed version matches using nvidia-settings
|
||||
nvidia_settings_version=$(nvidia-settings --version 2>/dev/null | grep version | cut -d ' ' -f 4)
|
||||
[[ "${nvidia_settings_version}x" == "${nvidia_host_driver_version}x" ]] && return 0;
|
||||
|
||||
if [ "${nvidia_settings_version:-}X" != "${nvidia_host_driver_version:-}X" ]; then
|
||||
# Download the driver (if it does not yet exist locally)
|
||||
download_driver
|
||||
|
||||
# if command -v pacman &> /dev/null; then
|
||||
# echo "Install NVIDIA vulkan utils" \
|
||||
# && pacman -Syu --noconfirm --needed \
|
||||
# lib32-nvidia-utils \
|
||||
# lib32-vulkan-icd-loader
|
||||
# nvidia-utils \
|
||||
# vulkan-icd-loader \
|
||||
# && echo
|
||||
# fi
|
||||
if (($(echo $nvidia_host_driver_version | cut -d '.' -f 1) >= 550)); then
|
||||
sed -i 's/--no-multigpu//g' /etc/cont-init.d/70-configure_xorg.sh
|
||||
fi
|
||||
|
||||
echo "Installing NVIDIA driver v${nvidia_host_driver_version} to match what is running on the host"
|
||||
chmod +x ${USER_HOME}/Downloads/NVIDIA_${nvidia_host_driver_version}.run
|
||||
${USER_HOME}/Downloads/NVIDIA_${nvidia_host_driver_version}.run \
|
||||
if (($(echo $nvidia_host_driver_version | cut -d '.' -f 1) > 500)); then
|
||||
print_step_header "Installing NVIDIA driver v${nvidia_host_driver_version:?} to match what is running on the host"
|
||||
chmod +x "${USER_HOME:?}/Downloads/NVIDIA_${nvidia_host_driver_version:?}.run"
|
||||
"${USER_HOME:?}/Downloads/NVIDIA_${nvidia_host_driver_version:?}.run" \
|
||||
--silent \
|
||||
--accept-license \
|
||||
--skip-depmod \
|
||||
@@ -78,72 +97,163 @@ function install_nvidia_driver {
|
||||
--no-check-for-alternate-installs \
|
||||
--no-libglx-indirect \
|
||||
--no-install-libglvnd \
|
||||
> ${USER_HOME}/Downloads/nvidia_gpu_install.log 2>&1
|
||||
>"${USER_HOME:?}/Downloads/nvidia_gpu_install.log" 2>&1
|
||||
else
|
||||
print_step_header "Installing Legacy NVIDIA driver v${nvidia_host_driver_version:?} to match what is running on the host"
|
||||
chmod +x "${USER_HOME:?}/Downloads/NVIDIA_${nvidia_host_driver_version:?}.run"
|
||||
"${USER_HOME:?}/Downloads/NVIDIA_${nvidia_host_driver_version:?}.run" \
|
||||
--silent \
|
||||
--accept-license \
|
||||
--skip-depmod \
|
||||
--skip-module-unload \
|
||||
--no-kernel-module \
|
||||
--no-kernel-module-source \
|
||||
--install-compat32-libs \
|
||||
--no-nouveau-check \
|
||||
--no-nvidia-modprobe \
|
||||
--no-systemd \
|
||||
--no-distro-scripts \
|
||||
--no-rpms \
|
||||
--no-backup \
|
||||
--no-check-for-alternate-installs \
|
||||
--no-libglx-indirect \
|
||||
--no-install-libglvnd \
|
||||
>"${USER_HOME:?}/Downloads/nvidia_gpu_install.log" 2>&1
|
||||
fi
|
||||
else
|
||||
print_step_header "NVIDIA driver version ${nvidia_settings_version:-} is already installed"
|
||||
fi
|
||||
}
|
||||
|
||||
function patch_nvidia_driver {
|
||||
# REF: https://github.com/keylase/nvidia-patch#docker-support
|
||||
if [ "${NVIDIA_PATCH_VERSION:-}X" != "X" ]; then
|
||||
# Don't fail boot if something goes wrong here. Set +e
|
||||
(
|
||||
set +e
|
||||
if [ ! -f "${USER_HOME:?}/Downloads/nvidia-patch.${NVIDIA_PATCH_VERSION:?}.sh" ]; then
|
||||
print_step_header "Fetch NVIDIA NVENC patch"
|
||||
wget -q --show-progress --progress=bar:force:noscroll \
|
||||
-O "${USER_HOME:?}/Downloads/nvidia-patch.${NVIDIA_PATCH_VERSION:?}.sh" \
|
||||
"https://raw.githubusercontent.com/keylase/nvidia-patch/${NVIDIA_PATCH_VERSION:?}/patch.sh"
|
||||
fi
|
||||
if [ ! -f "${USER_HOME:?}/Downloads/nvidia-patch-fbc.${NVIDIA_PATCH_VERSION:?}.sh" ]; then
|
||||
print_step_header "Fetch NVIDIA NvFBC patch"
|
||||
wget -q --show-progress --progress=bar:force:noscroll \
|
||||
-O "${USER_HOME:?}/Downloads/nvidia-patch-fbc.${NVIDIA_PATCH_VERSION:?}.sh" \
|
||||
"https://raw.githubusercontent.com/keylase/nvidia-patch/${NVIDIA_PATCH_VERSION:?}/patch-fbc.sh"
|
||||
fi
|
||||
chmod +x \
|
||||
"${USER_HOME:?}/Downloads/nvidia-patch.${NVIDIA_PATCH_VERSION:?}.sh" \
|
||||
"${USER_HOME:?}/Downloads/nvidia-patch-fbc.${NVIDIA_PATCH_VERSION:?}.sh"
|
||||
|
||||
print_step_header "Install NVIDIA driver patches"
|
||||
echo "/patched-lib" >/etc/ld.so.conf.d/000-patched-lib.conf
|
||||
mkdir -p "/patched-lib"
|
||||
PATCH_OUTPUT_DIR="/patched-lib" "${USER_HOME:?}/Downloads/nvidia-patch.${NVIDIA_PATCH_VERSION:?}.sh"
|
||||
PATCH_OUTPUT_DIR="/patched-lib" "${USER_HOME:?}/Downloads/nvidia-patch-fbc.${NVIDIA_PATCH_VERSION:?}.sh"
|
||||
|
||||
pushd "/patched-lib" &>/dev/null || {
|
||||
print_error "Failed to push directory to /patched-lib"
|
||||
exit 1
|
||||
}
|
||||
for f in *; do
|
||||
suffix="${f##*.so}"
|
||||
name="$(basename "$f" "$suffix")"
|
||||
[ -h "$name" ] || ln -sf "$f" "$name"
|
||||
[ -h "$name" ] || ln -sf "$f" "$name.1"
|
||||
done
|
||||
ldconfig
|
||||
popd &>/dev/null || {
|
||||
print_error "Failed to pop directory out of /patched-lib"
|
||||
exit 1
|
||||
}
|
||||
)
|
||||
else
|
||||
print_step_header "Leaving NVIDIA driver stock without patching"
|
||||
fi
|
||||
}
|
||||
|
||||
function install_deb_mesa {
|
||||
if [ ! -f /tmp/init-mesa-libs-install.log ]; then
|
||||
print_step_header "Enable i386 arch"
|
||||
dpkg --add-architecture i386
|
||||
if [ "${ENABLE_SID:-}" = "true" ]; then
|
||||
print_step_header "Add Debian SID sources"
|
||||
echo "deb http://deb.debian.org/debian/ sid main" >/etc/apt/sources.list
|
||||
fi
|
||||
apt-get update &>>/tmp/init-mesa-libs-install.log
|
||||
print_step_header "Install mesa vulkan drivers"
|
||||
echo "" >>/tmp/init-mesa-libs-install.log
|
||||
apt-get install -y --no-install-recommends \
|
||||
libvulkan1 \
|
||||
libvulkan1:i386 \
|
||||
mesa-vulkan-drivers \
|
||||
mesa-vulkan-drivers:i386 \
|
||||
mesa-utils \
|
||||
mesa-utils-extra \
|
||||
vulkan-tools \
|
||||
&>>/tmp/init-mesa-libs-install.log
|
||||
else
|
||||
print_step_header "Mesa has already been installed into this container"
|
||||
fi
|
||||
}
|
||||
|
||||
function install_amd_gpu_driver {
|
||||
echo "Install AMD vulkan driver"
|
||||
if command -v pacman &>/dev/null; then
|
||||
print_step_header "Install AMD Mesa driver"
|
||||
pacman -Syu --noconfirm --needed \
|
||||
lib32-mesa \
|
||||
lib32-vulkan-icd-loader \
|
||||
lib32-vulkan-radeon \
|
||||
vulkan-icd-loader \
|
||||
vulkan-radeon
|
||||
# There is currently nothing to install inside the debian container. This already comes with the vulken drives that are required
|
||||
# elif command -v apt-get &> /dev/null; then
|
||||
# [[ "${APT_UPDATED:-false}" == 'false' ]] && apt-get update && export APT_UPDATED=true
|
||||
# apt-get install -y \
|
||||
# libvulkan1 \
|
||||
# libvulkan1:i386 \
|
||||
# mesa-vulkan-drivers \
|
||||
# mesa-vulkan-drivers:i386
|
||||
elif command -v apt-get &>/dev/null; then
|
||||
install_deb_mesa
|
||||
fi
|
||||
}
|
||||
|
||||
function install_intel_gpu_driver {
|
||||
echo "Install Intel vulkan driver"
|
||||
if command -v pacman &>/dev/null; then
|
||||
print_step_header "Install Intel Mesa driver"
|
||||
pacman -Syu --noconfirm --needed \
|
||||
lib32-mesa \
|
||||
lib32-vulkan-icd-loader \
|
||||
lib32-vulkan-intel \
|
||||
vulkan-icd-loader \
|
||||
vulkan-intel
|
||||
# There is currently nothing to install inside the debian container. This already comes with the vulken drives that are required
|
||||
# elif command -v apt-get &> /dev/null; then
|
||||
# [[ "${APT_UPDATED:-false}" == 'false' ]] && apt-get update && export APT_UPDATED=true
|
||||
# apt-get install -y \
|
||||
# libvulkan1 \
|
||||
# libvulkan1:i386 \
|
||||
# mesa-vulkan-drivers \
|
||||
# mesa-vulkan-drivers:i386
|
||||
elif command -v apt-get &>/dev/null; then
|
||||
install_deb_mesa
|
||||
fi
|
||||
}
|
||||
|
||||
# NVIDIA GPU
|
||||
if [[ ! -z ${nvidia_pci_address} ]]; then
|
||||
echo "**** Found NVIDIA device '${nvidia_gpu_name}' ****";
|
||||
install_nvidia_driver
|
||||
else
|
||||
echo "**** No NVIDIA device found ****";
|
||||
fi
|
||||
# Intel Arc GPU or Intel CPU with possible iGPU
|
||||
if [[ ! -z ${intel_gpu_model} ]]; then
|
||||
echo "**** Found Intel device '${intel_gpu_model}' ****";
|
||||
if [ "${intel_gpu_model:-}X" != "X" ]; then
|
||||
print_header "Found Intel device '${intel_gpu_model:?}'"
|
||||
install_intel_gpu_driver
|
||||
elif [[ ! -z ${intel_cpu_model} ]]; then
|
||||
echo "**** Found Intel device '${intel_cpu_model}' ****";
|
||||
elif [ "${intel_cpu_model:-}X" != "X" ]; then
|
||||
print_header "Found Intel device '${intel_cpu_model:?}'"
|
||||
install_intel_gpu_driver
|
||||
else
|
||||
echo "**** No Intel device found ****";
|
||||
print_header "No Intel device found"
|
||||
fi
|
||||
# AMD GPU
|
||||
if [[ ! -z ${amd_gpu_model} ]]; then
|
||||
echo "**** Found AMD device '${amd_gpu_model}' ****";
|
||||
if [ "${amd_gpu_model:-}X" != "X" ]; then
|
||||
print_header "Found AMD device '${amd_gpu_model:?}'"
|
||||
install_amd_gpu_driver
|
||||
else
|
||||
echo "**** No AMD device found ****";
|
||||
print_header "No AMD device found"
|
||||
fi
|
||||
# NVIDIA GPU
|
||||
if [ "${NVIDIA_DRIVER_VERSION:-}X" != "X" ]; then
|
||||
export nvidia_host_driver_version="${NVIDIA_DRIVER_VERSION:?}"
|
||||
print_header "Forcing install of NVIDIA driver version '${nvidia_host_driver_version:?}' because the 'NVIDIA_DRIVER_VERSION' variable is set."
|
||||
install_nvidia_driver
|
||||
patch_nvidia_driver
|
||||
elif [ "${nvidia_pci_address:-}X" != "X" ]; then
|
||||
print_header "Found NVIDIA device '${nvidia_gpu_name:?}'"
|
||||
install_nvidia_driver
|
||||
patch_nvidia_driver
|
||||
else
|
||||
print_header "No NVIDIA device found"
|
||||
fi
|
||||
|
||||
echo "DONE"
|
||||
echo -e "\e[34mDONE\e[0m"
|
||||
|
||||
22
overlay/etc/cont-init.d/70-configure_desktop.sh
Normal file
22
overlay/etc/cont-init.d/70-configure_desktop.sh
Normal file
@@ -0,0 +1,22 @@
|
||||
|
||||
print_header "Configure Desktop"
|
||||
|
||||
if ([ "${MODE}" != "s" ] && [ "${MODE}" != "secondary" ]); then
|
||||
print_step_header "Enable Desktop service."
|
||||
sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/desktop.ini
|
||||
else
|
||||
print_step_header "Desktop service not available when container is run in 'secondary' mode."
|
||||
sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/desktop.ini
|
||||
fi
|
||||
|
||||
# Setup home directory
|
||||
if [[ ! -f /tmp/.home-directory-template-updated ]]; then
|
||||
print_step_header "Ensure home directory template is owned by the default user."
|
||||
chown -R ${PUID}:${PGID} /templates/home_directory_template
|
||||
print_step_header "Installing default home directory template"
|
||||
mkdir -p "${USER_HOME:?}"
|
||||
rsync -aq /templates/home_directory_template/ "${USER_HOME:?}"/
|
||||
touch /tmp/.home-directory-template-updated
|
||||
fi
|
||||
|
||||
echo -e "\e[34mDONE\e[0m"
|
||||
@@ -30,32 +30,42 @@ fi
|
||||
|
||||
# Configure a NVIDIA X11 config
|
||||
function configure_nvidia_x_server {
|
||||
echo "Configuring X11 with GPU ID: '${gpu_select}'"
|
||||
print_step_header "Configuring X11 with GPU ID: '${gpu_select}'"
|
||||
nvidia_gpu_hex_id=$(nvidia-smi --format=csv --query-gpu=pci.bus_id --id="${gpu_select}" 2> /dev/null | sed -n 2p)
|
||||
IFS=":." ARR_ID=(${nvidia_gpu_hex_id})
|
||||
unset IFS
|
||||
bus_id=PCI:$((16#${ARR_ID[1]})):$((16#${ARR_ID[2]})):$((16#${ARR_ID[3]}))
|
||||
echo "Configuring X11 with PCI bus ID: '${bus_id}'"
|
||||
print_step_header "Configuring X11 with PCI bus ID: '${bus_id}'"
|
||||
export MODELINE=$(cvt -r "${DISPLAY_SIZEW}" "${DISPLAY_SIZEH}" "${DISPLAY_REFRESH}" | sed -n 2p)
|
||||
echo "Writing X11 config with ${MODELINE}"
|
||||
print_step_header "Writing X11 config with ${MODELINE}"
|
||||
connected_monitor="--use-display-device=None"
|
||||
if [[ "X${DISPLAY_VIDEO_PORT:-}" != "X" ]]; then
|
||||
connected_monitor="--connected-monitor=${DISPLAY_VIDEO_PORT:?}"
|
||||
fi
|
||||
nvidia-xconfig --virtual="${DISPLAY_SIZEW:?}x${DISPLAY_SIZEH:?}" --depth="${DISPLAY_CDEPTH:?}" --mode=$(echo "${MODELINE:?}" | awk '{print $2}' | tr -d '"') --allow-empty-initial-configuration --no-probe-all-gpus --busid="${bus_id:?}" --no-multigpu --no-sli --no-base-mosaic --only-one-x-screen ${connected_monitor:?}
|
||||
sed -i '/Driver\s\+"nvidia"/a\ Option "ModeValidation" "NoMaxPClkCheck, NoEdidMaxPClkCheck, NoMaxSizeCheck, NoHorizSyncCheck, NoVertRefreshCheck, NoVirtualSizeCheck, NoTotalSizeCheck, NoDualLinkDVICheck, NoDisplayPortBandwidthCheck, AllowNon3DVisionModes, AllowNonHDMI3DModes, AllowNonEdidModes, NoEdidHDMI2Check, AllowDpInterlaced"\n Option "HardDPMS" "False"' /etc/X11/xorg.conf
|
||||
# Allow SteamHeadless to run with an eGPU
|
||||
sed -i '/Driver\s\+"nvidia"/a\ Option "AllowExternalGpus" "True"' /etc/X11/xorg.conf
|
||||
# Configure primary GPU
|
||||
sed -i '/Driver\s\+"nvidia"/a\ Option "PrimaryGPU" "yes"' /etc/X11/xorg.conf
|
||||
# Force X server to start even if no display devices are connected
|
||||
sed -i '/Driver\s\+"nvidia"/a\ Option "AllowEmptyInitialConfiguration"' /etc/X11/xorg.conf
|
||||
# Disable some mode validation checks
|
||||
sed -i '/Driver\s\+"nvidia"/a\ Option "ModeValidation" "NoMaxPClkCheck, NoEdidMaxPClkCheck, NoMaxSizeCheck, NoHorizSyncCheck, NoVertRefreshCheck, NoVirtualSizeCheck, NoTotalSizeCheck, NoDualLinkDVICheck, NoDisplayPortBandwidthCheck, AllowNon3DVisionModes, AllowNonHDMI3DModes, AllowNonEdidModes, NoEdidHDMI2Check, AllowDpInterlaced"' /etc/X11/xorg.conf
|
||||
# Configure the default modeline
|
||||
sed -i '/Section\s\+"Monitor"/a\ '"${MODELINE}" /etc/X11/xorg.conf
|
||||
# Prevent interference between GPUs
|
||||
echo -e "Section \"ServerFlags\"\n Option \"AutoAddGPU\" \"false\"\nEndSection" | tee -a /etc/X11/xorg.conf > /dev/null
|
||||
# Configure primary GPU
|
||||
sed -i '/Driver\s\+"nvidia"/a\ Option "AllowEmptyInitialConfiguration"\n Option "PrimaryGPU" "yes"' /usr/share/X11/xorg.conf.d/nvidia-drm-outputclass.conf
|
||||
}
|
||||
|
||||
# Allow anybody for running x server
|
||||
function configure_x_server {
|
||||
# Configure x to be run by anyone
|
||||
if grep -Fxq "allowed_users=console" /etc/X11/Xwrapper.config; then
|
||||
echo "Configure Xwrapper.config"
|
||||
if [[ ! -f /etc/X11/Xwrapper.config ]]; then
|
||||
print_step_header "Create Xwrapper.config"
|
||||
echo 'allowed_users=anybody' > /etc/X11/Xwrapper.config
|
||||
echo 'needs_root_rights=yes' >> /etc/X11/Xwrapper.config
|
||||
elif grep -Fxq "allowed_users=console" /etc/X11/Xwrapper.config; then
|
||||
print_step_header "Configure Xwrapper.config"
|
||||
sed -i "s/allowed_users=console/allowed_users=anybody/" /etc/X11/Xwrapper.config
|
||||
echo 'needs_root_rights=yes' >> /etc/X11/Xwrapper.config
|
||||
fi
|
||||
@@ -69,7 +79,7 @@ function configure_x_server {
|
||||
# Clear out old lock files
|
||||
display_file=${XORG_SOCKET_DIR}/X${DISPLAY#:}
|
||||
if [ -S ${display_file} ]; then
|
||||
echo "Removing ${display_file} before starting"
|
||||
print_step_header "Removing ${display_file} before starting"
|
||||
rm -f /tmp/.X${DISPLAY#:}-lock
|
||||
rm ${display_file}
|
||||
fi
|
||||
@@ -80,43 +90,46 @@ function configure_x_server {
|
||||
chmod 1777 /tmp/.ICE-unix/
|
||||
|
||||
# Check if this container is being run as a secondary instance
|
||||
if [ "${MODE}" == "p" ] | [ "${MODE}" == "primary" ]; then
|
||||
echo "Configure container as primary the X server"
|
||||
if ([ "${MODE}" = "p" ] || [ "${MODE}" = "primary" ]); then
|
||||
print_step_header "Configure container as primary the X server"
|
||||
# Enable supervisord script
|
||||
sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/xorg.ini
|
||||
elif [ "${MODE}" == "fb" ] | [ "${MODE}" == "framebuffer" ]; then
|
||||
echo "Configure container to use a virtual framebuffer as the X server"
|
||||
print_step_header "Configure container to use a virtual framebuffer as the X server"
|
||||
# Disable xorg supervisord script
|
||||
sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/xorg.ini
|
||||
# Enable xvfb supervisord script
|
||||
sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/xvfb.ini
|
||||
else
|
||||
print_step_header "Configure container with no X server"
|
||||
sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/xorg.ini
|
||||
fi
|
||||
|
||||
# Enable KB/Mouse input capture with Xorg if configured
|
||||
if [ ${ENABLE_EVDEV_INPUTS:-} = "true" ]; then
|
||||
echo "Enabling evdev input class on pointers, keyboards, touchpads, touch screens, etc."
|
||||
cp -fv /usr/share/X11/xorg.conf.d/10-evdev.conf /etc/X11/xorg.conf.d/10-evdev.conf
|
||||
print_step_header "Enabling evdev input class on pointers, keyboards, touchpads, touch screens, etc."
|
||||
cp -f /usr/share/X11/xorg.conf.d/10-evdev.conf /etc/X11/xorg.conf.d/10-evdev.conf
|
||||
else
|
||||
echo "Leaving evdev inputs disabled"
|
||||
print_step_header "Leaving evdev inputs disabled"
|
||||
fi
|
||||
|
||||
# Configure dummy config if no monitor is connected (not applicable to NVIDIA)
|
||||
if [[ "X${monitor_connected}" == "X" ]]; then
|
||||
echo "No monitors connected. Installing dummy xorg.conf"
|
||||
if ([ "X${monitor_connected}" = "X" ] || [ "${FORCE_X11_DUMMY_CONFIG}" = "true" ]); then
|
||||
print_step_header "No monitors connected. Installing dummy xorg.conf"
|
||||
# Use a dummy display input
|
||||
cp -fv /templates/xorg/xorg.dummy.conf /etc/X11/xorg.conf
|
||||
cp -f /templates/xorg/xorg.dummy.conf /etc/X11/xorg.conf
|
||||
fi
|
||||
}
|
||||
|
||||
if ([ "${MODE}" != "s" ] && [ "${MODE}" != "secondary" ]); then
|
||||
if [[ -z ${nvidia_gpu_hex_id} ]]; then
|
||||
echo "**** Generate default xorg.conf ****";
|
||||
print_header "Generate default xorg.conf"
|
||||
configure_x_server
|
||||
else
|
||||
echo "**** Generate NVIDIA xorg.conf ****";
|
||||
print_header "Generate NVIDIA xorg.conf"
|
||||
configure_x_server
|
||||
configure_nvidia_x_server
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "DONE"
|
||||
echo -e "\e[34mDONE\e[0m"
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
|
||||
echo "**** Configure Dockerd ****"
|
||||
|
||||
if ([ "${MODE}" != "s" ] && [ "${MODE}" != "secondary" ]); then
|
||||
if [ ! -S /var/run/docker.sock ]; then
|
||||
echo "Enable Dockerd daemon"
|
||||
sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/dind.ini
|
||||
else
|
||||
echo "Docker socket has been passed in from host. Using that instead"
|
||||
fi
|
||||
# Configure 'default' user to run docker commands without sudo
|
||||
if ! getent group docker &> /dev/null; then
|
||||
echo "Add user '${USER}' to docker group for sudoless execution"
|
||||
groupadd docker
|
||||
usermod -aG docker ${USER}
|
||||
mkdir -p ${USER_HOME:?}/.docker
|
||||
chown -R ${PUID}:${PGID} ${USER_HOME:?}/.docker
|
||||
chmod -R g+rwx ${USER_HOME:?}/.docker
|
||||
fi
|
||||
else
|
||||
echo "Dockerd daemon not available when container is run in 'secondary' mode"
|
||||
fi
|
||||
|
||||
echo "DONE"
|
||||
13
overlay/etc/cont-init.d/80-configure_flatpak.sh
Normal file
13
overlay/etc/cont-init.d/80-configure_flatpak.sh
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
print_header "Configure Flatpak"
|
||||
|
||||
if [ "X${NVIDIA_VISIBLE_DEVICES:-}" != "X" ]; then
|
||||
# Fix some flatpak quirks (not sure what is happening here) for NVIDIA containers
|
||||
mount -t proc none /proc
|
||||
flatpak list
|
||||
print_step_header "Flatpak configured for running inside a Docker container"
|
||||
else
|
||||
print_step_header "Flatpak already configured for running inside a Docker container"
|
||||
fi
|
||||
|
||||
echo -e "\e[34mDONE\e[0m"
|
||||
@@ -1,10 +1,10 @@
|
||||
|
||||
echo "**** Configure Neko ****"
|
||||
print_header "Configure Neko"
|
||||
# REF: https://neko.m1k1o.net/#/getting-started/configuration
|
||||
|
||||
if ([ "${MODE}" != "s" ] && [ "${MODE}" != "secondary" ]); then
|
||||
if [ ${WEB_UI_MODE} = "neko" ]; then
|
||||
echo "Enable Neko server"
|
||||
print_step_header "Enable Neko server"
|
||||
sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/neko.ini
|
||||
|
||||
# Make directories for neko
|
||||
@@ -15,9 +15,9 @@ if ([ "${MODE}" != "s" ] && [ "${MODE}" != "secondary" ]); then
|
||||
# Configure nat1to1 if it is not already set
|
||||
if [[ -z ${NEKO_NAT1TO1} ]]; then
|
||||
export NEKO_NAT1TO1=$(ip route get 1 | awk '{print $(NF-2);exit}')
|
||||
echo "Setting NEKO_NAT1TO1=${NEKO_NAT1TO1}"
|
||||
print_step_header "Setting NEKO_NAT1TO1=${NEKO_NAT1TO1}"
|
||||
else
|
||||
echo "User provided setting NEKO_NAT1TO1=${NEKO_NAT1TO1}"
|
||||
print_step_header "User provided setting NEKO_NAT1TO1=${NEKO_NAT1TO1}"
|
||||
fi
|
||||
|
||||
# Configure hardware acceleration if it is not already set
|
||||
@@ -39,10 +39,10 @@ if ([ "${MODE}" != "s" ] && [ "${MODE}" != "secondary" ]); then
|
||||
export NEKO_SCREEN="${DISPLAY_SIZEW}x${DISPLAY_SIZEH}@${DISPLAY_REFRESH}"
|
||||
fi
|
||||
else
|
||||
echo "Disable Neko server"
|
||||
print_step_header "Disable Neko server"
|
||||
fi
|
||||
else
|
||||
echo "Neko server not available when container is run in 'secondary' mode"
|
||||
print_step_header "Neko server not available when container is run in 'secondary' mode"
|
||||
fi
|
||||
|
||||
echo "DONE"
|
||||
echo -e "\e[34mDONE\e[0m"
|
||||
|
||||
134
overlay/etc/cont-init.d/90-configure_steam.sh
Normal file
134
overlay/etc/cont-init.d/90-configure_steam.sh
Normal file
@@ -0,0 +1,134 @@
|
||||
|
||||
print_header "Configure Steam"
|
||||
|
||||
steam_autostart_desktop="$(
|
||||
cat <<EOF
|
||||
[Desktop Entry]
|
||||
Encoding=UTF-8
|
||||
Type=Application
|
||||
Name=Steam
|
||||
Comment=Launch steam on login
|
||||
Exec=/usr/games/steam %U ${STEAM_ARGS:-}
|
||||
Icon=steam
|
||||
OnlyShowIn=XFCE;
|
||||
RunHook=0
|
||||
StartupNotify=false
|
||||
Terminal=false
|
||||
Hidden=false
|
||||
EOF
|
||||
)"
|
||||
|
||||
default_steam_config="$(
|
||||
cat <<EOF
|
||||
"InstallConfigStore"
|
||||
{
|
||||
"Software"
|
||||
{
|
||||
"Valve"
|
||||
{
|
||||
"Steam"
|
||||
{
|
||||
"CompatToolMapping"
|
||||
{
|
||||
"0"
|
||||
{
|
||||
"name" "proton_hotfix"
|
||||
"config" ""
|
||||
"priority" "75"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
)"
|
||||
|
||||
default_steam_library_config="$(
|
||||
cat <<EOF
|
||||
"libraryfolders"
|
||||
{
|
||||
"0"
|
||||
{
|
||||
"path" "/home/default/.steam/steam"
|
||||
"label" "Home"
|
||||
"totalsize" "0"
|
||||
"update_clean_bytes_tally" "0"
|
||||
"time_last_update_verified" "0"
|
||||
"apps"
|
||||
{
|
||||
}
|
||||
}
|
||||
"1"
|
||||
{
|
||||
"path" "/mnt/games/GameLibrary/Steam"
|
||||
"label" "Games"
|
||||
"contentid" "4532270033051814356"
|
||||
"totalsize" "0"
|
||||
"update_clean_bytes_tally" "0"
|
||||
"time_last_update_verified" "0"
|
||||
"apps"
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
)"
|
||||
|
||||
games_steam_library_config="$(
|
||||
cat <<EOF
|
||||
"libraryfolder"
|
||||
{
|
||||
"contentid" "4532270033051814356"
|
||||
"label" "Games"
|
||||
}
|
||||
EOF
|
||||
)"
|
||||
|
||||
if [ "${ENABLE_STEAM:-}" = "true" ]; then
|
||||
if [ "${MODE}" == "s" ] || [ "${MODE}" == "secondary" ]; then
|
||||
print_step_header "Enable Steam supervisor.d service"
|
||||
sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/steam.ini
|
||||
else
|
||||
print_step_header "Enable Steam auto-start script"
|
||||
mkdir -p "${USER_HOME:?}/.config/autostart"
|
||||
echo "${steam_autostart_desktop:?}" >"${USER_HOME:?}/.config/autostart/Steam.desktop"
|
||||
sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/steam.ini
|
||||
fi
|
||||
|
||||
# Ensuring Steam Play is enabled for all titles
|
||||
CONFIG_VDF="${USER_HOME:?}/.steam/steam/config/config.vdf"
|
||||
if [ ! -f "${CONFIG_VDF}" ]; then
|
||||
print_step_header "Initializing Steam config"
|
||||
mkdir -p "$(dirname "${CONFIG_VDF}")"
|
||||
echo "${default_steam_config}" >"${CONFIG_VDF}"
|
||||
chown -R "${USER:?}:${USER:?}" "${USER_HOME:?}/.steam"
|
||||
else
|
||||
print_step_header "Steam config already exists, skipping initialization"
|
||||
fi
|
||||
|
||||
# Ensure Steam library folder is set to /mnt/games if not already
|
||||
LIBRARY_VDF="${USER_HOME:?}/.steam/steam/steamapps/libraryfolders.vdf"
|
||||
if [ ! -f "${LIBRARY_VDF}" ]; then
|
||||
print_step_header "Initializing Steam library"
|
||||
mkdir -p "$(dirname "${LIBRARY_VDF}")"
|
||||
echo "${default_steam_library_config}" >"${LIBRARY_VDF}"
|
||||
chown -R "${USER:?}:${USER:?}" "${USER_HOME:?}/.steam"
|
||||
# Only if we have mounted a /mnt/games path, then make the default games library for steam
|
||||
if [ -d "/mnt/games" ]; then
|
||||
mkdir -p "/mnt/games/GameLibrary/Steam/steamapps"
|
||||
chown "${USER:?}:${USER:?}" \
|
||||
"/mnt/games/GameLibrary" \
|
||||
"/mnt/games/GameLibrary/Steam" \
|
||||
"/mnt/games/GameLibrary/Steam/steamapps"
|
||||
echo "${games_steam_library_config}" >"/mnt/games/GameLibrary/Steam/libraryfolder.vdf"
|
||||
fi
|
||||
else
|
||||
print_step_header "Steam library config already exists, skipping initialization"
|
||||
fi
|
||||
else
|
||||
print_step_header "Disable Steam service"
|
||||
sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/steam.ini
|
||||
fi
|
||||
|
||||
echo -e "\e[34mDONE\e[0m"
|
||||
@@ -1,15 +1,15 @@
|
||||
|
||||
echo "**** Configure Sunshine ****"
|
||||
print_header "Configure Sunshine"
|
||||
|
||||
if ([ "${MODE}" != "s" ] && [ "${MODE}" != "secondary" ]); then
|
||||
if [ "${ENABLE_SUNSHINE:-}" = "true" ]; then
|
||||
echo "Enable Sunshine server"
|
||||
print_step_header "Enable Sunshine server"
|
||||
sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/sunshine.ini
|
||||
else
|
||||
echo "Disable Sunshine server"
|
||||
print_step_header "Disable Sunshine server"
|
||||
fi
|
||||
else
|
||||
echo "Sunshine server not available when container is run in 'secondary' mode"
|
||||
print_step_header "Sunshine server not available when container is run in 'secondary' mode"
|
||||
fi
|
||||
|
||||
echo "DONE"
|
||||
echo -e "\e[34mDONE\e[0m"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
echo "**** Configure VNC ****"
|
||||
print_header "Configure VNC"
|
||||
|
||||
function get_next_unused_port() {
|
||||
local __start_port=${1}
|
||||
@@ -15,66 +15,37 @@ function get_next_unused_port() {
|
||||
# Note: Ports 32035-32248 are unallocated port ranges. We should be able to find something in here that we can use
|
||||
# REF: https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml?&page=130
|
||||
DYNAMIC_PORT_VNC=$(get_next_unused_port 32035)
|
||||
DYNAMIC_PORT_NOVNC_SERVICE=$(get_next_unused_port ${DYNAMIC_PORT_VNC})
|
||||
DYNAMIC_PORT_AUDIO_WEBSOCKET=$(get_next_unused_port ${DYNAMIC_PORT_NOVNC_SERVICE})
|
||||
DYNAMIC_PORT_AUDIO_STREAM=$(get_next_unused_port ${DYNAMIC_PORT_AUDIO_WEBSOCKET})
|
||||
export PORT_VNC=${PORT_VNC:-$DYNAMIC_PORT_VNC}
|
||||
echo "Configure VNC service port '${PORT_VNC}'"
|
||||
export PORT_NOVNC_SERVICE=${PORT_NOVNC_SERVICE:-$DYNAMIC_PORT_NOVNC_SERVICE}
|
||||
echo "Configure noVNC service port '${PORT_NOVNC_SERVICE}'"
|
||||
export PORT_AUDIO_WEBSOCKET=${PORT_AUDIO_WEBSOCKET:-$DYNAMIC_PORT_AUDIO_WEBSOCKET}
|
||||
echo "Configure audio websocket port '${PORT_AUDIO_WEBSOCKET}'"
|
||||
print_step_header "Configure VNC service port '${PORT_VNC}'"
|
||||
DYNAMIC_PORT_AUDIO_STREAM=$(get_next_unused_port ${DYNAMIC_PORT_VNC})
|
||||
export PORT_AUDIO_STREAM=${PORT_AUDIO_STREAM:-$DYNAMIC_PORT_AUDIO_STREAM}
|
||||
echo "Configure pulseaudio encoded stream port '${PORT_AUDIO_STREAM}'"
|
||||
print_step_header "Configure pulseaudio encoded stream port '${PORT_AUDIO_STREAM}'"
|
||||
|
||||
if ([ "${MODE}" != "s" ] && [ "${MODE}" != "secondary" ]); then
|
||||
|
||||
if [ ${WEB_UI_MODE} = "vnc" ]; then
|
||||
echo "Enable VNC server"
|
||||
if [ "${WEB_UI_MODE:-}" = "vnc" ]; then
|
||||
print_step_header "Enable VNC server"
|
||||
sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/vnc.ini
|
||||
|
||||
# Configure Nginx proxy for the websocket and VNC
|
||||
cp -f /opt/noVNC/nginx.template.conf /opt/noVNC/nginx.conf
|
||||
sed -i "s|<USER>|${USER}|" /opt/noVNC/nginx.conf
|
||||
sed -i "s|<PORT_NOVNC_WEB>|${PORT_NOVNC_WEB}|" /opt/noVNC/nginx.conf
|
||||
sed -i "s|<PORT_NOVNC_SERVICE>|${PORT_NOVNC_SERVICE}|" /opt/noVNC/nginx.conf
|
||||
sed -i "s|<PORT_AUDIO_WEBSOCKET>|${PORT_AUDIO_WEBSOCKET}|" /opt/noVNC/nginx.conf
|
||||
mkdir -p /var/log/vncproxy
|
||||
chown -R ${USER} /var/log/vncproxy
|
||||
|
||||
# TODO: Remove this... Always enable VNC audio
|
||||
if [[ "${ENABLE_VNC_AUDIO}" == "true" ]]; then
|
||||
# Credits for this audio patch:
|
||||
# - https://github.com/novnc/noVNC/issues/302
|
||||
# - https://github.com/vexingcodes/dwarf-fortress-docker
|
||||
# - https://github.com/calebj/noVNC
|
||||
if [ -f /opt/noVNC/audio.patch ]; then
|
||||
echo "Patching noVNC with audio websocket"
|
||||
# Update port specification in patch file
|
||||
sed -i "s|<PORT_AUDIO_WEBSOCKET>|${PORT_AUDIO_WEBSOCKET}|" /opt/noVNC/audio.patch
|
||||
# Apply patch
|
||||
pushd /opt/noVNC/ &> /dev/null
|
||||
patch -p1 --input=/opt/noVNC/audio.patch --batch --quiet
|
||||
popd &> /dev/null
|
||||
rm /opt/noVNC/audio.patch
|
||||
fi
|
||||
# Enable supervisord script
|
||||
sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/vnc-audio.ini
|
||||
|
||||
# Remove x11vnc from applications menu
|
||||
if ! grep -q 'Hidden=true' /usr/share/applications/x11vnc.desktop; then
|
||||
echo 'Hidden=true' >> /usr/share/applications/x11vnc.desktop
|
||||
fi
|
||||
else
|
||||
echo "Disable audio stream"
|
||||
echo "Disable audio websock"
|
||||
print_step_header "Disable audio stream"
|
||||
print_step_header "Disable audio websock"
|
||||
# Disable supervisord script
|
||||
sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/vnc-audio.ini
|
||||
fi
|
||||
else
|
||||
echo "Disable VNC server"
|
||||
print_step_header "Disable VNC server"
|
||||
sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/vnc.ini
|
||||
sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/vnc-audio.ini
|
||||
fi
|
||||
else
|
||||
echo "VNC server not available when container is run in 'secondary' mode"
|
||||
print_step_header "VNC server not available when container is run in 'secondary' mode"
|
||||
sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/vnc.ini
|
||||
sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/vnc-audio.ini
|
||||
fi
|
||||
|
||||
echo "DONE"
|
||||
echo -e "\e[34mDONE\e[0m"
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
if [ "${MODE}" == "s" ] | [ "${MODE}" == "secondary" ]; then
|
||||
echo "Configure container as secondary"
|
||||
# Disable dbus
|
||||
echo " - Disable dbus"
|
||||
sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/dbus.ini
|
||||
# Disable desktop
|
||||
echo " - Disable desktop"
|
||||
sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/desktop.ini
|
||||
# Disable sshd
|
||||
echo " - Disable sshd"
|
||||
sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/sshd.ini
|
||||
# Disable vnc
|
||||
echo " - Disable vnc"
|
||||
sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/vnc.ini
|
||||
# Disable vnc
|
||||
echo " - Disable vnc"
|
||||
sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/vnc.ini
|
||||
# Disable vnc-audio
|
||||
echo " - Disable vnc audio stream"
|
||||
echo " - Disable vnc audio websock"
|
||||
sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/vnc-audio.ini
|
||||
# Disable xorg
|
||||
echo " - Disable xorg"
|
||||
sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/xorg.ini
|
||||
|
||||
# Enable pulseaudio
|
||||
echo " - Enable pulseaudio"
|
||||
sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/pulseaudio.ini
|
||||
# Enable steam
|
||||
echo " - Enable steam"
|
||||
sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/steam.ini
|
||||
# Enable udev
|
||||
echo " - Enable udev"
|
||||
sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/udev.ini
|
||||
fi
|
||||
|
||||
echo "DONE"
|
||||
34
overlay/etc/cont-init.d/95-setup_wol.sh
Normal file
34
overlay/etc/cont-init.d/95-setup_wol.sh
Normal file
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env bash
|
||||
###
|
||||
# File: 10-setup_user.sh
|
||||
# Project: cont-init.d
|
||||
# File Created: Tuesday, 5th September 2023 6:15:12 pm
|
||||
# Author: Josh.5 (jsunnex@gmail.com)
|
||||
# -----
|
||||
# Last Modified: Tuesday, 5th September 2023 6:39:32 pm
|
||||
# Modified By: Josh.5 (jsunnex@gmail.com)
|
||||
###
|
||||
|
||||
print_header "Configure WoL Manager"
|
||||
|
||||
if ([ "${MODE}" != "s" ] && [ "${MODE}" != "secondary" ]); then
|
||||
if [ "${ENABLE_WOL_POWER_MANAGER:-}" = "true" ]; then
|
||||
if [ -f "/tmp/.wol-monitor" ]; then
|
||||
print_step_header "Container started in WoL Manager mode. Disabling all other services."
|
||||
for init_config in /etc/supervisor.d/*.ini ; do
|
||||
init_config_basename=$(basename "${init_config:?}")
|
||||
init_name="${init_config_basename%.*}"
|
||||
[ "${init_name:?}" = "wol-power-manager" ] && continue
|
||||
echo " - Disable ${init_name:?}"
|
||||
sed -i 's|^autostart.*=.*$|autostart=false|' "${init_config:?}"
|
||||
done
|
||||
fi
|
||||
print_step_header "Enable WoL Manager service."
|
||||
sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/wol-power-manager.ini
|
||||
else
|
||||
print_step_header "Disable WoL Manager service."
|
||||
sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/wol-power-manager.ini
|
||||
fi
|
||||
else
|
||||
print_step_header "WoL Manager service not available when container is run in 'secondary' mode."
|
||||
fi
|
||||
@@ -1,13 +0,0 @@
|
||||
[Desktop Entry]
|
||||
Encoding=UTF-8
|
||||
Version=0.9.4
|
||||
Type=Application
|
||||
Name=Steam
|
||||
Comment=launch steam on login
|
||||
Exec=/usr/bin/flatpak run --branch=stable --arch=x86_64 --command=/app/bin/steam-wrapper --file-forwarding com.valvesoftware.Steam @@u %U @@ -silent
|
||||
Icon=steam
|
||||
OnlyShowIn=XFCE;
|
||||
RunHook=0
|
||||
StartupNotify=false
|
||||
Terminal=false
|
||||
Hidden=false
|
||||
@@ -1,14 +0,0 @@
|
||||
|
||||
[program:dind]
|
||||
priority=20
|
||||
autostart=false
|
||||
autorestart=true
|
||||
user=root
|
||||
command=/usr/bin/start-dind.sh
|
||||
stopsignal=INT
|
||||
stdout_logfile=/home/%(ENV_USER)s/.cache/log/dind.log
|
||||
stdout_logfile_maxbytes=10MB
|
||||
stdout_logfile_backups=7
|
||||
stderr_logfile=/home/%(ENV_USER)s/.cache/log/dind.err.log
|
||||
stderr_logfile_maxbytes=10MB
|
||||
stderr_logfile_backups=7
|
||||
@@ -1,14 +0,0 @@
|
||||
|
||||
[program:sshd]
|
||||
priority=10
|
||||
autostart=true
|
||||
autorestart=true
|
||||
user=root
|
||||
command=/usr/sbin/sshd -Ddp "%(ENV_PORT_SSH)s"
|
||||
stopsignal=INT
|
||||
stdout_logfile=/var/log/supervisor/sshd.log
|
||||
stdout_logfile_maxbytes=10MB
|
||||
stdout_logfile_backups=7
|
||||
stderr_logfile=/var/log/supervisor/sshd.err.log
|
||||
stderr_logfile_maxbytes=10MB
|
||||
stderr_logfile_backups=7
|
||||
@@ -10,8 +10,7 @@ autorestart=true
|
||||
startretries=50
|
||||
user=%(ENV_USER)s
|
||||
directory=/home/%(ENV_USER)s
|
||||
# command=/usr/games/steam -bigpicture
|
||||
command=/usr/games/steam
|
||||
command=/usr/games/steam %(ENV_STEAM_ARGS)s
|
||||
environment=HOME="/home/%(ENV_USER)s",USER="%(ENV_USER)s",DISPLAY="%(ENV_DISPLAY)s"
|
||||
stopsignal=INT
|
||||
stdout_logfile=/home/%(ENV_USER)s/.cache/log/steam.log
|
||||
|
||||
@@ -12,17 +12,3 @@ stdout_logfile_backups=7
|
||||
stderr_logfile=/home/%(ENV_USER)s/.cache/log/audiostream.err.log
|
||||
stderr_logfile_maxbytes=10MB
|
||||
stderr_logfile_backups=7
|
||||
|
||||
[program:audiowebsock]
|
||||
priority=40
|
||||
autostart=false
|
||||
autorestart=true
|
||||
user=%(ENV_USER)s
|
||||
command=/usr/local/bin/websockify %(ENV_PORT_AUDIO_WEBSOCKET)s localhost:%(ENV_PORT_AUDIO_STREAM)s
|
||||
stopsignal=INT
|
||||
stdout_logfile=/home/%(ENV_USER)s/.cache/log/audiowebsock.log
|
||||
stdout_logfile_maxbytes=10MB
|
||||
stdout_logfile_backups=7
|
||||
stderr_logfile=/home/%(ENV_USER)s/.cache/log/audiowebsock.err.log
|
||||
stderr_logfile_maxbytes=10MB
|
||||
stderr_logfile_backups=7
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
priority=30
|
||||
autostart=false
|
||||
autorestart=true
|
||||
user=%(ENV_USER)s
|
||||
user=root
|
||||
command=/usr/bin/start-x11vnc.sh
|
||||
environment=HOME="/home/%(ENV_USER)s",USER="%(ENV_USER)s",DISPLAY="%(ENV_DISPLAY)s",PORT_VNC="%(ENV_PORT_VNC)s"
|
||||
stopsignal=INT
|
||||
@@ -14,12 +14,12 @@ stderr_logfile=/home/%(ENV_USER)s/.cache/log/x11vnc.err.log
|
||||
stderr_logfile_maxbytes=10MB
|
||||
stderr_logfile_backups=7
|
||||
|
||||
[program:novnc]
|
||||
[program:frontend]
|
||||
priority=30
|
||||
autostart=false
|
||||
autorestart=true
|
||||
user=%(ENV_USER)s
|
||||
command=/opt/noVNC/utils/launch.sh --vnc localhost:%(ENV_PORT_VNC)s --listen %(ENV_PORT_NOVNC_SERVICE)s
|
||||
user=root
|
||||
command=/opt/frontend/utils/run.sh --web-port %(ENV_PORT_NOVNC_WEB)s --remote-host localhost --vnc-port %(ENV_PORT_VNC)s --audio-port %(ENV_PORT_AUDIO_STREAM)s
|
||||
environment=HOME="/home/%(ENV_USER)s",USER="%(ENV_USER)s"
|
||||
stopsignal=INT
|
||||
stdout_logfile=/home/%(ENV_USER)s/.cache/log/novnc.log
|
||||
@@ -28,37 +28,3 @@ stdout_logfile_backups=7
|
||||
stderr_logfile=/home/%(ENV_USER)s/.cache/log/novnc.err.log
|
||||
stderr_logfile_maxbytes=10MB
|
||||
stderr_logfile_backups=7
|
||||
|
||||
[program:vncproxy]
|
||||
priority=30
|
||||
autostart=false
|
||||
autorestart=true
|
||||
numprocs=1
|
||||
startsecs=0
|
||||
user=%(ENV_USER)s
|
||||
command=/usr/sbin/nginx -c /opt/noVNC/nginx.conf
|
||||
environment=HOME="/home/%(ENV_USER)s",USER="%(ENV_USER)s"
|
||||
stopsignal=INT
|
||||
stdout_logfile=/home/%(ENV_USER)s/.cache/log/vncproxy.log
|
||||
stdout_logfile_maxbytes=10MB
|
||||
stdout_logfile_backups=7
|
||||
stderr_logfile=/home/%(ENV_USER)s/.cache/log/vncproxy.err.log
|
||||
stderr_logfile_maxbytes=10MB
|
||||
stderr_logfile_backups=7
|
||||
|
||||
# [program:kasmxproxy]
|
||||
# priority=30
|
||||
# autostart=false
|
||||
# autorestart=true
|
||||
# numprocs=1
|
||||
# startsecs=0
|
||||
# user=%(ENV_USER)s
|
||||
# command=/usr/sbin/nginx -c /opt/noVNC/nginx.conf
|
||||
# environment=HOME="/home/%(ENV_USER)s",USER="%(ENV_USER)s"
|
||||
# stopsignal=INT
|
||||
# stdout_logfile=/home/%(ENV_USER)s/.cache/log/vncproxy.log
|
||||
# stdout_logfile_maxbytes=10MB
|
||||
# stdout_logfile_backups=7
|
||||
# stderr_logfile=/home/%(ENV_USER)s/.cache/log/vncproxy.err.log
|
||||
# stderr_logfile_maxbytes=10MB
|
||||
# stderr_logfile_backups=7
|
||||
|
||||
15
overlay/etc/supervisor.d/wol-power-manager.ini
Normal file
15
overlay/etc/supervisor.d/wol-power-manager.ini
Normal file
@@ -0,0 +1,15 @@
|
||||
|
||||
[program:wol-power-manager]
|
||||
priority=60
|
||||
autostart=false
|
||||
autorestart=true
|
||||
user=root
|
||||
command=/usr/bin/steam-headless-wol-power-manager
|
||||
environment=HOME="/home/%(ENV_USER)s",USER="%(ENV_USER)s"
|
||||
stopsignal=INT
|
||||
stdout_logfile=/home/%(ENV_USER)s/.cache/log/wol-power-manager.log
|
||||
stdout_logfile_maxbytes=10MB
|
||||
stdout_logfile_backups=7
|
||||
stderr_logfile=/home/%(ENV_USER)s/.cache/log/wol-power-manager.err.log
|
||||
stderr_logfile_maxbytes=10MB
|
||||
stderr_logfile_backups=7
|
||||
@@ -1,40 +0,0 @@
|
||||
daemon off;
|
||||
worker_processes auto;
|
||||
pid /tmp/vncproxy.pid;
|
||||
error_log /home/<USER>/.cache/log/vncproxy.err.log;
|
||||
|
||||
events {
|
||||
}
|
||||
|
||||
http {
|
||||
server {
|
||||
listen <PORT_NOVNC_WEB> default_server;
|
||||
|
||||
access_log /home/<USER>/.cache/log/vncproxy.log;
|
||||
client_body_temp_path /tmp/client_body;
|
||||
fastcgi_temp_path /tmp/fastcgi_temp;
|
||||
proxy_temp_path /tmp/proxy_temp;
|
||||
scgi_temp_path /tmp/scgi_temp;
|
||||
uwsgi_temp_path /tmp/uwsgi_temp;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:<PORT_NOVNC_SERVICE>/;
|
||||
}
|
||||
|
||||
location /websockify {
|
||||
proxy_pass http://127.0.0.1:<PORT_NOVNC_SERVICE>/;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "Upgrade";
|
||||
proxy_set_header Host $host;
|
||||
}
|
||||
|
||||
location /audiowebsock {
|
||||
proxy_pass http://127.0.0.1:<PORT_AUDIO_WEBSOCKET>/;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "Upgrade";
|
||||
proxy_set_header Host $host;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
echo "**** Installing/upgrading Steam via flatpak ****"
|
||||
|
||||
# Install Steam client
|
||||
flatpak --user remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
|
||||
flatpak --user install --assumeyes --noninteractive --or-update flathub com.valvesoftware.Steam
|
||||
# Configure any required overrides
|
||||
flatpak --user override --filesystem=/mnt/games com.valvesoftware.Steam
|
||||
# TODO: Check if we should add /dev/dri here??
|
||||
|
||||
# Configure default steam library paths
|
||||
echo "Configure Steam default libraries..."
|
||||
mkdir -p /mnt/games/GameLibrary/SteamLibrary
|
||||
libraryfolders="$(cat <<EOF
|
||||
"libraryfolders"
|
||||
{
|
||||
"0"
|
||||
{
|
||||
"path" "${USER_HOME:?}/.var/app/com.valvesoftware.Steam/.local/share/Steam"
|
||||
"label" ""
|
||||
"contentid" "5619710282499379610"
|
||||
"totalsize" "0"
|
||||
"update_clean_bytes_tally" "0"
|
||||
"time_last_update_corruption" "0"
|
||||
"apps"
|
||||
{
|
||||
}
|
||||
}
|
||||
"1"
|
||||
{
|
||||
"path" "/mnt/games/GameLibrary/SteamLibrary"
|
||||
"label" "Mounted Games"
|
||||
"contentid" "4437054932394438372"
|
||||
"totalsize" "0"
|
||||
"update_clean_bytes_tally" "0"
|
||||
"time_last_update_corruption" "0"
|
||||
"apps"
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
)"
|
||||
if [[ ! -f ${USER_HOME:?}/.var/app/com.valvesoftware.Steam/.local/share/Steam/steamapps/libraryfolders.vdf ]]; then
|
||||
mkdir -p ${USER_HOME:?}/.var/app/com.valvesoftware.Steam/.local/share/Steam/steamapps
|
||||
echo "${libraryfolders}" > ${USER_HOME:?}/.var/app/com.valvesoftware.Steam/.local/share/Steam/steamapps/libraryfolders.vdf
|
||||
fi
|
||||
if [[ ! -f ${USER_HOME:?}/.var/app/com.valvesoftware.Steam/.local/share/Steam/config/libraryfolders.vdf ]]; then
|
||||
mkdir -p ${USER_HOME:?}/.var/app/com.valvesoftware.Steam/.local/share/Steam/config
|
||||
echo "${libraryfolders}" > ${USER_HOME:?}/.var/app/com.valvesoftware.Steam/.local/share/Steam/config/libraryfolders.vdf
|
||||
fi
|
||||
|
||||
echo "DONE"
|
||||
@@ -0,0 +1,7 @@
|
||||
[Default Applications]
|
||||
x-scheme-handler/http=xfce4-web-browser.desktop
|
||||
x-scheme-handler/https=xfce4-web-browser.desktop
|
||||
|
||||
[Added Associations]
|
||||
x-scheme-handler/http=xfce4-web-browser.desktop;
|
||||
x-scheme-handler/https=xfce4-web-browser.desktop;
|
||||
@@ -0,0 +1 @@
|
||||
WebBrowser=custom-WebBrowser
|
||||
@@ -47,4 +47,25 @@
|
||||
</property>
|
||||
</property>
|
||||
</property>
|
||||
<property name="desktop-icons" type="empty">
|
||||
<property name="style" type="int" value="0"/>
|
||||
<property name="icon-size" type="uint" value="48"/>
|
||||
<property name="show-tooltips" type="bool" value="true"/>
|
||||
<property name="show-thumbnails" type="bool" value="true"/>
|
||||
</property>
|
||||
<property name="last" type="empty">
|
||||
<property name="window-width" type="int" value="653"/>
|
||||
<property name="window-height" type="int" value="558"/>
|
||||
</property>
|
||||
<property name="windowlist-menu" type="empty">
|
||||
<property name="show-icons" type="bool" value="true"/>
|
||||
<property name="show-add-remove-workspaces" type="bool" value="false"/>
|
||||
<property name="show-workspace-names" type="bool" value="false"/>
|
||||
<property name="show" type="bool" value="true"/>
|
||||
</property>
|
||||
<property name="desktop-menu" type="empty">
|
||||
<property name="show-delete" type="bool" value="false"/>
|
||||
<property name="show-icons" type="bool" value="true"/>
|
||||
<property name="show" type="bool" value="true"/>
|
||||
</property>
|
||||
</channel>
|
||||
@@ -7,15 +7,14 @@
|
||||
<property name="dark-mode" type="bool" value="true"/>
|
||||
<property name="panel-1" type="empty">
|
||||
<property name="position" type="string" value="p=6;x=0;y=0"/>
|
||||
<property name="length" type="uint" value="100"/>
|
||||
<property name="length" type="double" value="100"/>
|
||||
<property name="position-locked" type="bool" value="true"/>
|
||||
<property name="icon-size" type="uint" value="16"/>
|
||||
<property name="size" type="uint" value="26"/>
|
||||
<property name="icon-size" type="uint" value="36"/>
|
||||
<property name="size" type="uint" value="40"/>
|
||||
<property name="plugin-ids" type="array">
|
||||
<value type="int" value="1"/>
|
||||
<value type="int" value="2"/>
|
||||
<value type="int" value="3"/>
|
||||
<value type="int" value="4"/>
|
||||
<value type="int" value="5"/>
|
||||
<value type="int" value="6"/>
|
||||
<value type="int" value="8"/>
|
||||
@@ -23,13 +22,17 @@
|
||||
<value type="int" value="11"/>
|
||||
<value type="int" value="12"/>
|
||||
<value type="int" value="13"/>
|
||||
<value type="int" value="14"/>
|
||||
</property>
|
||||
<property name="background-style" type="uint" value="0"/>
|
||||
<property name="mode" type="uint" value="0"/>
|
||||
<property name="autohide-behavior" type="uint" value="0"/>
|
||||
<property name="nrows" type="uint" value="1"/>
|
||||
</property>
|
||||
</property>
|
||||
<property name="plugins" type="empty">
|
||||
<property name="plugin-1" type="string" value="applicationsmenu"/>
|
||||
<property name="plugin-1" type="string" value="applicationsmenu">
|
||||
<property name="button-icon" type="string" value="steam-headless"/>
|
||||
</property>
|
||||
<property name="plugin-2" type="string" value="tasklist">
|
||||
<property name="grouping" type="uint" value="1"/>
|
||||
</property>
|
||||
@@ -37,7 +40,6 @@
|
||||
<property name="expand" type="bool" value="true"/>
|
||||
<property name="style" type="uint" value="0"/>
|
||||
</property>
|
||||
<property name="plugin-4" type="string" value="pager"/>
|
||||
<property name="plugin-5" type="string" value="separator">
|
||||
<property name="style" type="uint" value="0"/>
|
||||
</property>
|
||||
@@ -53,10 +55,11 @@
|
||||
<property name="plugin-11" type="string" value="separator">
|
||||
<property name="style" type="uint" value="0"/>
|
||||
</property>
|
||||
<property name="plugin-12" type="string" value="clock"/>
|
||||
<property name="plugin-12" type="string" value="clock">
|
||||
<property name="mode" type="uint" value="2"/>
|
||||
</property>
|
||||
<property name="plugin-13" type="string" value="separator">
|
||||
<property name="style" type="uint" value="0"/>
|
||||
</property>
|
||||
<property name="plugin-14" type="string" value="actions"/>
|
||||
</property>
|
||||
</channel>
|
||||
@@ -0,0 +1,92 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<channel name="xfwm4" version="1.0">
|
||||
<property name="general" type="empty">
|
||||
<property name="activate_action" type="string" value="bring"/>
|
||||
<property name="borderless_maximize" type="bool" value="true"/>
|
||||
<property name="box_move" type="bool" value="false"/>
|
||||
<property name="box_resize" type="bool" value="false"/>
|
||||
<property name="button_layout" type="string" value="O|SHMC"/>
|
||||
<property name="button_offset" type="int" value="0"/>
|
||||
<property name="button_spacing" type="int" value="0"/>
|
||||
<property name="click_to_focus" type="bool" value="true"/>
|
||||
<property name="cycle_apps_only" type="bool" value="false"/>
|
||||
<property name="cycle_draw_frame" type="bool" value="true"/>
|
||||
<property name="cycle_raise" type="bool" value="false"/>
|
||||
<property name="cycle_hidden" type="bool" value="true"/>
|
||||
<property name="cycle_minimum" type="bool" value="true"/>
|
||||
<property name="cycle_minimized" type="bool" value="false"/>
|
||||
<property name="cycle_preview" type="bool" value="true"/>
|
||||
<property name="cycle_tabwin_mode" type="int" value="0"/>
|
||||
<property name="cycle_workspaces" type="bool" value="false"/>
|
||||
<property name="double_click_action" type="string" value="maximize"/>
|
||||
<property name="double_click_distance" type="int" value="5"/>
|
||||
<property name="double_click_time" type="int" value="250"/>
|
||||
<property name="easy_click" type="string" value="Alt"/>
|
||||
<property name="focus_delay" type="int" value="250"/>
|
||||
<property name="focus_hint" type="bool" value="true"/>
|
||||
<property name="focus_new" type="bool" value="true"/>
|
||||
<property name="frame_opacity" type="int" value="100"/>
|
||||
<property name="frame_border_top" type="int" value="0"/>
|
||||
<property name="full_width_title" type="bool" value="true"/>
|
||||
<property name="horiz_scroll_opacity" type="bool" value="false"/>
|
||||
<property name="inactive_opacity" type="int" value="100"/>
|
||||
<property name="maximized_offset" type="int" value="0"/>
|
||||
<property name="mousewheel_rollup" type="bool" value="true"/>
|
||||
<property name="move_opacity" type="int" value="100"/>
|
||||
<property name="placement_mode" type="string" value="center"/>
|
||||
<property name="placement_ratio" type="int" value="20"/>
|
||||
<property name="popup_opacity" type="int" value="100"/>
|
||||
<property name="prevent_focus_stealing" type="bool" value="false"/>
|
||||
<property name="raise_delay" type="int" value="250"/>
|
||||
<property name="raise_on_click" type="bool" value="true"/>
|
||||
<property name="raise_on_focus" type="bool" value="false"/>
|
||||
<property name="raise_with_any_button" type="bool" value="true"/>
|
||||
<property name="repeat_urgent_blink" type="bool" value="false"/>
|
||||
<property name="resize_opacity" type="int" value="100"/>
|
||||
<property name="scroll_workspaces" type="bool" value="false"/>
|
||||
<property name="shadow_delta_height" type="int" value="0"/>
|
||||
<property name="shadow_delta_width" type="int" value="0"/>
|
||||
<property name="shadow_delta_x" type="int" value="0"/>
|
||||
<property name="shadow_delta_y" type="int" value="-3"/>
|
||||
<property name="shadow_opacity" type="int" value="50"/>
|
||||
<property name="show_app_icon" type="bool" value="false"/>
|
||||
<property name="show_dock_shadow" type="bool" value="true"/>
|
||||
<property name="show_frame_shadow" type="bool" value="true"/>
|
||||
<property name="show_popup_shadow" type="bool" value="false"/>
|
||||
<property name="snap_resist" type="bool" value="false"/>
|
||||
<property name="snap_to_border" type="bool" value="true"/>
|
||||
<property name="snap_to_windows" type="bool" value="false"/>
|
||||
<property name="snap_width" type="int" value="10"/>
|
||||
<property name="vblank_mode" type="string" value="auto"/>
|
||||
<property name="theme" type="string" value="Default-xhdpi"/>
|
||||
<property name="tile_on_move" type="bool" value="true"/>
|
||||
<property name="title_alignment" type="string" value="center"/>
|
||||
<property name="title_font" type="string" value="Sans Bold 9"/>
|
||||
<property name="title_horizontal_offset" type="int" value="0"/>
|
||||
<property name="titleless_maximize" type="bool" value="false"/>
|
||||
<property name="title_shadow_active" type="string" value="false"/>
|
||||
<property name="title_shadow_inactive" type="string" value="false"/>
|
||||
<property name="title_vertical_offset_active" type="int" value="0"/>
|
||||
<property name="title_vertical_offset_inactive" type="int" value="0"/>
|
||||
<property name="toggle_workspaces" type="bool" value="false"/>
|
||||
<property name="unredirect_overlays" type="bool" value="true"/>
|
||||
<property name="urgent_blink" type="bool" value="false"/>
|
||||
<property name="use_compositing" type="bool" value="true"/>
|
||||
<property name="workspace_count" type="int" value="1"/>
|
||||
<property name="wrap_cycle" type="bool" value="false"/>
|
||||
<property name="wrap_layout" type="bool" value="false"/>
|
||||
<property name="wrap_resistance" type="int" value="10"/>
|
||||
<property name="wrap_windows" type="bool" value="false"/>
|
||||
<property name="wrap_workspaces" type="bool" value="false"/>
|
||||
<property name="zoom_desktop" type="bool" value="true"/>
|
||||
<property name="zoom_pointer" type="bool" value="true"/>
|
||||
<property name="workspace_names" type="array">
|
||||
<value type="string" value="Workspace 1"/>
|
||||
<value type="string" value="Workspace 2"/>
|
||||
<value type="string" value="Workspace 3"/>
|
||||
<value type="string" value="Workspace 4"/>
|
||||
</property>
|
||||
<property name="margin_top" type="int" value="0"/>
|
||||
</property>
|
||||
</channel>
|
||||
@@ -14,7 +14,7 @@
|
||||
<property name="EnableInputFeedbackSounds" type="empty"/>
|
||||
</property>
|
||||
<property name="Xft" type="empty">
|
||||
<property name="DPI" type="empty"/>
|
||||
<property name="DPI" type="int" value="110"/>
|
||||
<property name="Antialias" type="empty"/>
|
||||
<property name="Hinting" type="empty"/>
|
||||
<property name="HintStyle" type="empty"/>
|
||||
@@ -32,7 +32,7 @@
|
||||
<property name="MenuImages" type="empty"/>
|
||||
<property name="ButtonImages" type="empty"/>
|
||||
<property name="MenuBarAccel" type="empty"/>
|
||||
<property name="CursorThemeName" type="empty"/>
|
||||
<property name="CursorThemeName" type="string" value="default"/>
|
||||
<property name="CursorThemeSize" type="empty"/>
|
||||
<property name="DecorationLayout" type="empty"/>
|
||||
<property name="DialogsUseHeader" type="empty"/>
|
||||
@@ -41,4 +41,8 @@
|
||||
<property name="Gdk" type="empty">
|
||||
<property name="WindowScalingFactor" type="empty"/>
|
||||
</property>
|
||||
<property name="Xfce" type="empty">
|
||||
<property name="LastCustomDPI" type="int" value="110"/>
|
||||
<property name="SyncThemes" type="bool" value="true"/>
|
||||
</property>
|
||||
</channel>
|
||||
@@ -0,0 +1,10 @@
|
||||
[Desktop Entry]
|
||||
NoDisplay=true
|
||||
Version=1.0
|
||||
Encoding=UTF-8
|
||||
Type=X-XFCE-Helper
|
||||
X-XFCE-Category=WebBrowser
|
||||
X-XFCE-CommandsWithParameter=/home/default/.local/share/flatpak/exports/bin/org.mozilla.firefox "%s"
|
||||
Icon=org.mozilla.firefox
|
||||
Name=org.mozilla.firefox
|
||||
X-XFCE-Commands=/home/default/.local/share/flatpak/exports/bin/org.mozilla.firefox
|
||||
@@ -3,12 +3,36 @@
|
||||
"PATH": "$(PATH):$(HOME)\/.local\/bin"
|
||||
},
|
||||
"apps": [
|
||||
{
|
||||
"name": "Desktop",
|
||||
"image-path": "desktop.png",
|
||||
"exclude-global-prep-cmd": "true"
|
||||
},
|
||||
{
|
||||
"name": "Steam Big Picture",
|
||||
"output": "steam.txt",
|
||||
"cmd": "",
|
||||
"image-path": "steam.png",
|
||||
"exclude-global-prep-cmd": "true",
|
||||
"detached": [
|
||||
"\/usr\/games\/steam steam:\/\/open\/bigpicture"
|
||||
"\/usr\/games\/steam steam:\/\/open\/bigpicture",
|
||||
"\/usr\/bin\/sunshine-run sleep infinity"
|
||||
],
|
||||
"prep-cmd": [
|
||||
{
|
||||
"do": "",
|
||||
"undo": "sh -c \"sleep 5 && pkill -f -2 \/usr\/bin\/sunshine\""
|
||||
},
|
||||
{
|
||||
"do": "",
|
||||
"undo": "\/usr\/bin\/sunshine-stop"
|
||||
},
|
||||
{
|
||||
"do": "",
|
||||
"undo": "\/usr\/bin\/xfce4-close-all-windows"
|
||||
},
|
||||
{
|
||||
"do": "",
|
||||
"undo": "\/usr\/games\/steam steam:\/\/close\/bigpicture"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -28,6 +28,10 @@
|
||||
#
|
||||
min_log_level = info
|
||||
|
||||
# A list of commands to be run before/after all applications.
|
||||
# If any of the prep-commands fail, starting the application is aborted.
|
||||
global_prep_cmd = [{"do":"/usr/bin/xfce4-minimise-all-windows","undo":"/usr/bin/sunshine-stop"}]
|
||||
|
||||
# The origin of the remote endpoint address that is not denied for HTTP method /pin
|
||||
# Could be any of the following values:
|
||||
# pc|lan|wan
|
||||
@@ -95,7 +99,7 @@ min_log_level = info
|
||||
# ping_timeout = 10000
|
||||
|
||||
# The file where configuration for the different applications that Sunshine can run during a stream
|
||||
file_apps = /home/default/sunshine/apps.json
|
||||
file_apps = apps.json
|
||||
|
||||
# Percentage of error correcting packets per data packet in each video frame
|
||||
# Higher values can correct for more network packet loss, but at the cost of increasing bandwidth usage
|
||||
@@ -111,7 +115,7 @@ file_apps = /home/default/sunshine/apps.json
|
||||
#
|
||||
# Unlike simply broadcasting to multiple Client, this will generate distinct video streams.
|
||||
# Note, CPU usage increases for each distinct video stream generated
|
||||
# channels = 1
|
||||
channels = 2
|
||||
|
||||
# The back/select button on the controller
|
||||
# On the Shield, the home and powerbutton are not passed to Moonlight
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
Section "Device"
|
||||
Identifier "Configured Video Device"
|
||||
Driver "dummy"
|
||||
VideoRam 256000
|
||||
EndSection
|
||||
|
||||
Section "Monitor"
|
||||
Identifier "Configured Monitor"
|
||||
HorizSync 31.5-48.5
|
||||
VertRefresh 50-70
|
||||
HorizSync 5.0 - 1000.0
|
||||
VertRefresh 5.0 - 200.0
|
||||
ModeLine "1920x1080" 148.50 1920 2448 2492 2640 1080 1084 1089 1125 +Hsync +Vsync
|
||||
EndSection
|
||||
|
||||
Section "Screen"
|
||||
@@ -16,6 +18,6 @@ Section "Screen"
|
||||
DefaultDepth 24
|
||||
SubSection "Display"
|
||||
Depth 24
|
||||
Modes "1600x900"
|
||||
Modes "1920x1080" "1280x800" "1024x768" "1920x1080" "1600x900" "1440x900"
|
||||
EndSubSection
|
||||
EndSection
|
||||
|
||||
@@ -28,7 +28,7 @@ wait_for_x() {
|
||||
wait_for_udev() {
|
||||
MAX=10
|
||||
CT=0
|
||||
while [ ! -f /tmp/.udev-started ]; do
|
||||
while [ ! -e /run/udev/control ]; do
|
||||
sleep 1
|
||||
CT=$(( CT + 1 ))
|
||||
if [ "$CT" -ge "$MAX" ]; then
|
||||
@@ -53,6 +53,20 @@ wait_for_docker() {
|
||||
echo "DOCKERD RUNNING!"
|
||||
}
|
||||
|
||||
# Wait for desktop to start
|
||||
wait_for_desktop() {
|
||||
MAX=30
|
||||
CT=0
|
||||
while [ ! -f /tmp/.started-desktop ]; do
|
||||
sleep 1
|
||||
CT=$(( CT + 1 ))
|
||||
if [ "$CT" -ge "$MAX" ]; then
|
||||
echo "FATAL: $0: Gave up waiting for Desktop to start"
|
||||
exit 11
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# Fech NVIDIA GPU device (if one exists)
|
||||
get_nvidia_gpu_id() {
|
||||
if [ "${NVIDIA_VISIBLE_DEVICES:-}" == "all" ]; then
|
||||
@@ -67,3 +81,24 @@ get_nvidia_gpu_id() {
|
||||
fi
|
||||
echo ${gpu_select}
|
||||
}
|
||||
|
||||
export_desktop_dbus_session() {
|
||||
if [ ! -f /tmp/.dbus-desktop-session.env ]; then
|
||||
echo "$(dbus-launch)" > /tmp/.dbus-desktop-session.env
|
||||
fi
|
||||
export $(cat /tmp/.dbus-desktop-session.env)
|
||||
}
|
||||
|
||||
# Wait for desktop dbus session to start
|
||||
wait_for_desktop_dbus_session() {
|
||||
MAX=10
|
||||
CT=0
|
||||
while [ ! -f /tmp/.dbus-desktop-session.env ]; do
|
||||
sleep 1
|
||||
CT=$(( CT + 1 ))
|
||||
if [ "$CT" -ge "$MAX" ]; then
|
||||
echo "FATAL: $0: Gave up waiting for Desktop dbus-launch session to be created"
|
||||
exit 11
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
@@ -4,12 +4,11 @@ echo "**** Installing/upgrading Firefox via flatpak ****"
|
||||
|
||||
# Install Firefox
|
||||
flatpak --user remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
|
||||
flatpak --user install --assumeyes --noninteractive --or-update flathub org.mozilla.firefox
|
||||
flatpak --user install --assumeyes --or-update flathub org.mozilla.firefox
|
||||
|
||||
# Configure Firefox as the default browser
|
||||
echo "Configure Firefox..."
|
||||
custom_webbrowser="$(cat <<EOF
|
||||
"libraryfolders"
|
||||
[Desktop Entry]
|
||||
NoDisplay=true
|
||||
Version=1.0
|
||||
@@ -22,9 +21,9 @@ Name=org.mozilla.firefox
|
||||
X-XFCE-Commands=${USER_HOME:?}/.local/share/flatpak/exports/bin/org.mozilla.firefox
|
||||
EOF
|
||||
)"
|
||||
if [[ ! -f ${USER_HOME:?}/.local/share/xfce4/helpers/custom-WebBrowser.desktop ]]; then
|
||||
mkdir -p ${USER_HOME:?}/.local/share/xfce4/helpers
|
||||
echo "${custom_webbrowser}" > ${USER_HOME:?}/.local/share/xfce4/helpers/custom-WebBrowser.desktop
|
||||
if [[ ! -f "${USER_HOME:?}/.local/share/xfce4/helpers/custom-WebBrowser.desktop" ]]; then
|
||||
mkdir -p "${USER_HOME:?}/.local/share/xfce4/helpers"
|
||||
echo "${custom_webbrowser}" > "${USER_HOME:?}/.local/share/xfce4/helpers/custom-WebBrowser.desktop"
|
||||
gio mime x-scheme-handler/http org.mozilla.firefox.desktop
|
||||
fi
|
||||
|
||||
14
overlay/usr/bin/install_flatseal.sh
Executable file
14
overlay/usr/bin/install_flatseal.sh
Executable file
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
echo "**** Installing/upgrading Flatseal via flatpak ****"
|
||||
|
||||
# Install Flatseal
|
||||
flatpak --user remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
|
||||
flatpak --user install --assumeyes --or-update com.github.tchx84.Flatseal
|
||||
|
||||
# Configure Flatseal
|
||||
echo "Configure Flatseal..."
|
||||
sed -i 's/^Categories=.*$/Categories=Utility;/' \
|
||||
${USER_HOME}/.local/share/flatpak/exports/share/applications/com.github.tchx84.Flatseal.desktop
|
||||
|
||||
echo "DONE"
|
||||
@@ -4,9 +4,9 @@ echo "**** Installing/upgrading ProtonUp-Qt via flatpak ****"
|
||||
|
||||
# Install ProtonUp-Qt
|
||||
flatpak --user remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
|
||||
flatpak --user install --assumeyes --noninteractive --or-update net.davidotek.pupgui2
|
||||
flatpak --user install --assumeyes --or-update net.davidotek.pupgui2
|
||||
|
||||
# Configure Firefox as the default browser
|
||||
# Configure ProtonUp-Qt
|
||||
echo "Configure ProtonUp-Qt..."
|
||||
sed -i 's/^Categories=.*$/Categories=Utility;/' \
|
||||
${USER_HOME}/.local/share/flatpak/exports/share/applications/net.davidotek.pupgui2.desktop
|
||||
35
overlay/usr/bin/set-custom-res.sh
Executable file
35
overlay/usr/bin/set-custom-res.sh
Executable file
@@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
###
|
||||
# File: set-custom-res.sh
|
||||
# Project: bin
|
||||
# Author: LyzardByte Community Docs
|
||||
###
|
||||
|
||||
# Get params and set any defaults
|
||||
width=${1:-1920}
|
||||
height=${2:-1080}
|
||||
refresh_rate=${3:-60}
|
||||
|
||||
# You may need to adjust the scaling differently so the UI/Text isn't too small / big
|
||||
scale=${4:-1}
|
||||
|
||||
# Get the name of the active display
|
||||
display_output=$(xrandr | grep " connected" | awk '{print $1 }')
|
||||
|
||||
# Get the modeline info from the 2nd row in the cvt output
|
||||
modeline=$(cvt ${width} ${height} ${refresh_rate} | awk 'FNR == 2')
|
||||
xrandr_mode_str=${modeline//Modeline \"*\" /}
|
||||
mode_alias="${width}x${height}"
|
||||
|
||||
echo "xrandr setting new mode ${mode_alias} ${xrandr_mode_str}"
|
||||
xrandr --newmode ${mode_alias} ${xrandr_mode_str}
|
||||
xrandr --addmode ${display_output} ${mode_alias}
|
||||
|
||||
# Reset Scaling
|
||||
xrandr --output ${display_output} --scale ${scale}
|
||||
|
||||
# Apply new xrandr mode
|
||||
xrandr --output ${display_output} --primary --mode ${mode_alias} --pos 0x0 --rotate normal --scale ${scale}
|
||||
|
||||
# Optionally reset your wallpaper
|
||||
# xwallpaper --zoom /path/to/wallpaper.png
|
||||
@@ -5,7 +5,7 @@
|
||||
# File Created: Thursday, 1st January 1970 12:00:00 pm
|
||||
# Author: Console and webGui login account (jsunnex@gmail.com)
|
||||
# -----
|
||||
# Last Modified: Saturday, 8th July 2023 2:34:11 am
|
||||
# Last Modified: Saturday, 8th July 2023 6:16:47 pm
|
||||
# Modified By: Console and webGui login account (jsunnex@gmail.com)
|
||||
###
|
||||
set -e
|
||||
@@ -19,24 +19,35 @@ trap _term SIGTERM SIGINT
|
||||
|
||||
|
||||
# CONFIGURE:
|
||||
export $(dbus-launch)
|
||||
|
||||
# Remove lockfile
|
||||
rm -f /tmp/.started-desktop
|
||||
# Start a session bus instance of dbus-daemon
|
||||
# Note: This script should be the only one that waits for X after exporting this dbus session
|
||||
rm -fv /tmp/.dbus-desktop-session.env
|
||||
export_desktop_dbus_session
|
||||
# Configure some XDG environment variables
|
||||
export XDG_CACHE_HOME="${USER_HOME:?}/.cache"
|
||||
export XDG_CONFIG_HOME="${USER_HOME:?}/.config"
|
||||
export XDG_DATA_HOME="${USER_HOME:?}/.local/share"
|
||||
|
||||
# EXECUTE PROCESS:
|
||||
# Install/Upgrade user apps
|
||||
if [[ ! -f /tmp/.desktop-apps-updated.lock ]]; then
|
||||
source /opt/scripts/install_steam.sh
|
||||
source /opt/scripts/install_firefox.sh
|
||||
source /opt/scripts/install_protonup.sh
|
||||
touch /tmp/.desktop-apps-updated.lock
|
||||
fi
|
||||
# Wait for the X server to start
|
||||
wait_for_x
|
||||
# Install/Upgrade user apps
|
||||
if [[ ! -f /tmp/.desktop-apps-updated ]]; then
|
||||
xterm -geometry 200x50+0+0 -ls -e /bin/bash -c "
|
||||
source /usr/bin/install_firefox.sh;
|
||||
source /usr/bin/install_protonup.sh;
|
||||
sleep 1;
|
||||
"
|
||||
touch /tmp/.desktop-apps-updated
|
||||
fi
|
||||
|
||||
# Run the desktop environment
|
||||
echo "**** Starting Xfce4 ****"
|
||||
/usr/bin/startxfce4 &
|
||||
desktop_pid=$!
|
||||
|
||||
touch /tmp/.started-desktop
|
||||
|
||||
# WAIT FOR CHILD PROCESS:
|
||||
wait "$desktop_pid"
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
###
|
||||
# File: start-dind.sh
|
||||
# Project: bin
|
||||
# File Created: Saturday, 8th October 2022 1:49:45 pm
|
||||
# Author: Josh.5 (jsunnex@gmail.com)
|
||||
# -----
|
||||
# Last Modified: Saturday, 8th October 2022 1:49:45 pm
|
||||
# Modified By: Josh.5 (jsunnex@gmail.com)
|
||||
###
|
||||
set -e
|
||||
|
||||
|
||||
# CATCH TERM SIGNAL:
|
||||
_term() {
|
||||
kill -TERM "$docker_pid" 2>/dev/null
|
||||
}
|
||||
trap _term SIGTERM SIGINT
|
||||
|
||||
|
||||
# CONFIGURE:
|
||||
# Refrences:
|
||||
# - https://raw.githubusercontent.com/docker/docker/42b1175eda071c0e9121e1d64345928384a93df1/hack/dind
|
||||
#
|
||||
# apparmor sucks and Docker needs to know that it's in a container (c) @tianon
|
||||
export container=docker
|
||||
if [ -d /sys/kernel/security ] && ! mountpoint -q /sys/kernel/security; then
|
||||
mount -t securityfs none /sys/kernel/security || {
|
||||
echo >&2 'Could not mount /sys/kernel/security.'
|
||||
echo >&2 'AppArmor detection and --privileged mode might break.'
|
||||
}
|
||||
fi
|
||||
# cgroup v2: enable nesting
|
||||
if [ -f /sys/fs/cgroup/cgroup.controllers ]; then
|
||||
# move the processes from the root group to the /init group,
|
||||
# otherwise writing subtree_control fails with EBUSY.
|
||||
# An error during moving non-existent process (i.e., "cat") is ignored.
|
||||
mkdir -p /sys/fs/cgroup/init
|
||||
xargs -rn1 < /sys/fs/cgroup/cgroup.procs > /sys/fs/cgroup/init/cgroup.procs || :
|
||||
# enable controllers
|
||||
sed -e 's/ / +/g' -e 's/^/+/' < /sys/fs/cgroup/cgroup.controllers \
|
||||
> /sys/fs/cgroup/cgroup.subtree_control
|
||||
fi
|
||||
|
||||
|
||||
# EXECUTE PROCESS:
|
||||
/usr/local/bin/dockerd &
|
||||
docker_pid=$!
|
||||
|
||||
|
||||
# WAIT FOR CHILD PROCESS:
|
||||
wait "$docker_pid"
|
||||
26
overlay/usr/bin/start-dumb-udev.sh
Executable file
26
overlay/usr/bin/start-dumb-udev.sh
Executable file
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env bash
|
||||
###
|
||||
# File: start-dumb-udev.sh
|
||||
# Project: bin
|
||||
# File Created: Tuesday, 12th January 2022 8:46:47 am
|
||||
# Author: Josh.5 (jsunnex@gmail.com)
|
||||
# -----
|
||||
# Last Modified: Friday, 14th January 2022 9:21:00 am
|
||||
# Modified By: Josh.5 (jsunnex@gmail.com)
|
||||
###
|
||||
set -e
|
||||
|
||||
# CATCH TERM SIGNAL:
|
||||
_term() {
|
||||
kill -TERM "$dumb_udev_pid" 2>/dev/null
|
||||
}
|
||||
trap _term SIGTERM SIGINT
|
||||
|
||||
|
||||
# EXECUTE PROCESS:
|
||||
# Start dumb-udev
|
||||
dumb-udev &
|
||||
dumb_udev_pid=$!
|
||||
|
||||
# WAIT FOR CHILD PROCESS:
|
||||
wait "$dumb_udev_pid"
|
||||
@@ -1,45 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
###
|
||||
# File: start-kasmvnc.sh
|
||||
# Project: bin
|
||||
# File Created: Thursday, 1st January 1970 12:00:00 pm
|
||||
# Author: Console and webGui login account (jsunnex@gmail.com)
|
||||
# -----
|
||||
# Last Modified: Saturday, 8th July 2023 4:44:25 am
|
||||
# Modified By: Console and webGui login account (jsunnex@gmail.com)
|
||||
###
|
||||
set -e
|
||||
source /usr/bin/common-functions.sh
|
||||
|
||||
# CATCH TERM SIGNAL:
|
||||
_term() {
|
||||
kill -TERM "$kasmxproxy_pid" 2>/dev/null
|
||||
pkill --signal TERM -P "$xvnc_pid" 2>/dev/null
|
||||
}
|
||||
trap _term SIGTERM SIGINT
|
||||
|
||||
|
||||
# EXECUTE PROCESS:
|
||||
# Wait for the X server to start
|
||||
wait_for_x
|
||||
# Start the Xvnc server
|
||||
# vncserver :88 -fg -noxstartup -websocketPort ${PORT_NOVNC_WEB:?} -disableBasicAuth -interface 0.0.0.0 -dry-run
|
||||
#eval "$(vncserver :88 -fg -noxstartup -websocketPort ${PORT_NOVNC_WEB:?} -disableBasicAuth -interface 0.0.0.0 -dry-run)" &
|
||||
## xvnc_command="$(vncserver :88 -fg -noxstartup -websocketPort 8438 -disableBasicAuth -interface 0.0.0.0 -dry-run)"
|
||||
## bash -c "${xvnc_command}" &
|
||||
# NOTE: I've run it like this because the -fg is not doing anything when executed with vncserver.
|
||||
# This prints the Xvnc command which is then executed.
|
||||
vnc_server_args="${vnc_server_args:-} -hw3d -drinode /dev/dri/renderD128"
|
||||
|
||||
eval "$(vncserver :88 -fg -noxstartup -websocketPort ${PORT_NOVNC_WEB:?} -disableBasicAuth -interface 0.0.0.0 ${vnc_server_args:-} -dry-run)" &
|
||||
xvnc_pid=$!
|
||||
# Wait a few seconds for the Xvnc service to start
|
||||
sleep 3
|
||||
# Start the Kasm X Proxy
|
||||
kasmxproxy -a :55 -v :88 &
|
||||
kasmxproxy_pid=$!
|
||||
|
||||
|
||||
# WAIT FOR CHILD PROCESS:
|
||||
wait "$xvnc_pid"
|
||||
wait "$kasmxproxy_pid"
|
||||
@@ -19,7 +19,6 @@ trap _term SIGTERM SIGINT
|
||||
|
||||
# EXECUTE PROCESS:
|
||||
echo "PULSEAUDIO: Starting pulseaudio service"
|
||||
sleep 5
|
||||
#/usr/bin/pulseaudio --disallow-module-loading --disallow-exit --exit-idle-time=-1 &
|
||||
/usr/bin/pulseaudio --exit-idle-time=-1 &
|
||||
pulseaudio_pid=$!
|
||||
|
||||
@@ -5,50 +5,73 @@
|
||||
# File Created: Tuesday, 4th October 2022 8:22:17 pm
|
||||
# Author: Josh.5 (jsunnex@gmail.com)
|
||||
# -----
|
||||
# Last Modified: Tuesday, 4th October 2022 8:22:17 pm
|
||||
# Modified By: Josh.5 (jsunnex@gmail.com)
|
||||
# Last Modified: Wednesday, 27th November 2024 3:54:19 pm
|
||||
# Modified By: Josh5 (jsunnex@gmail.com)
|
||||
###
|
||||
set -e
|
||||
source /usr/bin/common-functions.sh
|
||||
|
||||
# CATCH TERM SIGNAL:
|
||||
_term() {
|
||||
kill -INT "$sunshine_pid" 2>/dev/null
|
||||
sleep 0.5
|
||||
counter=0
|
||||
while kill -0 "$sunshine_pid"; do
|
||||
kill -TERM "$sunshine_pid" 2>/dev/null
|
||||
counter=$((counter + 1))
|
||||
[ "$counter" -gt 8 ] && break
|
||||
sleep 0.5
|
||||
done
|
||||
counter=0
|
||||
while kill -0 "$sunshine_pid"; do
|
||||
kill -KILL "$sunshine_pid" 2>/dev/null
|
||||
counter=$((counter + 1))
|
||||
[ "$counter" -gt 4 ] && break
|
||||
sleep 0.5
|
||||
done
|
||||
}
|
||||
trap _term SIGTERM SIGINT
|
||||
|
||||
|
||||
# CONFIGURE:
|
||||
# Install default configurations
|
||||
mkdir -p /home/${USER}/sunshine
|
||||
if [[ ! -f /home/${USER}/sunshine/sunshine.conf ]]; then
|
||||
cp -vf /templates/sunshine/* /home/${USER}/sunshine/
|
||||
# TODO: Set the default encoder '# encoder = nvenc'
|
||||
# nvidia_gpu_id=$(get_nvidia_gpu_id)
|
||||
# if [[ "X${nvidia_gpu_id:-}" != "X" ]]; then
|
||||
# if [[ "all video" == *"${NVIDIA_DRIVER_CAPABILITIES}"* ]]; then
|
||||
# # Check if we have a nvidia GPU available
|
||||
# sed -i 's|^# encoder.*=.*$|encoder = nvenc|' /home/${USER}/sunshine/sunshine.conf
|
||||
# fi
|
||||
# else
|
||||
# # TODO: Enable the vaapi device if not using nvenc
|
||||
# # vainfo --display drm --device /dev/dri/renderD128 2> /dev/null | grep -E "((VAProfileH264High|VAProfileHEVCMain|VAProfileHEVCMain10).*VAEntrypointEncSlice)"
|
||||
# # Loop over any render devices
|
||||
# echo
|
||||
# fi
|
||||
mkdir -p "${USER_HOME:?}/.config/sunshine"
|
||||
if [ ! -f "${USER_HOME:?}/.config/sunshine/sunshine.conf" ]; then
|
||||
cp -vf /templates/sunshine/sunshine.conf "${USER_HOME:?}/.config/sunshine/sunshine.conf"
|
||||
fi
|
||||
if [ ! -f "${USER_HOME:?}/.config/sunshine/apps.json" ]; then
|
||||
cp -vf /templates/sunshine/apps.json "${USER_HOME:?}/.config/sunshine/apps.json"
|
||||
fi
|
||||
if [ ! -f "${USER_HOME:?}/.config/sunshine/sunshine_state.json" ]; then
|
||||
echo "{}" > "${USER_HOME:?}/.config/sunshine/sunshine_state.json"
|
||||
fi
|
||||
|
||||
# Reset the default username/password
|
||||
if ([ "X${SUNSHINE_USER:-}" != "X" ] && [ "X${SUNSHINE_PASS:-}" != "X" ]); then
|
||||
sunshine /home/${USER}/sunshine/sunshine.conf --creds ${SUNSHINE_USER:-} ${SUNSHINE_PASS:-}
|
||||
/usr/bin/sunshine "${USER_HOME:?}/.config/sunshine/sunshine.conf" --creds "${SUNSHINE_USER:?}" "${SUNSHINE_PASS:?}"
|
||||
fi
|
||||
# If we are running the SHUI, then force the same user upon sunshine
|
||||
if ([ "X${WEBUI_USER:-}" != "X" ] && [ "X${WEBUI_PASS:-}" != "X" ]); then
|
||||
/usr/bin/sunshine "${USER_HOME:?}/.config/sunshine/sunshine.conf" --creds "${WEBUI_USER:?}" "${WEBUI_PASS:?}"
|
||||
fi
|
||||
# Remove any auto-start scripts from user's .local dir
|
||||
if [ -f "${USER_HOME:?}/.config/autostart/Sunshine.desktop" ]; then
|
||||
rm -fv "${USER_HOME:?}/.config/autostart/Sunshine.desktop"
|
||||
fi
|
||||
|
||||
|
||||
# EXECUTE PROCESS:
|
||||
# Wait for the X server to start
|
||||
wait_for_x
|
||||
|
||||
# Start a session bus instance of dbus-daemon
|
||||
wait_for_desktop_dbus_session
|
||||
export_desktop_dbus_session
|
||||
|
||||
# Wait for the desktop to start
|
||||
wait_for_desktop
|
||||
|
||||
# Start the sunshine server
|
||||
sunshine /home/${USER}/sunshine/sunshine.conf &
|
||||
/usr/bin/dumb-init /usr/bin/sunshine "${USER_HOME:?}/.config/sunshine/sunshine.conf" &
|
||||
sunshine_pid=$!
|
||||
|
||||
|
||||
|
||||
@@ -16,10 +16,7 @@ _term() {
|
||||
}
|
||||
trap _term SIGTERM SIGINT
|
||||
|
||||
|
||||
# EXECUTE PROCESS:
|
||||
# Remove lockfile
|
||||
rm -f /tmp/.udev-started
|
||||
# Start udev
|
||||
if command -v udevd &>/dev/null; then
|
||||
unshare --net udevd --daemon &>/dev/null
|
||||
@@ -29,11 +26,8 @@ fi
|
||||
# Monitor kernel uevents
|
||||
udevadm monitor &
|
||||
monitor_pid=$!
|
||||
# Touch lockfile
|
||||
sleep 1
|
||||
touch /tmp/.udev-started
|
||||
# Wait for 10 seconds, then request device events from the kernel
|
||||
sleep 10
|
||||
# Wait for 5 seconds, then request device events from the kernel
|
||||
sleep 5
|
||||
udevadm trigger
|
||||
|
||||
# WAIT FOR CHILD PROCESS:
|
||||
|
||||
@@ -20,7 +20,9 @@ trap _term SIGTERM SIGINT
|
||||
|
||||
# EXECUTE PROCESS:
|
||||
# Wait for udev
|
||||
if [ $(grep autostart /etc/supervisor.d/udev.ini 2> /dev/null) == "autostart=true" ]; then
|
||||
wait_for_udev
|
||||
fi
|
||||
# Run X server
|
||||
/usr/bin/Xorg \
|
||||
-ac \
|
||||
|
||||
84
overlay/usr/bin/steam-headless-wol-power-manager
Executable file
84
overlay/usr/bin/steam-headless-wol-power-manager
Executable file
@@ -0,0 +1,84 @@
|
||||
#!/usr/bin/env bash
|
||||
###
|
||||
# File: steam-headless-wol-power-manager
|
||||
# Project: bin
|
||||
# File Created: Tuesday, 5th September 2023 5:35:38 pm
|
||||
# Author: Josh.5 (jsunnex@gmail.com)
|
||||
# -----
|
||||
# Last Modified: Tuesday, 5th September 2023 5:35:38 pm
|
||||
# Modified By: Josh.5 (jsunnex@gmail.com)
|
||||
###
|
||||
set -e
|
||||
|
||||
# Function to execute restart to WoL monitor
|
||||
restart_to_wol_monitor() {
|
||||
# Create WoL monitor lock file. This will be read during the next restart and will trigger a singluar WoL monitor service.
|
||||
touch /tmp/.wol-monitor
|
||||
|
||||
# Stop all processes inside the container by sending a SIGINT to the main supervisord process (PID 1)
|
||||
kill -2 1
|
||||
|
||||
# Exit script
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Function to execute restart to Desktop
|
||||
restart_to_desktop_mode() {
|
||||
# Remove WoL monitor lock file.
|
||||
rm -f /tmp/.wol-monitor
|
||||
|
||||
# Stop all processes inside the container by sending a SIGINT to the main supervisord process (PID 1)
|
||||
kill -2 1
|
||||
|
||||
# Exit script
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Function to monitor for no user input
|
||||
start_idle_monitor() {
|
||||
# Set the idle timeout in milliseconds (60 minutes = 3600000 milliseconds)
|
||||
local idle_timeout=3600000
|
||||
|
||||
# Monitor input. After an hour of no input
|
||||
echo "Starting idle inputs monitor service..."
|
||||
while true; do
|
||||
# Sleep for a short interval (e.g., 1 minute) before checking
|
||||
sleep 60
|
||||
|
||||
# Get the current idle time in milliseconds using xprintidle
|
||||
idle_time=$(xprintidle)
|
||||
|
||||
# Check if the idle time exceeds the specified timeout
|
||||
if [ "${idle_time:?}" -ge "${idle_timeout:?}" ]; then
|
||||
# TODO: Check if any sessions exist in sunshine
|
||||
|
||||
# Execute restart to WoL monitor function
|
||||
echo "No user activity for over 60 minutes. Entering WoL Monitor Mode."
|
||||
restart_to_wol_monitor
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# Function to monitor for WoL events
|
||||
start_wol_monitor() {
|
||||
# Specify port to listen to (9 is the default WoL port).
|
||||
listen_port=9
|
||||
|
||||
# Start the WoL monitor service
|
||||
echo "Starting WoL monitor service..."
|
||||
|
||||
while true; do
|
||||
# Listen for WoL magic packets on the specified port
|
||||
tcpdump -i any -n -l -c 1 -q "udp port $listen_port and (udp[8:4] = 0xFFFFFFFF)"
|
||||
|
||||
# Execute restart to desktop function
|
||||
echo "WoL event received. Entering Desktop Mode."
|
||||
restart_to_desktop_mode
|
||||
done
|
||||
}
|
||||
|
||||
if [ -f "/tmp/.wol-monitor" ]; then
|
||||
start_wol_monitor
|
||||
else
|
||||
start_idle_monitor
|
||||
fi
|
||||
163
overlay/usr/bin/sunshine-run
Executable file
163
overlay/usr/bin/sunshine-run
Executable file
@@ -0,0 +1,163 @@
|
||||
#!/usr/bin/env bash
|
||||
###
|
||||
# File: sunshine-run
|
||||
# Project: bin
|
||||
# File Created: Tuesday, 23rd August 2023 3:28:52 pm
|
||||
# Author: Josh.5 (jsunnex@gmail.com)
|
||||
# -----
|
||||
# Last Modified: Saturday, 20th July 2024 7:07:00 pm
|
||||
# Modified By: Josh5 (jsunnex@gmail.com)
|
||||
###
|
||||
set -e
|
||||
|
||||
exec >> >(tee -a ${USER_HOME:?}/.cache/log/sunshine_run.log) 2>&1
|
||||
echo
|
||||
echo "-------------------------------"
|
||||
echo
|
||||
date
|
||||
echo
|
||||
echo "-------------------------------"
|
||||
echo
|
||||
echo "**** Execute sunshine-run ****"
|
||||
echo
|
||||
|
||||
# Trap SIGINT, SIGQUIT, SIGHUP, SIGTERM to forward signals to the child process
|
||||
_term() {
|
||||
if [ -n "${proc_pid}" ]; then
|
||||
# Read all child processes of proc_pid first
|
||||
child_pids=$(pgrep -P $proc_pid)
|
||||
# Forward the signal proc_pid
|
||||
echo " - Checking for status of main process ${proc_pid}"
|
||||
if kill -0 "${proc_pid}" 2>/dev/null; then
|
||||
echo " - Forwarding signal $1 to process ${proc_pid}"
|
||||
kill -s "${1}" "${proc_pid}"
|
||||
else
|
||||
echo " - Process ${proc_pid} is already stopped. Nothing to do here."
|
||||
fi
|
||||
for child_pid in ${child_pids:-}; do
|
||||
echo " - Checking for status of child process ${child_pid}"
|
||||
if kill -0 "${child_pid}" 2>/dev/null; then
|
||||
echo " - Forwarding signal $1 to process ${child_pid}"
|
||||
kill -s "${1}" "${child_pid}"
|
||||
else
|
||||
echo " - Process ${child_pid} is already stopped. Nothing to do here."
|
||||
fi
|
||||
done
|
||||
fi
|
||||
}
|
||||
trap '_term INT' SIGINT
|
||||
trap '_term QUIT' SIGQUIT
|
||||
trap '_term HUP' SIGHUP
|
||||
trap '_term TERM' SIGTERM
|
||||
|
||||
# Record sunshine-run PID
|
||||
echo " - Recording sunshine-run PID '$$' in /tmp/sunshine-exec-run.pid"
|
||||
echo "$$" > /tmp/sunshine-exec-run.pid
|
||||
|
||||
# Wipe session config
|
||||
echo "" > /tmp/sunshine-exec-run.conf
|
||||
|
||||
# Update display resolution and refresh reate if client provided the required details
|
||||
if ([ "X${SUNSHINE_CLIENT_WIDTH:-}" != "X" ] && [ "X${SUNSHINE_CLIENT_HEIGHT:-}" != "X" ] && [ "X${SUNSHINE_CLIENT_FPS:-}" != "X" ]); then
|
||||
# Don't fail script if something goes wrong here. Set +e in subprocess
|
||||
(
|
||||
set +e
|
||||
echo " - Setting display resolution to ${SUNSHINE_CLIENT_WIDTH:?}x${SUNSHINE_CLIENT_HEIGHT:?} ${SUNSHINE_CLIENT_FPS:?}Hz"
|
||||
|
||||
# Read current display mode and extract resolution and refresh rate from the mode string
|
||||
__xrandr_out="$(xrandr -q)"
|
||||
__current_current_mode=$(echo "${__xrandr_out:?}" | awk '/\*/ {print $0}')
|
||||
__current_resolution=$(echo ${__current_current_mode:?} | awk '{print $1}')
|
||||
__current_refresh_rate=$(echo ${__current_current_mode:?} | awk '{sub(/\*/, "", $2); print $2}')
|
||||
|
||||
# Get the primary output device
|
||||
__primary_output="$(echo "${__xrandr_out:?}" | grep primary | head -n1 | awk '{print $1}')"
|
||||
if [ "X${__primary_output:-}" = "X" ]; then
|
||||
__primary_output="$(echo "${__xrandr_out:?}" | grep -E "\sconnected" | head -n1 | awk '{print $1}')"
|
||||
fi
|
||||
|
||||
if [ "X${__primary_output:-}" != "X" ]; then
|
||||
# Get the modeline from cvt and extract the second line (which contains the modeline)
|
||||
__client_modeline=$(cvt "${SUNSHINE_CLIENT_WIDTH:?}" "${SUNSHINE_CLIENT_HEIGHT:?}" "${SUNSHINE_CLIENT_FPS:?}" | grep Modeline | sed -e 's/Modeline //')
|
||||
# Create a new mode for this. This allows us to force a set refresh rate that may not be supported by the display
|
||||
__client_mode=$(echo "${__client_modeline:?}" | awk -F '"' '{print $2}')
|
||||
|
||||
# Check if this custom mode is already created
|
||||
if ! echo "${__xrandr_out:?}" | grep -q "${__client_mode:?}"; then
|
||||
# Custom mode does not yet exist. Create it
|
||||
echo " - Adding new mode '${__client_mode:?}' with new modeline '${__client_modeline:?}'"
|
||||
xrandr --newmode "${__client_mode:?}" ${__client_modeline##*\"}
|
||||
if [ $? -gt 0 ]; then
|
||||
echo " - WARNING: Failed to add new mode '${__client_mode:?}'."
|
||||
else
|
||||
echo " - SUCCESS"
|
||||
fi
|
||||
else
|
||||
echo " - Custom mode '${__client_mode:?}' already exists."
|
||||
fi
|
||||
# Check if custom mode exists
|
||||
__xrandr_out="$(xrandr -q)"
|
||||
if echo "${__xrandr_out:?}" | grep -q "${__client_mode:?}"; then
|
||||
# Check if this mode is already added to the primary display
|
||||
if ! echo "${__xrandr_out:?}" | sed -n "/${__primary_output:?}/,/^[^[:space:]]/ {/^[[:space:]]/p}" | grep -q "${__client_mode:?}"; then
|
||||
# Custom mode exists, but is not yet added to the primary output device. Add it
|
||||
echo " - Adding custom mode '${__client_mode:?}' to device '${__primary_output:?}'"
|
||||
xrandr --addmode "${__primary_output:?}" "${__client_mode:?}"
|
||||
__mode_added=$?
|
||||
if [ "${__mode_added:-0}" -gt 0 ]; then
|
||||
echo " - WARNING: Failed to assign custom mode to primary output device '${__primary_output:?}'."
|
||||
else
|
||||
echo " - SUCCESS"
|
||||
fi
|
||||
else
|
||||
echo " - Custom mode '${__client_mode:?}' is already configured for the primary output device."
|
||||
__mode_added=0
|
||||
fi
|
||||
else
|
||||
echo " - WARNING: Custom mode '${__client_mode:?}' does not exist."
|
||||
fi
|
||||
|
||||
# Set the current resoultion to the new mode
|
||||
if ([ "X${__mode_added:-}" = "X" ] || [ "${__mode_added:-0}" -gt 0 ]); then
|
||||
echo " - Attempting to set the display mode to a supported '${SUNSHINE_CLIENT_WIDTH:?}x${SUNSHINE_CLIENT_HEIGHT:?}' mode. Note that this may not support the configured refresh rate."
|
||||
xrandr --output "${__primary_output:?}" --mode ${SUNSHINE_CLIENT_WIDTH:?}x${SUNSHINE_CLIENT_HEIGHT:?} --refresh ${SUNSHINE_CLIENT_FPS:?}
|
||||
if [ $? -gt 0 ]; then
|
||||
echo " - WARNING: Failed to set current output to mode '${SUNSHINE_CLIENT_WIDTH:?}x${SUNSHINE_CLIENT_HEIGHT:?}' on device '${__primary_output:?}'."
|
||||
else
|
||||
echo " - SUCCESS"
|
||||
fi
|
||||
else
|
||||
echo " - Setting the display mode to '${__client_mode:?}'"
|
||||
xrandr --output "${__primary_output:?}" --mode "${__client_mode:?}" --rate "${SUNSHINE_CLIENT_FPS:?}"
|
||||
if [ $? -gt 0 ]; then
|
||||
echo " - WARNING: Failed to set current output to custom mode '${__client_mode:?}' on device '${__primary_output:?}'."
|
||||
else
|
||||
echo " - SUCCESS"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Save original display settings to config file. This will be read and used to restore the original display settings when the client disconnects.
|
||||
echo "primary_output='${__primary_output:?}'" >> /tmp/sunshine-exec-run.conf
|
||||
echo "display_mode='${__current_resolution:?}'" >> /tmp/sunshine-exec-run.conf
|
||||
echo "display_rate='${__current_refresh_rate:?}'" >> /tmp/sunshine-exec-run.conf
|
||||
fi
|
||||
)
|
||||
fi
|
||||
|
||||
# Run child process
|
||||
/usr/bin/dumb-init "${@}" &
|
||||
proc_pid=$!
|
||||
|
||||
# Wait for child process to exit:
|
||||
echo " - Waiting for PID '${proc_pid}' to exit"
|
||||
wait "$proc_pid"
|
||||
|
||||
# Clean up PID file
|
||||
if [ -f /tmp/sunshine-exec-run.pid ]; then
|
||||
echo " - Removing sunshine-run pidfile."
|
||||
rm -f /tmp/sunshine-exec-run.pid
|
||||
else
|
||||
echo " - WARNING: No sunshine-run pidfile found for removal."
|
||||
fi
|
||||
|
||||
echo "DONE"
|
||||
110
overlay/usr/bin/sunshine-stop
Executable file
110
overlay/usr/bin/sunshine-stop
Executable file
@@ -0,0 +1,110 @@
|
||||
#!/usr/bin/env bash
|
||||
###
|
||||
# File: sunshine-stop
|
||||
# Project: bin
|
||||
# File Created: Tuesday, 23rd August 2023 3:28:52 pm
|
||||
# Author: Josh.5 (jsunnex@gmail.com)
|
||||
# -----
|
||||
# Last Modified: Friday, 23rd August 2023 4:21:00 pm
|
||||
# Modified By: Josh.5 (jsunnex@gmail.com)
|
||||
###
|
||||
set -e
|
||||
|
||||
exec >> >(tee -a ${USER_HOME:?}/.cache/log/sunshine_stop.log) 2>&1
|
||||
echo
|
||||
echo "-------------------------------"
|
||||
echo
|
||||
date
|
||||
echo
|
||||
echo "-------------------------------"
|
||||
echo
|
||||
echo "**** Execute sunshine-stop ****"
|
||||
echo
|
||||
|
||||
# Read the run config
|
||||
if [ -f /tmp/sunshine-exec-run.conf ]; then
|
||||
echo " - Reading sunshine-run config."
|
||||
. /tmp/sunshine-exec-run.conf
|
||||
else
|
||||
echo " - WARNING: No sunshine-run config found for import."
|
||||
fi
|
||||
|
||||
# Read the process PID
|
||||
if [ -f /tmp/sunshine-exec-run.pid ]; then
|
||||
main_process_pid="$(cat /tmp/sunshine-exec-run.pid)"
|
||||
echo " - Found initial sunshine-run PID '${main_process_pid}'."
|
||||
else
|
||||
echo " - WARNING: No sunshine-run PID found."
|
||||
fi
|
||||
|
||||
# Send a INT signal to the PID (if it is found)
|
||||
if [ "X${main_process_pid:-}" != "X" ]; then
|
||||
echo " - Sending SIGINT to PID '${main_process_pid}'."
|
||||
kill -INT "${main_process_pid}" || true
|
||||
sleep 1
|
||||
fi
|
||||
|
||||
# Run a loop to check for any other "sunshine-run" processes and send them also a INT signal
|
||||
echo " - Checking for other sunshine-run processes..."
|
||||
for process_pid in $(ps aux | grep -v grep | grep sunshine-run | awk '{print $2}'); do
|
||||
# Ensure this process is still running
|
||||
if ! kill -0 "$process_pid" 2>/dev/null; then
|
||||
continue
|
||||
fi
|
||||
echo " - Stopping PID '${process_pid}' - $(ps -p ${process_pid} -o command | awk 'NR>1')"
|
||||
# Send this process a SIGINT
|
||||
echo " - Sending SIGINT to PID '${process_pid}'."
|
||||
kill -INT "${process_pid}" 2>/dev/null || true
|
||||
sleep 0.5
|
||||
# Send this process a SIGTERM every 2 seconds util stopped or until it has sent 3 signals
|
||||
counter=0
|
||||
while kill -0 "$process_pid" 2>/dev/null; do
|
||||
echo " - Sending SIGTERM to PID '${process_pid}'."
|
||||
kill -TERM "$process_pid" 2>/dev/null || true
|
||||
counter=$((counter + 1))
|
||||
[ "$counter" -gt 2 ] && break
|
||||
sleep 2
|
||||
done
|
||||
# Send this process a SIGKILL every second until stopped or until it has sent 3 signals
|
||||
counter=0
|
||||
while kill -0 "$process_pid" 2>/dev/null; do
|
||||
echo " - Sending SIGKILL to PID '${process_pid}'."
|
||||
kill -KILL "$process_pid" 2>/dev/null || true
|
||||
counter=$((counter + 1))
|
||||
[ "$counter" -gt 2 ] && break
|
||||
sleep 1
|
||||
done
|
||||
if ! kill -0 "$process_pid" 2>/dev/null; then
|
||||
echo " - PID '${process_pid}' stopped."
|
||||
else
|
||||
echo " - ERROR: Failed to kill PID '${process_pid}'."
|
||||
fi
|
||||
done
|
||||
echo " - All sunshine-run related processes are stopped."
|
||||
|
||||
# Check if the required information was stored for resetting the display resolution and refresh rate
|
||||
if ([ "X${primary_output:-}" != "X" ] && [ "X${display_mode:-}" != "X" ] && [ "X${display_rate:-}" != "X" ]); then
|
||||
# Reset display resolution and refresh rate
|
||||
echo " - Resetting display resolution to ${display_mode:?} ${display_rate:?}Hz"
|
||||
xrandr --output "${primary_output:?}" --mode "${display_mode:?}" --rate "${display_rate:?}"
|
||||
else
|
||||
echo " - WARNING: original display config not found. Resolution will not be reset."
|
||||
fi
|
||||
|
||||
# Clean up config file
|
||||
if [ -f /tmp/sunshine-exec-run.conf ]; then
|
||||
echo " - Removing sunshine-run config."
|
||||
rm -f /tmp/sunshine-exec-run.conf
|
||||
else
|
||||
echo " - WARNING: No sunshine-run config found for removal."
|
||||
fi
|
||||
|
||||
# Clean up PID file
|
||||
if [ -f /tmp/sunshine-exec-run.pid ]; then
|
||||
echo " - Removing sunshine-run pidfile."
|
||||
rm -f /tmp/sunshine-exec-run.pid
|
||||
else
|
||||
echo " - WARNING: No sunshine-run pidfile found for removal."
|
||||
fi
|
||||
|
||||
echo "DONE"
|
||||
23
overlay/usr/bin/xfce4-close-all-windows
Executable file
23
overlay/usr/bin/xfce4-close-all-windows
Executable file
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env bash
|
||||
###
|
||||
# File: xfce4-close-all-windows
|
||||
# Project: bin
|
||||
# File Created: Tuesday, 22nd August 2023 3:28:52 pm
|
||||
# Author: Josh.5 (jsunnex@gmail.com)
|
||||
# -----
|
||||
# Last Modified: Tuesday, 22nd August 2023 3:28:52 pm
|
||||
# Modified By: Josh.5 (jsunnex@gmail.com)
|
||||
###
|
||||
set -e
|
||||
|
||||
# Get a list of open windows
|
||||
WINDOW_IDS=$(wmctrl -l | grep -vwE "Desktop$|xfce4-panel$" | cut -f1 -d' ')
|
||||
# Close each window
|
||||
for i in ${WINDOW_IDS}; do
|
||||
wmctrl -ic "$i";
|
||||
done
|
||||
# Keep checking and waiting until all windows are closed
|
||||
while [ "X${WINDOW_IDS:-}" != "X" ]; do
|
||||
sleep 0.2;
|
||||
WINDOW_IDS=$(wmctrl -l | grep -vwE "Desktop$|xfce4-panel$" | cut -f1 -d' ')
|
||||
done
|
||||
19
overlay/usr/bin/xfce4-minimise-all-windows
Executable file
19
overlay/usr/bin/xfce4-minimise-all-windows
Executable file
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/env bash
|
||||
###
|
||||
# File: xfce4-minimise-all-windows
|
||||
# Project: bin
|
||||
# File Created: Tuesday, 22nd August 2023 3:28:52 pm
|
||||
# Author: Josh.5 (jsunnex@gmail.com)
|
||||
# -----
|
||||
# Last Modified: Tuesday, 22nd August 2023 3:28:52 pm
|
||||
# Modified By: Josh.5 (jsunnex@gmail.com)
|
||||
###
|
||||
set -e
|
||||
|
||||
# Get a list of open windows
|
||||
WINDOW_IDS=$(wmctrl -l | grep -vwE "Desktop$|xfce4-panel$" | cut -f1 -d' ')
|
||||
# Minimise each window
|
||||
for i in ${WINDOW_IDS}; do
|
||||
wmctrl -ir "$i" -b add,hidden;
|
||||
sleep 0.2
|
||||
done
|
||||
Reference in New Issue
Block a user