Compare commits
3 Commits
dev-fronte
...
dev-kasmvn
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0ad203f89d | ||
|
|
63754aaed5 | ||
|
|
e717cd209f |
250
.github/workflows/build_ci.yml
vendored
250
.github/workflows/build_ci.yml
vendored
@@ -1,170 +1,128 @@
|
|||||||
|
---
|
||||||
|
|
||||||
name: Build and Deploy CI
|
name: Build and Deploy CI
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
|
||||||
push:
|
push:
|
||||||
branches: ['dev-**', 'pr-**', staging, master]
|
branches: [ 'dev-**', 'pr-**', staging, master ]
|
||||||
tags: ['**']
|
tags: [ '**' ]
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [staging, master]
|
branches: [ staging, master ]
|
||||||
schedule:
|
schedule:
|
||||||
# At 02:30 on Saturday
|
# At 02:30 on Saturday
|
||||||
- cron: '30 2 * * 6'
|
- cron: '30 2 * * 6'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
build_docker:
|
build_docker:
|
||||||
|
|
||||||
name: Build Docker Image
|
name: Build Docker Image
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
packages: write
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
flavour: ['debian', 'arch']
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
# ---
|
# Fetch shallow git repository
|
||||||
- name: Checkout repository
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
# ---
|
# Use QEMU to build
|
||||||
- name: Set up Docker Buildx
|
- name: Set up QEMU
|
||||||
uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 #v3.8.0
|
if: success()
|
||||||
|
id: qemu
|
||||||
|
uses: docker/setup-qemu-action@v1
|
||||||
|
|
||||||
# ---
|
# Use docker buildx to build the docker image
|
||||||
- name: Prepare
|
- name: Build the Docker image
|
||||||
if: success()
|
uses: docker/setup-buildx-action@v1
|
||||||
id: prepare
|
if: success()
|
||||||
run: |
|
id: buildx
|
||||||
FLAVOUR=${{ matrix.flavour }}
|
with:
|
||||||
echo "FLAVOUR='${FLAVOUR}'"
|
version: latest
|
||||||
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
|
# Generate 'prepare' build arguments to be retrieved later on
|
||||||
DOCKER_HUB_IMAGE=docker.io/josh5/${SERVICE_NAME:?}
|
- name: Prepare
|
||||||
GHCR_IMAGE=ghcr.io/${ORG:?}/${SERVICE_NAME:?}
|
if: success()
|
||||||
|
id: prepare
|
||||||
|
run: |
|
||||||
|
echo "GITHUB_REF:${GITHUB_REF}"
|
||||||
|
echo "GITHUB_REPOSITORY:${GITHUB_REPOSITORY}"
|
||||||
|
DOCKER_IMAGE=docker.io/josh5/steam-headless
|
||||||
|
VERSION_TAG=${GITHUB_REF#refs/*/}
|
||||||
|
|
||||||
DOCKER_TAGS=""
|
DOCKER_TAGS=""
|
||||||
if [[ ${GITHUB_REF} == refs/heads/master ]]; then
|
if [[ ${VERSION_TAG%/merge} == 'master' ]]; then
|
||||||
if [[ ${FLAVOUR} == 'debian' ]]; then
|
DOCKER_TAGS="${DOCKER_TAGS}${DOCKER_IMAGE}:latest,"
|
||||||
DOCKER_TAGS="${DOCKER_TAGS}${DOCKER_HUB_IMAGE}:latest,${GHCR_IMAGE}:latest,${GHCR_IMAGE}:stable,"
|
elif [[ ${VERSION_TAG%/merge} == 'staging' ]]; then
|
||||||
fi
|
DOCKER_TAGS="${DOCKER_TAGS}${DOCKER_IMAGE}:staging,"
|
||||||
DOCKER_TAGS="${DOCKER_TAGS}${DOCKER_HUB_IMAGE}:${FLAVOUR},${GHCR_IMAGE}:${FLAVOUR},"
|
elif [[ ${VERSION_TAG%/merge} =~ "dev-"* ]]; then
|
||||||
elif [[ ${GITHUB_REF} == refs/heads/staging ]]; then
|
DOCKER_TAGS="${DOCKER_TAGS}${DOCKER_IMAGE}:${VERSION_TAG%/merge},"
|
||||||
DOCKER_TAGS="${DOCKER_TAGS}${DOCKER_HUB_IMAGE}:${FLAVOUR}-staging,${GHCR_IMAGE}:${FLAVOUR}-staging,"
|
fi
|
||||||
elif [[ ${GITHUB_REF} == refs/heads/dev-* ]]; then
|
if [[ ${GITHUB_REF} == refs/tags/* ]]; then
|
||||||
DOCKER_TAGS="${DOCKER_TAGS}${DOCKER_HUB_IMAGE}:${FLAVOUR}-${VERSION_TAG},${GHCR_IMAGE}:${FLAVOUR}-${VERSION_TAG},"
|
VERSION=${GITHUB_REF#refs/tags/}
|
||||||
elif [[ ${GITHUB_REF} == refs/tags/* ]]; then
|
if [[ ${VERSION} =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}[-\w]*$ ]]; then
|
||||||
VERSION=${GITHUB_REF#refs/tags/}
|
DOCKER_TAGS="${DOCKER_TAGS}${DOCKER_IMAGE}:${VERSION},"
|
||||||
if [[ ${VERSION} =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}[-\w]*$ ]]; then
|
DOCKER_TAGS="${DOCKER_TAGS}${DOCKER_IMAGE}:latest,"
|
||||||
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
|
|
||||||
|
|
||||||
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
|
fi
|
||||||
echo "DOCKER_TAGS='${DOCKER_TAGS}'"
|
fi
|
||||||
|
|
||||||
echo "Build: [$(date +"%F %T")] [${GITHUB_REF_NAME}] [${GITHUB_SHA}] [${FLAVOUR}]" > ./overlay/version.txt
|
echo "Build: [$(date +"%F %T")] [${GITHUB_REF_NAME}] [${GITHUB_SHA}]" > ./overlay/version.txt
|
||||||
|
|
||||||
DOCKER_PUSH="true"
|
DOCKER_PUSH="true"
|
||||||
if [[ ${DOCKER_HUB_IMAGE} != 'docker.io/josh5/steam-headless' ]]; then
|
if [[ ${DOCKER_IMAGE} != 'docker.io/josh5/steam-headless' ]]; then
|
||||||
DOCKER_PUSH="false"
|
DOCKER_PUSH="false"
|
||||||
fi
|
fi
|
||||||
if [[ ${VERSION_TAG%/merge} =~ "pr-"* ]]; then
|
if [[ ${VERSION_TAG%/merge} =~ "pr-"* ]]; then
|
||||||
DOCKER_PUSH="false"
|
DOCKER_PUSH="false"
|
||||||
fi
|
fi
|
||||||
if [[ ${VERSION_TAG%/merge} =~ ^[0-9]+$ ]]; then
|
if [[ ${VERSION_TAG%/merge} =~ ^[0-9]+$ ]]; then
|
||||||
DOCKER_PUSH="false"
|
DOCKER_PUSH="false"
|
||||||
fi
|
fi
|
||||||
if [[ "X${DOCKER_TAGS}" == "X" ]]; then
|
|
||||||
DOCKER_PUSH="false"
|
|
||||||
fi
|
|
||||||
echo "DOCKER_PUSH='${DOCKER_PUSH}'"
|
|
||||||
cat ./overlay/version.txt
|
|
||||||
|
|
||||||
echo "docker_hub_image:${DOCKER_HUB_IMAGE:?}"
|
echo ::set-output name=docker_image::${DOCKER_IMAGE}
|
||||||
echo "docker_hub_image=${DOCKER_HUB_IMAGE:?}" >> $GITHUB_OUTPUT
|
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 "ghcr_image:${GHCR_IMAGE:?}"
|
# Cache the build
|
||||||
echo "ghcr_image=${GHCR_IMAGE:?}" >> $GITHUB_OUTPUT
|
- name: Cache Docker layers
|
||||||
|
uses: actions/cache@v2
|
||||||
|
id: cache
|
||||||
|
with:
|
||||||
|
path: /tmp/.buildx-cache
|
||||||
|
key: ${{ runner.os }}-buildx-${{ github.sha }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-buildx-
|
||||||
|
|
||||||
|
# Login to Docker Hub
|
||||||
|
- name: Login to Docker Hub
|
||||||
|
if: success() && (startsWith(github.ref, 'refs/heads/') || startsWith(github.ref, 'refs/tags/'))
|
||||||
|
uses: docker/login-action@v1
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKER_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
|
|
||||||
|
# Run docker build and push
|
||||||
|
- name: Docker Build and Push
|
||||||
|
if: success()
|
||||||
|
uses: docker/build-push-action@v2
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
file: Dockerfile
|
||||||
|
pull: true
|
||||||
|
platforms: ${{ steps.prepare.outputs.docker_platforms }}
|
||||||
|
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
|
||||||
|
|
||||||
echo "sha_short:${SHA_SHORT:?}"
|
# Keep only latest cache
|
||||||
echo "sha_short=${SHA_SHORT:?}" >> $GITHUB_OUTPUT
|
# https://github.com/docker/build-push-action/issues/252
|
||||||
|
# https://github.com/moby/buildkit/issues/1896
|
||||||
echo "service_name:${SERVICE_NAME:?}"
|
- name: Move cache
|
||||||
echo "service_name=${SERVICE_NAME:?}" >> $GITHUB_OUTPUT
|
if: always()
|
||||||
|
run: |
|
||||||
echo "docker_image:${DOCKER_HUB_IMAGE:?}"
|
if [[ -e /tmp/.buildx-cache-new ]]; then
|
||||||
echo "docker_image=${DOCKER_HUB_IMAGE:?}" >> $GITHUB_OUTPUT
|
echo "Cleaning up old cache..."
|
||||||
|
rm -rf /tmp/.buildx-cache
|
||||||
echo "docker_tags:$(echo ${DOCKER_TAGS} | sed 's/,$//')"
|
mv -v /tmp/.buildx-cache-new /tmp/.buildx-cache
|
||||||
echo "docker_tags=$(echo ${DOCKER_TAGS} | sed 's/,$//')" >> $GITHUB_OUTPUT
|
fi
|
||||||
|
|
||||||
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:
|
|
||||||
registry: ghcr.io
|
|
||||||
username: ${{ github.actor }}
|
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
# ---
|
|
||||||
- name: Log into Docker Hub registry
|
|
||||||
if: success() && (startsWith(github.ref, 'refs/heads/') || startsWith(github.ref, 'refs/tags/'))
|
|
||||||
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 #v3.3.0
|
|
||||||
with:
|
|
||||||
username: ${{ secrets.DOCKER_USERNAME }}
|
|
||||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
|
||||||
|
|
||||||
# ---
|
|
||||||
- name: Docker meta
|
|
||||||
if: success()
|
|
||||||
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.${{ matrix.flavour }}
|
|
||||||
platforms: ${{ steps.prepare.outputs.docker_platforms }}
|
|
||||||
pull: 'true'
|
|
||||||
push: ${{ steps.prepare.outputs.docker_push }}
|
|
||||||
tags: |
|
|
||||||
${{ steps.prepare.outputs.docker_tags }}
|
|
||||||
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
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
FROM debian:bookworm-slim
|
FROM debian:bullseye-slim
|
||||||
LABEL maintainer="Josh.5 <jsunnex@gmail.com>"
|
LABEL maintainer="Josh.5 <jsunnex@gmail.com>"
|
||||||
|
|
||||||
# Update package repos
|
# Update package repos
|
||||||
ARG DEBIAN_FRONTEND=noninteractive
|
ARG DEBIAN_FRONTEND=noninteractive
|
||||||
RUN \
|
RUN \
|
||||||
echo "**** Update apt database ****" \
|
echo "**** Update apt database ****" \
|
||||||
&& sed -i '/^Components: main/ s/$/ contrib non-free/' /etc/apt/sources.list.d/debian.sources \
|
&& sed -i '/^.*main/ s/$/ contrib non-free/' /etc/apt/sources.list \
|
||||||
&& \
|
&& \
|
||||||
echo
|
echo
|
||||||
|
|
||||||
@@ -70,7 +70,6 @@ RUN \
|
|||||||
mlocate \
|
mlocate \
|
||||||
nano \
|
nano \
|
||||||
net-tools \
|
net-tools \
|
||||||
p7zip-full \
|
|
||||||
patch \
|
patch \
|
||||||
pciutils \
|
pciutils \
|
||||||
pkg-config \
|
pkg-config \
|
||||||
@@ -83,7 +82,6 @@ RUN \
|
|||||||
unzip \
|
unzip \
|
||||||
vim \
|
vim \
|
||||||
wget \
|
wget \
|
||||||
xmlstarlet \
|
|
||||||
xz-utils \
|
xz-utils \
|
||||||
&& \
|
&& \
|
||||||
echo "**** Install python ****" \
|
echo "**** Install python ****" \
|
||||||
@@ -92,7 +90,6 @@ RUN \
|
|||||||
python3-numpy \
|
python3-numpy \
|
||||||
python3-pip \
|
python3-pip \
|
||||||
python3-setuptools \
|
python3-setuptools \
|
||||||
python3-venv \
|
|
||||||
&& \
|
&& \
|
||||||
echo "**** Section cleanup ****" \
|
echo "**** Section cleanup ****" \
|
||||||
&& apt-get clean autoclean -y \
|
&& apt-get clean autoclean -y \
|
||||||
@@ -104,27 +101,6 @@ RUN \
|
|||||||
&& \
|
&& \
|
||||||
echo
|
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
|
# Install supervisor
|
||||||
RUN \
|
RUN \
|
||||||
echo "**** Update apt database ****" \
|
echo "**** Update apt database ****" \
|
||||||
@@ -144,13 +120,48 @@ RUN \
|
|||||||
&& \
|
&& \
|
||||||
echo
|
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
|
# 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 \
|
RUN \
|
||||||
echo "**** Update apt database ****" \
|
echo "**** Update apt database ****" \
|
||||||
&& apt-get update \
|
&& apt-get update \
|
||||||
@@ -162,7 +173,6 @@ RUN \
|
|||||||
libxcomposite-dev \
|
libxcomposite-dev \
|
||||||
libxcursor1 \
|
libxcursor1 \
|
||||||
wmctrl \
|
wmctrl \
|
||||||
libfuse2 \
|
|
||||||
x11-utils \
|
x11-utils \
|
||||||
x11-xfs-utils \
|
x11-xfs-utils \
|
||||||
x11-xkb-utils \
|
x11-xkb-utils \
|
||||||
@@ -171,7 +181,6 @@ RUN \
|
|||||||
xauth \
|
xauth \
|
||||||
xbindkeys \
|
xbindkeys \
|
||||||
xclip \
|
xclip \
|
||||||
xcvt \
|
|
||||||
xdotool \
|
xdotool \
|
||||||
xfishtank \
|
xfishtank \
|
||||||
xfonts-base \
|
xfonts-base \
|
||||||
@@ -183,6 +192,7 @@ RUN \
|
|||||||
xserver-xorg-legacy \
|
xserver-xorg-legacy \
|
||||||
xserver-xorg-video-all \
|
xserver-xorg-video-all \
|
||||||
xserver-xorg-video-dummy \
|
xserver-xorg-video-dummy \
|
||||||
|
xvfb \
|
||||||
&& \
|
&& \
|
||||||
echo "**** Section cleanup ****" \
|
echo "**** Section cleanup ****" \
|
||||||
&& apt-get clean autoclean -y \
|
&& apt-get clean autoclean -y \
|
||||||
@@ -195,14 +205,11 @@ RUN \
|
|||||||
echo
|
echo
|
||||||
|
|
||||||
# Install audio requirements
|
# Install audio requirements
|
||||||
ENV \
|
|
||||||
PULSE_SOCKET_DIR="/tmp/pulse" \
|
|
||||||
PULSE_SERVER="unix:/tmp/pulse/pulse-socket"
|
|
||||||
RUN \
|
RUN \
|
||||||
echo "**** Update apt database ****" \
|
echo "**** Update apt database ****" \
|
||||||
&& apt-get update \
|
&& apt-get update \
|
||||||
&& \
|
&& \
|
||||||
echo "**** Install pulseaudio requirements ****" \
|
echo "**** Install X Server requirements ****" \
|
||||||
&& apt-get install -y --no-install-recommends \
|
&& apt-get install -y --no-install-recommends \
|
||||||
pulseaudio \
|
pulseaudio \
|
||||||
alsa-utils \
|
alsa-utils \
|
||||||
@@ -220,28 +227,17 @@ RUN \
|
|||||||
echo
|
echo
|
||||||
|
|
||||||
# Install desktop environment
|
# Install desktop environment
|
||||||
# TODO: Specify all needed packages and add '--no-install-recommends'
|
|
||||||
RUN \
|
RUN \
|
||||||
echo "**** Update apt database ****" \
|
echo "**** Update apt database ****" \
|
||||||
&& apt-get update \
|
&& 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 ****" \
|
echo "**** Install desktop environment ****" \
|
||||||
&& apt-get install -y \
|
&& apt-get install -y \
|
||||||
fonts-vlgothic \
|
|
||||||
gedit \
|
|
||||||
imagemagick \
|
|
||||||
msttcorefonts \
|
|
||||||
xdg-utils \
|
|
||||||
xfce4 \
|
xfce4 \
|
||||||
xfce4-terminal \
|
xfce4-terminal \
|
||||||
|
msttcorefonts \
|
||||||
|
fonts-vlgothic \
|
||||||
|
gedit \
|
||||||
# Delete these as they are not needed at all
|
# Delete these as they are not needed at all
|
||||||
&& rm -f \
|
&& rm -f \
|
||||||
/usr/share/applications/software-properties-drivers.desktop \
|
/usr/share/applications/software-properties-drivers.desktop \
|
||||||
@@ -251,26 +247,17 @@ 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-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-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-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/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-settings.desktop \
|
||||||
&& sed -i '/[Desktop Entry]/a\NoDisplay=true' /usr/share/applications/thunar.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/pavucontrol.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 \
|
&& sed -i '/[Desktop Entry]/a\NoDisplay=true' /usr/share/applications/debian-uxterm.desktop \
|
||||||
|
&& sed -i '/[Desktop Entry]/a\NoDisplay=true' /usr/share/applications/debian-xterm.desktop \
|
||||||
# Force these apps to be "System" Apps rather than "Categories=System;Utility;Core;GTK;Filesystem;"
|
# 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/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/thunar-bulk-rename.desktop \
|
||||||
&& sed -i 's/^Categories=.*$/Categories=System;/' /usr/share/applications/org.gnome.gedit.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 ****" \
|
echo "**** Section cleanup ****" \
|
||||||
&& apt-get clean autoclean -y \
|
&& apt-get clean autoclean -y \
|
||||||
&& apt-get autoremove -y \
|
&& apt-get autoremove -y \
|
||||||
@@ -282,20 +269,23 @@ RUN \
|
|||||||
echo
|
echo
|
||||||
|
|
||||||
# Add support for flatpaks
|
# 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 \
|
RUN \
|
||||||
echo "**** Update apt database ****" \
|
echo "**** Update apt database ****" \
|
||||||
&& apt-get update \
|
&& apt-get update \
|
||||||
&& \
|
&& \
|
||||||
echo "**** Install flatpak support ****" \
|
echo "**** Install flatpak support ****" \
|
||||||
&& apt-get install -y --no-install-recommends \
|
&& apt-get install -y \
|
||||||
|
bridge-utils \
|
||||||
flatpak \
|
flatpak \
|
||||||
gnome-software-plugin-flatpak \
|
gnome-software-plugin-flatpak \
|
||||||
|
libpam-cgfs \
|
||||||
|
libvirt0 \
|
||||||
|
lxc \
|
||||||
|
uidmap \
|
||||||
&& \
|
&& \
|
||||||
echo "**** Configure flatpak ****" \
|
echo "**** Configure flatpak ****" \
|
||||||
|
&& chmod u+s /usr/bin/bwrap \
|
||||||
&& flatpak remote-add flathub https://flathub.org/repo/flathub.flatpakrepo \
|
&& flatpak remote-add flathub https://flathub.org/repo/flathub.flatpakrepo \
|
||||||
&& dpkg-statoverride --update --add root root 0755 /usr/bin/bwrap \
|
|
||||||
&& \
|
&& \
|
||||||
echo "**** Section cleanup ****" \
|
echo "**** Section cleanup ****" \
|
||||||
&& apt-get clean autoclean -y \
|
&& apt-get clean autoclean -y \
|
||||||
@@ -307,6 +297,119 @@ RUN \
|
|||||||
&& \
|
&& \
|
||||||
echo
|
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
|
||||||
|
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 "**** 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 \
|
||||||
|
&& 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 "**** Update apt database ****" \
|
||||||
|
&& apt-get update \
|
||||||
|
&& \
|
||||||
|
echo "**** Install nginx support ****" \
|
||||||
|
&& apt-get install -y \
|
||||||
|
nginx \
|
||||||
|
&& \
|
||||||
|
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 \
|
||||||
|
&& \
|
||||||
|
echo "**** Extract Websockify ****" \
|
||||||
|
&& 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 ****" \
|
||||||
|
&& cd /tmp \
|
||||||
|
&& mv -v /tmp/websockify-${WEBSOCKETIFY_VERSION} /opt/noVNC/utils/websockify \
|
||||||
|
&& \
|
||||||
|
echo "**** Section cleanup ****" \
|
||||||
|
&& rm -rf \
|
||||||
|
/tmp/websockify-* \
|
||||||
|
/tmp/websockify.tar.gz
|
||||||
|
|
||||||
# Setup audio streaming deps
|
# Setup audio streaming deps
|
||||||
RUN \
|
RUN \
|
||||||
echo "**** Update apt database ****" \
|
echo "**** Update apt database ****" \
|
||||||
@@ -357,26 +460,6 @@ RUN \
|
|||||||
intel-media-va-driver-non-free \
|
intel-media-va-driver-non-free \
|
||||||
i965-va-driver-shaders \
|
i965-va-driver-shaders \
|
||||||
libva2 \
|
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 \
|
vainfo \
|
||||||
vdpauinfo \
|
vdpauinfo \
|
||||||
&& \
|
&& \
|
||||||
@@ -390,123 +473,25 @@ RUN \
|
|||||||
&& \
|
&& \
|
||||||
echo
|
echo
|
||||||
|
|
||||||
# Install Steam
|
|
||||||
RUN \
|
|
||||||
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
|
# Configure default user and set env
|
||||||
COPY --from=lizardbyte/sunshine:v2025.122.141614-debian-bookworm /sunshine.deb /usr/src/sunshine.deb
|
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 \
|
RUN \
|
||||||
echo "**** Update apt database ****" \
|
echo "**** Configure default user '${USER}' ****" \
|
||||||
&& apt-get update \
|
&& mkdir -p \
|
||||||
&& \
|
${USER_HOME} \
|
||||||
echo "**** Install Sunshine requirements ****" \
|
&& useradd -d ${USER_HOME} -s /bin/bash ${USER} \
|
||||||
&& apt-get install -y \
|
&& chown -R ${USER} \
|
||||||
va-driver-all \
|
${USER_HOME} \
|
||||||
&& \
|
&& echo "${USER} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers \
|
||||||
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
|
|
||||||
|
|
||||||
# Install Web Frontend
|
|
||||||
ARG NODE_VERSION="v20"
|
|
||||||
ARG FRONTEND_VERSION=5ede778
|
|
||||||
RUN \
|
|
||||||
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 "**** Fetch Web Frontend ****" \
|
|
||||||
&& mkdir -p /opt \
|
|
||||||
&& cd /opt \
|
|
||||||
&& rm -rf /opt/frontend \
|
|
||||||
&& git clone https://github.com/Steam-Headless/frontend.git --branch dev-SHUI /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 "**** Install SHUIv2 requirements ****" \
|
|
||||||
&& cd /opt/frontend \
|
|
||||||
&& python3 -m venv --symlinks ./venv \
|
|
||||||
&& ./venv/bin/python3 -m pip install --no-cache-dir --upgrade pip \
|
|
||||||
&& ./venv/bin/python3 -m pip install --no-cache-dir -r ./requirements.txt \
|
|
||||||
&& \
|
|
||||||
echo "**** Build SHUIv2 vue ****" \
|
|
||||||
&& cd /opt/frontend \
|
|
||||||
&& cd ./shui2/shui-vue/ \
|
|
||||||
&& npm ci \
|
|
||||||
&& npm run build \
|
|
||||||
&& cd /opt/frontend \
|
|
||||||
&& cd ./shui2/server/ \
|
|
||||||
&& npm ci \
|
|
||||||
&& \
|
|
||||||
echo "**** Install Web Frontend icon ****" \
|
|
||||||
&& cd /opt/frontend \
|
|
||||||
&& convert ./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
|
|
||||||
|
|
||||||
# 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
|
echo
|
||||||
|
|
||||||
@@ -520,30 +505,31 @@ ENV \
|
|||||||
DISPLAY_SIZEH="900" \
|
DISPLAY_SIZEH="900" \
|
||||||
DISPLAY_SIZEW="1600" \
|
DISPLAY_SIZEW="1600" \
|
||||||
DISPLAY_VIDEO_PORT="DFP" \
|
DISPLAY_VIDEO_PORT="DFP" \
|
||||||
DISPLAY=":55"
|
DISPLAY=":55" \
|
||||||
ENV \
|
|
||||||
NVIDIA_DRIVER_CAPABILITIES="all" \
|
NVIDIA_DRIVER_CAPABILITIES="all" \
|
||||||
NVIDIA_VISIBLE_DEVICES="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
|
||||||
|
ENV \
|
||||||
|
PULSE_SOCKET_DIR="/tmp/pulse" \
|
||||||
|
PULSE_SERVER="unix:/tmp/pulse/pulse-socket"
|
||||||
|
|
||||||
# Set container configuration environment variables
|
# Set container configuration environment variables
|
||||||
# TODO: Set the default WEBUI_USER & WEBUI_PASS after release of SHUI
|
|
||||||
ENV \
|
ENV \
|
||||||
MODE="primary" \
|
MODE="primary" \
|
||||||
WEB_UI_MODE="vnc" \
|
WEB_UI_MODE="vnc" \
|
||||||
ENABLE_VNC_AUDIO="true" \
|
ENABLE_VNC_AUDIO="true" \
|
||||||
NEKO_PASSWORD=neko \
|
NEKO_PASSWORD=neko \
|
||||||
NEKO_PASSWORD_ADMIN=admin \
|
NEKO_PASSWORD_ADMIN=admin \
|
||||||
ENABLE_STEAM="true" \
|
ENABLE_SUNSHINE="false" \
|
||||||
STEAM_ARGS="-silent" \
|
ENABLE_EVDEV_INPUTS="false"
|
||||||
WEBUI_USER="" \
|
|
||||||
WEBUI_PASS="" \
|
|
||||||
ENABLE_SUNSHINE="true" \
|
|
||||||
ENABLE_EVDEV_INPUTS="true" \
|
|
||||||
ENABLE_WOL_POWER_MANAGER="false" \
|
|
||||||
ENABLE_SID="false"
|
|
||||||
|
|
||||||
# Configure required ports
|
# Configure required ports
|
||||||
ENV \
|
ENV \
|
||||||
|
PORT_SSH="" \
|
||||||
PORT_NOVNC_WEB="8083" \
|
PORT_NOVNC_WEB="8083" \
|
||||||
NEKO_NAT1TO1=""
|
NEKO_NAT1TO1=""
|
||||||
|
|
||||||
491
Dockerfile.arch
491
Dockerfile.arch
@@ -34,8 +34,6 @@ RUN \
|
|||||||
&& \
|
&& \
|
||||||
echo "**** Section cleanup ****" \
|
echo "**** Section cleanup ****" \
|
||||||
&& pacman -Scc --noconfirm \
|
&& pacman -Scc --noconfirm \
|
||||||
&& rm -fr /var/lib/pacman/sync/* \
|
|
||||||
&& rm -fr /var/cache/pacman/pkg/* \
|
|
||||||
&& \
|
&& \
|
||||||
echo
|
echo
|
||||||
|
|
||||||
@@ -43,34 +41,21 @@ RUN \
|
|||||||
RUN \
|
RUN \
|
||||||
echo "**** Install tools ****" \
|
echo "**** Install tools ****" \
|
||||||
&& pacman -Syu --noconfirm --needed \
|
&& pacman -Syu --noconfirm --needed \
|
||||||
base-devel \
|
|
||||||
bash \
|
bash \
|
||||||
bash-completion \
|
bash-completion \
|
||||||
curl \
|
curl \
|
||||||
docbook-xml \
|
|
||||||
docbook-xsl \
|
|
||||||
fakeroot \
|
|
||||||
p7zip \
|
|
||||||
patch \
|
|
||||||
git \
|
git \
|
||||||
jq \
|
|
||||||
less \
|
less \
|
||||||
locate \
|
|
||||||
man-db \
|
man-db \
|
||||||
nano \
|
nano \
|
||||||
net-tools \
|
net-tools \
|
||||||
pciutils \
|
|
||||||
pkg-config \
|
pkg-config \
|
||||||
procps \
|
|
||||||
psmisc \
|
|
||||||
psutils \
|
|
||||||
rsync \
|
rsync \
|
||||||
screen \
|
screen \
|
||||||
sudo \
|
sudo \
|
||||||
unzip \
|
unzip \
|
||||||
vim \
|
vim \
|
||||||
wget \
|
wget \
|
||||||
xmlstarlet \
|
|
||||||
xz \
|
xz \
|
||||||
&& \
|
&& \
|
||||||
echo "**** Install python ****" \
|
echo "**** Install python ****" \
|
||||||
@@ -82,44 +67,6 @@ RUN \
|
|||||||
&& \
|
&& \
|
||||||
echo "**** Section cleanup ****" \
|
echo "**** Section cleanup ****" \
|
||||||
&& pacman -Scc --noconfirm \
|
&& 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
|
echo
|
||||||
|
|
||||||
@@ -131,38 +78,48 @@ RUN \
|
|||||||
&& \
|
&& \
|
||||||
echo "**** Section cleanup ****" \
|
echo "**** Section cleanup ****" \
|
||||||
&& pacman -Scc --noconfirm \
|
&& pacman -Scc --noconfirm \
|
||||||
&& rm -fr /var/lib/pacman/sync/* \
|
|
||||||
&& rm -fr /var/cache/pacman/pkg/* \
|
|
||||||
&& \
|
&& \
|
||||||
echo
|
echo
|
||||||
|
|
||||||
# Install mscorefonts
|
# XFS requirements
|
||||||
RUN \
|
RUN \
|
||||||
echo "**** Install ms fonts ****" \
|
echo "**** Install XFS requirements ****" \
|
||||||
&& su - default -c "yay -Syu --noconfirm --needed ttf-msfonts" \
|
&& 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 "**** Section cleanup ****" \
|
echo "**** Section cleanup ****" \
|
||||||
&& pacman -Scc --noconfirm \
|
&& 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
|
echo
|
||||||
|
|
||||||
# Install X Server requirements
|
# Install X Server requirements
|
||||||
ENV \
|
# TODO: Remove doubles
|
||||||
XORG_SOCKET_DIR="/tmp/.X11-unix" \
|
# TODO: Things that are not required
|
||||||
XDG_RUNTIME_DIR="/tmp/.X11-unix/run" \
|
|
||||||
XDG_SESSION_TYPE="x11" \
|
|
||||||
FORCE_X11_DUMMY_CONFIG="false"
|
|
||||||
RUN \
|
RUN \
|
||||||
echo "**** Install X Server requirements ****" \
|
echo "**** Install X Server requirements ****" \
|
||||||
&& pacman -Syu --noconfirm --needed \
|
&& pacman -Syu --noconfirm --needed \
|
||||||
avahi \
|
avahi \
|
||||||
dbus \
|
dbus \
|
||||||
lib32-fontconfig \
|
lib32-fontconfig \
|
||||||
fuse2 \
|
ttf-liberation \
|
||||||
x11vnc \
|
x11vnc \
|
||||||
xorg \
|
xorg \
|
||||||
xorg-apps \
|
xorg-apps \
|
||||||
@@ -182,115 +139,94 @@ RUN \
|
|||||||
xorg-xrandr \
|
xorg-xrandr \
|
||||||
xorg-xsetroot \
|
xorg-xsetroot \
|
||||||
xorg-xwininfo \
|
xorg-xwininfo \
|
||||||
xf86-input-evdev \
|
|
||||||
xterm \
|
|
||||||
gamescope \
|
|
||||||
&& \
|
&& \
|
||||||
echo "**** Section cleanup ****" \
|
echo "**** Section cleanup ****" \
|
||||||
&& pacman -Scc --noconfirm \
|
&& pacman -Scc --noconfirm \
|
||||||
&& rm -fr /var/lib/pacman/sync/* \
|
|
||||||
&& rm -fr /var/cache/pacman/pkg/* \
|
|
||||||
&& \
|
&& \
|
||||||
echo
|
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
|
# Install audio requirements
|
||||||
ENV \
|
|
||||||
PULSE_SOCKET_DIR="/tmp/pulse" \
|
|
||||||
PULSE_SERVER="unix:/tmp/pulse/pulse-socket"
|
|
||||||
RUN \
|
RUN \
|
||||||
echo "**** Install X Server requirements ****" \
|
echo "**** Install X Server requirements ****" \
|
||||||
&& pacman -Syu --noconfirm --needed \
|
&& pacman -Syu --noconfirm --needed \
|
||||||
alsa-utils \
|
|
||||||
pavucontrol \
|
|
||||||
pulseaudio \
|
pulseaudio \
|
||||||
pulseaudio-alsa \
|
|
||||||
&& \
|
&& \
|
||||||
echo "**** Section cleanup ****" \
|
echo "**** Section cleanup ****" \
|
||||||
&& pacman -Scc --noconfirm \
|
&& pacman -Scc --noconfirm \
|
||||||
&& rm -fr /var/lib/pacman/sync/* \
|
|
||||||
&& rm -fr /var/cache/pacman/pkg/* \
|
|
||||||
&& \
|
&& \
|
||||||
echo
|
echo
|
||||||
|
|
||||||
# Install desktop environment
|
# Install openssh server
|
||||||
# TODO: Install equivelent of 'msttcorefonts' and 'fonts-vlgothic'
|
|
||||||
RUN \
|
RUN \
|
||||||
echo "**** Install desktop environment ****" \
|
echo "**** Install openssh server ****" \
|
||||||
&& pacman -Syu --noconfirm --needed \
|
&& pacman -Syu --noconfirm --needed \
|
||||||
gedit \
|
openssh \
|
||||||
xfce4 \
|
&& echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config \
|
||||||
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 ****" \
|
echo "**** Section cleanup ****" \
|
||||||
&& pacman -Scc --noconfirm \
|
&& pacman -Scc --noconfirm \
|
||||||
&& rm -fr /var/lib/pacman/sync/* \
|
|
||||||
&& rm -fr /var/cache/pacman/pkg/* \
|
|
||||||
&& \
|
&& \
|
||||||
echo
|
echo
|
||||||
|
|
||||||
# Add support for flatpaks
|
# Install noVNC
|
||||||
ENV \
|
# TODO: Add nginx
|
||||||
XDG_DATA_DIRS="/home/default/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share/:/usr/share/"
|
ARG NOVNC_VERSION=1.2.0
|
||||||
RUN \
|
RUN \
|
||||||
echo "**** Install flatpak support ****" \
|
echo "**** Fetch noVNC ****" \
|
||||||
&& pacman -Syu --noconfirm --needed \
|
&& cd /tmp \
|
||||||
flatpak \
|
&& wget -O /tmp/novnc.tar.gz https://github.com/novnc/noVNC/archive/v${NOVNC_VERSION}.tar.gz \
|
||||||
xdg-desktop-portal-gtk \
|
|
||||||
gnome-software \
|
|
||||||
&& \
|
&& \
|
||||||
echo "**** Configure flatpak ****" \
|
echo "**** Extract noVNC ****" \
|
||||||
&& chmod u-s /usr/bin/bwrap \
|
&& cd /tmp \
|
||||||
&& flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo \
|
&& tar -xvf /tmp/novnc.tar.gz \
|
||||||
&& su - default -c "flatpak remote-add --if-not-exists --user flathub https://flathub.org/repo/flathub.flatpakrepo" \
|
|
||||||
&& \
|
&& \
|
||||||
echo "**** Section cleanup ****" \
|
echo "**** Configure noVNC ****" \
|
||||||
&& pacman -Scc --noconfirm \
|
&& cd /tmp/noVNC-${NOVNC_VERSION} \
|
||||||
&& rm -fr /var/lib/pacman/sync/* \
|
&& sed -i 's/credentials: { password: password } });/credentials: { password: password },\n wsProtocols: ["'"binary"'"] });/g' app/ui.js \
|
||||||
&& 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 \
|
&& mkdir -p /opt \
|
||||||
|
&& rm -rf /opt/noVNC \
|
||||||
&& cd /opt \
|
&& cd /opt \
|
||||||
&& rm -rf /opt/frontend \
|
&& mv -f /tmp/noVNC-${NOVNC_VERSION} /opt/noVNC \
|
||||||
&& git clone https://github.com/Steam-Headless/frontend.git --branch master /opt/frontend \
|
&& cd /opt/noVNC \
|
||||||
&& cd /opt/frontend \
|
&& ln -s vnc.html index.html \
|
||||||
&& git checkout ${FRONTEND_VERSION} 2> /dev/null \
|
&& chmod -R 755 /opt/noVNC \
|
||||||
&& git submodule init \
|
|
||||||
&& git submodule update --depth 1 --recursive \
|
|
||||||
&& rm -rf /opt/frontend/.git \
|
|
||||||
&& \
|
&& \
|
||||||
echo "**** Configure Web Frontend ****" \
|
echo "**** Modify noVNC title ****" \
|
||||||
&& echo '<!DOCTYPE html>' > /opt/frontend/index.html \
|
&& sed -i '/ document.title =/c\ document.title = "Steam Headless - noVNC";' \
|
||||||
&& 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 \
|
/opt/noVNC/app/ui.js \
|
||||||
&& 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 ****" \
|
echo "**** Section cleanup ****" \
|
||||||
&& rm -f /tmp/steam-headless.png
|
&& rm -rf \
|
||||||
|
/tmp/noVNC* \
|
||||||
|
/tmp/novnc.tar.gz
|
||||||
|
|
||||||
# Install Websockify
|
# Install Websockify
|
||||||
ARG WEBSOCKETIFY_VERSION=0.11.0
|
ARG WEBSOCKETIFY_VERSION=0.10.0
|
||||||
RUN \
|
RUN \
|
||||||
echo "**** Fetch Websockify ****" \
|
echo "**** Fetch Websockify ****" \
|
||||||
&& cd /tmp \
|
&& cd /tmp \
|
||||||
@@ -306,201 +242,180 @@ RUN \
|
|||||||
&& \
|
&& \
|
||||||
echo "**** Install Websockify to noVNC path ****" \
|
echo "**** Install Websockify to noVNC path ****" \
|
||||||
&& cd /tmp \
|
&& cd /tmp \
|
||||||
&& mkdir -p /opt/noVNC/utils \
|
|
||||||
&& mv -v /tmp/websockify-${WEBSOCKETIFY_VERSION} /opt/noVNC/utils/websockify \
|
&& mv -v /tmp/websockify-${WEBSOCKETIFY_VERSION} /opt/noVNC/utils/websockify \
|
||||||
&& \
|
&& \
|
||||||
echo "**** Section cleanup ****" \
|
echo "**** Section cleanup ****" \
|
||||||
&& rm -rf \
|
&& rm -rf \
|
||||||
/tmp/websockify-* \
|
/tmp/websockify-* \
|
||||||
/tmp/websockify.tar.gz \
|
/tmp/websockify.tar.gz
|
||||||
&& \
|
|
||||||
echo
|
|
||||||
|
|
||||||
# Setup browser audio streaming deps
|
# Install firefox
|
||||||
|
# TODO: MOve under de
|
||||||
RUN \
|
RUN \
|
||||||
echo "**** Install audio streaming deps ****" \
|
echo "**** Install firefox ****" \
|
||||||
&& 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 \
|
&& pacman -Syu --noconfirm --needed \
|
||||||
firefox \
|
firefox \
|
||||||
&& \
|
&& \
|
||||||
echo "**** Section cleanup ****" \
|
echo "**** Section cleanup ****" \
|
||||||
&& pacman -Scc --noconfirm \
|
&& pacman -Scc --noconfirm \
|
||||||
&& rm -fr /var/lib/pacman/sync/* \
|
|
||||||
&& rm -fr /var/cache/pacman/pkg/* \
|
|
||||||
&& \
|
&& \
|
||||||
echo
|
echo
|
||||||
|
|
||||||
# Install Steam
|
# # 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
|
||||||
RUN \
|
RUN \
|
||||||
echo "**** Install Steam ****" \
|
echo "**** Install desktop environment ****" \
|
||||||
&& pacman -Syu --noconfirm --needed \
|
&& pacman -Syu --noconfirm --needed \
|
||||||
steam \
|
gedit \
|
||||||
|
xfce4 \
|
||||||
|
xfce4-terminal \
|
||||||
&& \
|
&& \
|
||||||
echo "**** Section cleanup ****" \
|
echo "**** Section cleanup ****" \
|
||||||
&& pacman -Scc --noconfirm \
|
&& pacman -Scc --noconfirm \
|
||||||
&& rm -fr /var/lib/pacman/sync/* \
|
|
||||||
&& rm -fr /var/cache/pacman/pkg/* \
|
|
||||||
&& \
|
&& \
|
||||||
echo
|
echo
|
||||||
|
|
||||||
# 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
|
|
||||||
|
|
||||||
# Install Protonup replacement
|
# Add support for flatpaks
|
||||||
RUN \
|
RUN \
|
||||||
echo "**** Install PorotonUP ****" \
|
echo "**** Install flatpak support ****" \
|
||||||
&& su - default -c "yay -Sy --noconfirm --needed --overwrite \"/usr/bin/normalizer\" protonup-qt" \
|
&& pacman -Syu --noconfirm --needed \
|
||||||
|
flatpak \
|
||||||
|
xdg-desktop-portal-gtk \
|
||||||
&& \
|
&& \
|
||||||
echo "**** Section cleanup ****" \
|
echo "**** Section cleanup ****" \
|
||||||
&& pacman -Scc --noconfirm \
|
&& 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
|
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
|
# Add FS overlay
|
||||||
COPY 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
|
# Set display environment variables
|
||||||
ENV \
|
ENV \
|
||||||
DISPLAY_CDEPTH="24" \
|
DISPLAY_CDEPTH="24" \
|
||||||
DISPLAY_REFRESH="120" \
|
DISPLAY_REFRESH="60" \
|
||||||
DISPLAY_SIZEH="900" \
|
DISPLAY_SIZEH="900" \
|
||||||
DISPLAY_SIZEW="1600" \
|
DISPLAY_SIZEW="1600" \
|
||||||
DISPLAY_VIDEO_PORT="DFP" \
|
DISPLAY_VIDEO_PORT="DFP" \
|
||||||
DISPLAY=":55"
|
DISPLAY=":55" \
|
||||||
ENV \
|
|
||||||
NVIDIA_DRIVER_CAPABILITIES="all" \
|
NVIDIA_DRIVER_CAPABILITIES="all" \
|
||||||
NVIDIA_VISIBLE_DEVICES="all"
|
NVIDIA_VISIBLE_DEVICES="all"
|
||||||
|
|
||||||
# Set container configuration environment variables
|
# Set container configuration environment variables
|
||||||
# APPIMAGE_EXTRACT_AND_RUN="0"
|
|
||||||
ENV \
|
ENV \
|
||||||
MODE="primary" \
|
MODE="primary" \
|
||||||
WEB_UI_MODE="vnc" \
|
ENABLE_VNC_AUDIO="true"
|
||||||
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
|
# Configure required ports
|
||||||
ENV \
|
ENV \
|
||||||
PORT_NOVNC_WEB="8083" \
|
PORT_SSH="" \
|
||||||
NEKO_NAT1TO1=""
|
PORT_NOVNC_WEB="8083"
|
||||||
|
|
||||||
# Expose the required ports
|
# Expose the required ports
|
||||||
EXPOSE 8083
|
EXPOSE 8083
|
||||||
|
|||||||
18
README.md
18
README.md
@@ -2,22 +2,14 @@
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
Remote Game Streaming Server.
|
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.
|
||||||
|
|
||||||
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:
|
## Features:
|
||||||
- Steam Client configured for running on Linux with Proton
|
- NVIDIA GPU support
|
||||||
- Moonlight compatible server for easy remote desktop streaming
|
- AMD GPU support
|
||||||
- Easy installation of EmeDeck, Heroic and Lutris via Flatpak
|
|
||||||
- Full video/audio noVNC web access to a Xfce4 Desktop
|
- 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
|
- Root access
|
||||||
- Based on Debian Bookworm
|
|
||||||
|
|
||||||
---
|
---
|
||||||
## Notes:
|
## Notes:
|
||||||
@@ -26,8 +18,6 @@ Easily deploy a Steam Docker instance in seconds.
|
|||||||
If you wish to install additional applications, you can generate a script inside the `~/init.d` directory ending with ".sh".
|
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.
|
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:
|
### 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.
|
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.
|
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.
|
||||||
|
|||||||
136
devops/run_server.sh
Executable file
136
devops/run_server.sh
Executable file
@@ -0,0 +1,136 @@
|
|||||||
|
#!/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,20 +5,19 @@
|
|||||||
# |____/ \__, |___/\__\___|_| |_| |_|
|
# |____/ \__, |___/\__\___|_| |_| |_|
|
||||||
# |___/
|
# |___/
|
||||||
#
|
#
|
||||||
NAME=SteamHeadless
|
NAME='SteamHeadless'
|
||||||
TZ=Pacific/Auckland
|
TZ='Pacific/Auckland'
|
||||||
USER_LOCALES=en_US.UTF-8 UTF-8
|
USER_LOCALES='en_US.UTF-8 UTF-8'
|
||||||
DISPLAY=:55
|
DISPLAY=':55'
|
||||||
SHM_SIZE=2G
|
SHM_SIZE='2G'
|
||||||
## HOME_DIR:
|
|
||||||
## Description: The path to the home directory on your host. Mounts to `/home/default` inside the container.
|
## DOCKER_RUNTIME:
|
||||||
HOME_DIR=/opt/container-data/steam-headless/home
|
## Options: ['runc', 'nvidia']
|
||||||
## SHARED_SOCKETS_DIR:
|
## Description: The name of an implementation of OCI Runtime Spec
|
||||||
## Description: Shared sockets such as pulse audio and X11.
|
## Available runtimes are listed when you run `docker info`.
|
||||||
SHARED_SOCKETS_DIR=/opt/container-data/steam-headless/sockets
|
## Your system may have other options available. As a simple rule, if you are
|
||||||
## GAMES_DIR:
|
## using an NVIDIA GPU, set this to 'nvidia' for anything else, set this to 'runc'.
|
||||||
## Description: The path to the games directory on your host. Mounts to `/mnt/games` inside the container.
|
DOCKER_RUNTIME='runc'
|
||||||
GAMES_DIR=/mnt/games
|
|
||||||
|
|
||||||
# ____ __ _ _ _ _
|
# ____ __ _ _ _ _
|
||||||
# | _ \ ___ / _| __ _ _ _| | |_ | | | |___ ___ _ __
|
# | _ \ ___ / _| __ _ _ _| | |_ | | | |___ ___ _ __
|
||||||
@@ -27,24 +26,10 @@ GAMES_DIR=/mnt/games
|
|||||||
# |____/ \___|_| \__,_|\__,_|_|\__| \___/|___/\___|_|
|
# |____/ \___|_| \__,_|\__,_|_|\__| \___/|___/\___|_|
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
PUID=1000
|
PUID='1000'
|
||||||
PGID=1000
|
PGID='1000'
|
||||||
UMASK=000
|
UMASK='000'
|
||||||
USER_PASSWORD=password
|
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
|
|
||||||
|
|
||||||
# ____ _
|
# ____ _
|
||||||
# / ___| ___ _ ____ _(_) ___ ___ ___
|
# / ___| ___ _ ____ _(_) ___ ___ ___
|
||||||
@@ -53,74 +38,54 @@ MODE=primary
|
|||||||
# |____/ \___|_| \_/ |_|\___\___||___/
|
# |____/ \___|_| \_/ |_|\___\___||___/
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
# 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
|
||||||
## WEB_UI_MODE:
|
## WEB_UI_MODE:
|
||||||
## Options: ['vnc', 'neko', 'none']
|
## Options: ['vnc', 'neko', 'none']
|
||||||
## Description: Configures the WebUI to use for accessing the virtual desktop.
|
## Description: Configures the WebUI to use for accessing the virtual desktop.
|
||||||
## Supported Modes: ['primary']
|
WEB_UI_MODE='vnc'
|
||||||
WEB_UI_MODE=vnc
|
|
||||||
## ENABLE_VNC_AUDIO:
|
## ENABLE_VNC_AUDIO:
|
||||||
## Options: ['true', 'false']
|
## Options: ['true', 'false']
|
||||||
## Description: Enables audio over for the VNC Web UI if 'WEB_UI_MODE' is set to 'vnc'.
|
## 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:
|
## PORT_NOVNC_WEB:
|
||||||
## Description: Configure the port to use for the WebUI.
|
## Description: Configure the port to use for the WebUI.
|
||||||
PORT_NOVNC_WEB=8083
|
PORT_NOVNC_WEB='8083'
|
||||||
## NEKO_NAT1TO1:
|
## NEKO_NAT1TO1:
|
||||||
## Description: Configure nat1to1 for the neko WebUI if it is enabled by setting 'WEB_UI_MODE' to 'neko'.
|
## 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.
|
||||||
## This will need to be the IP address of the host.
|
NEKO_NAT1TO1=''
|
||||||
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
|
# Sunshine
|
||||||
## ENABLE_SUNSHINE:
|
## ENABLE_SUNSHINE:
|
||||||
## Options: ['true', 'false']
|
## Options: ['true', 'false']
|
||||||
## Description: Enable Sunshine streaming service.
|
## Description: Enable Sunshine streaming service.
|
||||||
## Supported Modes: ['primary']
|
ENABLE_SUNSHINE='false'
|
||||||
ENABLE_SUNSHINE=false
|
|
||||||
## SUNSHINE_USER:
|
## SUNSHINE_USER:
|
||||||
## Description: Set the Sunshine service username.
|
## Description: Set the Sunshine service username.
|
||||||
SUNSHINE_USER=admin
|
#SUNSHINE_USER='admin'
|
||||||
## SUNSHINE_PASS:
|
## SUNSHINE_PASS:
|
||||||
## Description: Set the Sunshine service password.
|
## Description: Set the Sunshine service password.
|
||||||
SUNSHINE_PASS=admin
|
#SUNSHINE_PASS='admin'
|
||||||
|
|
||||||
# Xorg
|
# Xorg
|
||||||
## ENABLE_EVDEV_INPUTS:
|
## ENABLE_EVDEV_INPUTS:
|
||||||
## Available Options: ['true', 'false']
|
## Options: ['true', 'false']
|
||||||
## Description: Enable Keyboard and Mouse Passthrough. This will configure the Xorg server to catch all
|
## Description: Enable Keyboard and Mouse Passthrough. This will configure the Xorg server to catch all evdev events for Keyboard, Mouse, etc.
|
||||||
## evdev events for Keyboard, Mouse, etc.
|
ENABLE_EVDEV_INPUTS='true'
|
||||||
## 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 specific config (not required for non Nvidia GPUs)
|
||||||
## NVIDIA_DRIVER_CAPABILITIES:
|
## NVIDIA_DRIVER_CAPABILITIES:
|
||||||
## Options: ['all', 'compute', 'compat32', 'graphics', 'utility', 'video', 'display']
|
## Options: ['all', 'compute', 'compat32', 'graphics', 'utility', 'video', 'display']
|
||||||
## Description: Controls which driver libraries/binaries will be mounted inside the container.
|
## Description: Controls which driver libraries/binaries will be mounted inside the container.
|
||||||
## Supported Modes: ['primary', 'secondary']
|
NVIDIA_DRIVER_CAPABILITIES='all'
|
||||||
NVIDIA_DRIVER_CAPABILITIES=all
|
|
||||||
## NVIDIA_DRIVER_CAPABILITIES:
|
## NVIDIA_DRIVER_CAPABILITIES:
|
||||||
## Available Options: ['all', 'none', '<GPU UUID>']
|
## Options: ['all', 'none', '<GPU UUID>']
|
||||||
## Description: Controls which GPUs will be made accessible inside the container.
|
## Description: Controls which GPUs will be made accessible inside the container.
|
||||||
## Supported Modes: ['primary', 'secondary']
|
NVIDIA_VISIBLE_DEVICES='all'
|
||||||
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=
|
|
||||||
|
|||||||
@@ -1,76 +0,0 @@
|
|||||||
---
|
|
||||||
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
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
---
|
|
||||||
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
|
|
||||||
50
docs/compose-files/docker-compose.default.yml
Normal file
50
docs/compose-files/docker-compose.default.yml
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
---
|
||||||
|
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:
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
---
|
|
||||||
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
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
---
|
|
||||||
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.
|
> Depending on how you have installed this, the commands to execute docker compose may vary.
|
||||||
|
|
||||||
|
|
||||||
## PREPARE DIRECTORIES:
|
## PREPARE DIRECTORY:
|
||||||
|
|
||||||
> __Warning__
|
> __Warning__
|
||||||
>
|
>
|
||||||
@@ -18,78 +18,24 @@ 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.
|
> 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:
|
Create a directory for your service:
|
||||||
```shell
|
```
|
||||||
sudo mkdir -p /opt/container-services/steam-headless
|
sudo mkdir -p /opt/container-services/steam-headless
|
||||||
sudo chown -R $(id -u):$(id -g) /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:
|
Create a directory for your service config data:
|
||||||
```shell
|
```
|
||||||
sudo mkdir -p /opt/container-data/steam-headless/{home,.X11-unix,pulse}
|
sudo mkdir -p /opt/container-data/steam-headless/{home,.X11-unix,pulse}
|
||||||
sudo chown -R $(id -u):$(id -g) /opt/container-data/steam-headless
|
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.
|
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
|
Populate this file with the contents of the default [Docker Compose File](./compose-files/docker-compose.default.yml).
|
||||||
|
|
||||||
### 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:
|
## 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).
|
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.
|
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)
|
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 30 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.2 MiB |
@@ -1,25 +0,0 @@
|
|||||||
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
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
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
16
docs/k8s.md
@@ -1,16 +0,0 @@
|
|||||||
# 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/*`
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
## 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,57 +1,22 @@
|
|||||||
# Ubuntu Server Setup
|
# Ubuntu Server
|
||||||
|
|
||||||
Use these instructions to install **Steam Headless** on an Ubuntu Server system.
|
Follow these instructions to install Steam Headless on Ubuntu Server.
|
||||||
|
|
||||||
> ⚠️ **Note**
|
> __Note__
|
||||||
>
|
>
|
||||||
> These steps assume you are running a minimal **Ubuntu Server** installation **without any desktop environment**.
|
> This assumes that your Ubuntu Server has not be configured to run any desktop environment!
|
||||||
> This setup **will not work** on Ubuntu Desktop.
|
>
|
||||||
|
> This will not work with 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:
|
||||||
|
|
||||||
Install `docker-ce` on your Ubuntu server by following the [official Docker instructions](https://docs.docker.com/engine/install/ubuntu/).
|
Install docker-ce to your Ubuntu server following the [official instrctions](https://docs.docker.com/engine/install/ubuntu/).
|
||||||
|
|
||||||
Make sure you also install the `docker-compose-plugin` as noted in the Docker documentation.
|
Ensure you install the `docker-compose-plugin` mentioned within these instructions
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 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:
|
## CONFIGURE DOCKER COMPOSE:
|
||||||
|
|
||||||
After installing Docker, proceed to the [Compose Files](./docker-compose.md) section and select the appropriate configuration for your hardware setup.
|
Once you have installed docker, follow the [Compose Files](./docker-compose.md) section and select the right configuration file for your hardware.
|
||||||
|
|
||||||
|
|||||||
@@ -22,71 +22,44 @@ if [[ -f /version.txt ]]; then
|
|||||||
cat /version.txt
|
cat /version.txt
|
||||||
fi
|
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
|
# Execute all container init scripts
|
||||||
for init_script in /etc/cont-init.d/*.sh ; do
|
for init_script in /etc/cont-init.d/*.sh ; do
|
||||||
echo
|
echo
|
||||||
echo -e "\e[34m[ ${init_script:?}: executing... ]\e[0m"
|
echo "[ ${init_script}: executing... ]"
|
||||||
sed -i 's/\r$//' "${init_script:?}"
|
sed -i 's/\r$//' "${init_script}"
|
||||||
source "${init_script:?}"
|
source "${init_script}"
|
||||||
done
|
done
|
||||||
touch /tmp/.first-run-init-scripts
|
|
||||||
|
|
||||||
# Execute any user generated init scripts
|
# Execute any user generated init scripts
|
||||||
mkdir -p ${USER_HOME:?}/init.d
|
mkdir -p ${USER_HOME}/init.d
|
||||||
chown -R ${USER:?} ${USER_HOME:?}/init.d
|
chown -R ${USER} ${USER_HOME}/init.d
|
||||||
for user_init_script in ${USER_HOME:?}/init.d/*.sh ; do
|
for user_init_script in ${USER_HOME}/init.d/*.sh ; do
|
||||||
|
|
||||||
# Check that a file was found
|
# Check that a file was found
|
||||||
# (If no files exist in this directory, then user_init_script will be empty)
|
# (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
|
||||||
echo -e "\e[34m[ USER:${user_init_script:?}: executing... ]\e[0m"
|
echo "[ USER:${user_init_script}: executing... ]"
|
||||||
sed -i 's/\r$//' "$(readlink -e "${user_init_script:?}")"
|
sed -i 's/\r$//' "${user_init_script}"
|
||||||
|
|
||||||
# Execute user script in sub process with 'set +e'.
|
# Execute user script in sub process.
|
||||||
# This way if it is messed up, we dont get caught in an init loop.
|
# This way if it is messed up, we dont get caught in an init loop
|
||||||
chmod +x "${user_init_script:?}"
|
chmod +x "${user_init_script}"
|
||||||
(
|
cat "${user_init_script}" | bash
|
||||||
set +e
|
|
||||||
"${user_init_script:?}" || echo -e "\e[31mERROR: \e[33mFailed to execute user script '${user_init_script:?}'\e[0m"
|
|
||||||
)
|
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
done
|
done
|
||||||
touch /tmp/.first-run-user-init-scripts
|
|
||||||
|
# Ensure all scripts are executable
|
||||||
|
chmod a+rwx /opt/scripts/*.sh
|
||||||
|
|
||||||
# Start supervisord
|
# Start supervisord
|
||||||
echo
|
echo
|
||||||
print_header "Starting supervisord";
|
echo "**** Starting supervisord ****";
|
||||||
print_step_header "Logging all root services to '/var/log/supervisor/'"
|
echo "Logging all root services to '/var/log/supervisor/'"
|
||||||
print_step_header "Logging all user services to '/home/${USER:?}/.cache/log/'"
|
echo "Logging all user services to '/home/${USER}/.cache/log/'"
|
||||||
echo
|
echo
|
||||||
mkdir -p /var/log/supervisor
|
mkdir -p /var/log/supervisor
|
||||||
chmod a+rw /var/log/supervisor
|
chmod a+rw /var/log/supervisor
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
# File Created: Friday, 12th January 2022 8:54:01 am
|
# File Created: Friday, 12th January 2022 8:54:01 am
|
||||||
# Author: Josh.5 (jsunnex@gmail.com)
|
# Author: Josh.5 (jsunnex@gmail.com)
|
||||||
# -----
|
# -----
|
||||||
# Last Modified: Monday, 10th July 2023 5:56:17 pm
|
# Last Modified: Tuesday, 4th October 2022 11:27:10 am
|
||||||
# Modified By: Console and webGui login account (jsunnex@gmail.com)
|
# Modified By: Josh.5 (jsunnex@gmail.com)
|
||||||
###
|
###
|
||||||
|
|
||||||
PUID=${PUID:-99}
|
PUID=${PUID:-99}
|
||||||
@@ -14,21 +14,18 @@ PGID=${PGID:-100}
|
|||||||
UMASK=${UMASK:-000}
|
UMASK=${UMASK:-000}
|
||||||
USER_PASSWORD=${USER_PASSWORD:-password}
|
USER_PASSWORD=${USER_PASSWORD:-password}
|
||||||
|
|
||||||
print_header "Configure default user"
|
echo "**** Configure default user ****"
|
||||||
|
|
||||||
print_step_header "Setting default user uid=${PUID}(${USER}) gid=${PGID}(${USER})"
|
echo "Setting default user uid=${PUID}(${USER}) gid=${PGID}(${USER})"
|
||||||
usermod -o -u "${PUID}" ${USER}
|
usermod -o -u "${PUID}" ${USER}
|
||||||
groupmod -o -g "${PGID}" ${USER}
|
groupmod -o -g "${PGID}" ${USER}
|
||||||
|
|
||||||
|
|
||||||
print_step_header "Adding default user to any additional required device groups"
|
echo "Adding default user to video, audio, input and pulse groups"
|
||||||
additional_groups=( video audio input pulse )
|
usermod -a -G video,audio,input,pulse ${USER}
|
||||||
for group_name in "${additional_groups[@]}"; do
|
|
||||||
if [ $(getent group ${group_name:?}) ]; then
|
|
||||||
print_step_header "Adding user '${USER}' to group: '${group_name}'"
|
echo "Adding default user to any additional required device groups"
|
||||||
usermod -aG ${group_name:?} ${USER}
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
device_nodes=( /dev/uinput /dev/input/event* /dev/dri/* )
|
device_nodes=( /dev/uinput /dev/input/event* /dev/dri/* )
|
||||||
added_groups=""
|
added_groups=""
|
||||||
for dev in "${device_nodes[@]}"; do
|
for dev in "${device_nodes[@]}"; do
|
||||||
@@ -54,20 +51,20 @@ for dev in "${device_nodes[@]}"; do
|
|||||||
|
|
||||||
# Add group to user
|
# Add group to user
|
||||||
if [[ "${added_groups}" != *"${dev_group}"* ]]; then
|
if [[ "${added_groups}" != *"${dev_group}"* ]]; then
|
||||||
print_step_header "Adding user '${USER}' to group: '${dev_group}' for device: ${dev}"
|
echo "Adding user '${USER}' to group: '${dev_group}' for device: ${dev}"
|
||||||
usermod -aG ${dev_group} ${USER}
|
usermod -a -G ${dev_group} ${USER}
|
||||||
added_groups=" ${added_groups} ${dev_group} "
|
added_groups=" ${added_groups} ${dev_group} "
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
||||||
print_step_header "Setting umask to ${UMASK}";
|
echo "Setting umask to ${UMASK}";
|
||||||
umask ${UMASK}
|
umask ${UMASK}
|
||||||
|
|
||||||
|
|
||||||
# TODO: Move this to its own 'display' init script. It does not really belong here
|
# TODO: Move this to its own 'display' init script. It does not really belong here
|
||||||
# Configure the 'XDG_RUNTIME_DIR' path
|
# Configure the 'XDG_RUNTIME_DIR' path
|
||||||
print_step_header "Create the user XDG_RUNTIME_DIR path '${XDG_RUNTIME_DIR}'"
|
echo "Create the user XDG_RUNTIME_DIR path '${XDG_RUNTIME_DIR}'"
|
||||||
mkdir -p ${XDG_RUNTIME_DIR}
|
mkdir -p ${XDG_RUNTIME_DIR}
|
||||||
# Ensure it is owned by the 'default' user
|
# Ensure it is owned by the 'default' user
|
||||||
chown -R ${PUID}:${PGID} ${XDG_RUNTIME_DIR}
|
chown -R ${PUID}:${PGID} ${XDG_RUNTIME_DIR}
|
||||||
@@ -79,20 +76,27 @@ ln -sf /usr/share/backgrounds/steam.jpg /etc/alternatives/desktop-background
|
|||||||
chmod a+r /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
|
# Setup services log path
|
||||||
print_step_header "Setting ownership of all log files in '${USER_HOME}/.cache/log'"
|
echo "Setting ownership of all log files in '${USER_HOME}/.cache/log'"
|
||||||
mkdir -p "${USER_HOME}/.cache/log"
|
mkdir -p "${USER_HOME}/.cache/log"
|
||||||
chown -R ${PUID}:${PGID} "${USER_HOME}/.cache/log"
|
chown -R ${PUID}:${PGID} "${USER_HOME}/.cache/log"
|
||||||
|
|
||||||
|
|
||||||
# Set the root and user password
|
# Set the root and user password
|
||||||
print_step_header "Setting root password"
|
echo "Setting root password"
|
||||||
echo "root:${USER_PASSWORD}" | chpasswd
|
echo "root:${USER_PASSWORD}" | chpasswd
|
||||||
print_step_header "Setting user password"
|
echo "Setting user password"
|
||||||
echo "${USER}:${USER_PASSWORD}" | chpasswd
|
echo "${USER}:${USER_PASSWORD}" | chpasswd
|
||||||
|
|
||||||
# Set root XDG_RUNTIME_DIR path
|
# Set root XDG_RUNTIME_DIR path
|
||||||
mkdir -p /tmp/runtime-root
|
mkdir -p /tmp/runtime-root
|
||||||
chown root:root /tmp/runtime-root
|
chown root:root /tmp/runtime-root
|
||||||
|
|
||||||
echo -e "\e[34mDONE\e[0m"
|
echo "DONE"
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
|
|
||||||
# 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"
|
|
||||||
21
overlay/etc/cont-init.d/20-configre_sshd.sh
Normal file
21
overlay/etc/cont-init.d/20-configre_sshd.sh
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
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,32 +1,26 @@
|
|||||||
|
|
||||||
# Configure dbus
|
# Configure dbus
|
||||||
print_header "Configure container dbus"
|
echo "**** Configure container dbus ****";
|
||||||
|
if [[ "${HOST_DBUS}" == "true" ]]; then
|
||||||
if ([ "${MODE}" != "s" ] && [ "${MODE}" != "secondary" ]); then
|
echo "Container configured to use the host dbus";
|
||||||
if [[ "${HOST_DBUS}" == "true" ]]; then
|
# Disable supervisord script
|
||||||
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
|
|
||||||
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
|
|
||||||
sed -i "/ <user>/c\ <user>${USER}</user>" /usr/share/dbus-1/system.conf
|
|
||||||
# Remove old dbus session
|
|
||||||
rm -rf ${USER_HOME}/.dbus/session-bus/* 2> /dev/null
|
|
||||||
# Remove old dbus pids
|
|
||||||
mkdir -p /var/run/dbus
|
|
||||||
chown -R ${PUID}:${PGID} /var/run/dbus/
|
|
||||||
chmod -R 770 /var/run/dbus/
|
|
||||||
# Generate a dbus machine ID
|
|
||||||
dbus-uuidgen > /var/lib/dbus/machine-id
|
|
||||||
# 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
|
sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/dbus.ini
|
||||||
|
else
|
||||||
|
echo "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
|
||||||
|
sed -i "/ <user>/c\ <user>${USER}</user>" /usr/share/dbus-1/system.conf
|
||||||
|
# Remove old dbus session
|
||||||
|
rm -rf ${USER_HOME}/.dbus/session-bus/* 2> /dev/null
|
||||||
|
# Remove old dbus pids
|
||||||
|
mkdir -p /var/run/dbus
|
||||||
|
chown -R ${PUID}:${PGID} /var/run/dbus/
|
||||||
|
chmod -R 770 /var/run/dbus/
|
||||||
|
# Generate a dbus machine ID
|
||||||
|
dbus-uuidgen > /var/lib/dbus/machine-id
|
||||||
|
# Remove old lockfiles
|
||||||
|
find /var/run/dbus -name "pid" -exec rm -f {} \;
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo -e "\e[34mDONE\e[0m"
|
echo "DONE"
|
||||||
|
|||||||
@@ -1,51 +1,46 @@
|
|||||||
|
#!/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)
|
||||||
|
###
|
||||||
|
|
||||||
# Configure dbus
|
# Running udev only works in privileged container
|
||||||
print_header "Configure udevd"
|
# 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}"
|
||||||
|
|
||||||
# Since this container may also be run with CAP_SYS_ADMIN, ensure we can actually execute "udevadm trigger"
|
|
||||||
run_dumb_udev="false"
|
if [[ "${is_privileged}" == "true" ]]; then
|
||||||
if [ ! -w /sys ]; then
|
echo "**** Configure container to run udev management ****";
|
||||||
# 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
|
# Enable supervisord script
|
||||||
sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/udev.ini
|
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
|
# Configure udev permissions
|
||||||
if [[ -f /lib/udev/rules.d/60-steam-input.rules ]]; then
|
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
|
sed -i 's/MODE="0660"/MODE="0666"/' /lib/udev/rules.d/60-steam-input.rules
|
||||||
fi
|
fi
|
||||||
run_dumb_udev="false"
|
|
||||||
else
|
else
|
||||||
# Disable supervisord script since we are not able to execute "udevadm trigger"
|
# Disable supervisord script
|
||||||
print_step_header "Disable udev service due to privilege restrictions"
|
|
||||||
sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/udev.ini
|
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
|
fi
|
||||||
|
|
||||||
|
|
||||||
if [[ -e /dev/uinput ]]; then
|
if [[ -e /dev/uinput ]]; then
|
||||||
print_step_header "Ensure the default user has permission to r/w on input devices"
|
echo "**** Ensure the default user has permission to r/w on input devices ****";
|
||||||
chmod 0666 /dev/uinput
|
chmod 0666 /dev/uinput
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo -e "\e[34mDONE\e[0m"
|
echo "DONE"
|
||||||
|
|||||||
@@ -1,22 +1,19 @@
|
|||||||
|
|
||||||
# Configure dbus
|
|
||||||
print_header "Configure local"
|
|
||||||
|
|
||||||
current_local=$(head -n 1 /etc/locale.gen)
|
current_local=$(head -n 1 /etc/locale.gen)
|
||||||
user_local=$(echo ${USER_LOCALES} | cut -d ' ' -f 1)
|
user_local=$(echo ${USER_LOCALES} | cut -d ' ' -f 1)
|
||||||
|
|
||||||
if [ "${current_local}" != "${USER_LOCALES}" ]; then
|
if [ "${current_local}" != "${USER_LOCALES}" ]; then
|
||||||
print_step_header "Configuring Locales to ${USER_LOCALES}"
|
echo "**** Configuring Locales to ${USER_LOCALES} ****";
|
||||||
rm /etc/locale.gen
|
rm /etc/locale.gen
|
||||||
echo -e "${USER_LOCALES}\nen_US.UTF-8 UTF-8" > "/etc/locale.gen"
|
echo -e "${USER_LOCALES}\nen_US.UTF-8 UTF-8" > "/etc/locale.gen"
|
||||||
export LANGUAGE="${user_local}"
|
export LANGUAGE="${user_local}"
|
||||||
export LANG="${user_local}"
|
export LANG="${user_local}"
|
||||||
export LC_ALL="${user_local}" 2> /dev/null
|
export LC_ALL="${user_local}" 2> /dev/null
|
||||||
sleep 0.5
|
sleep 2
|
||||||
locale-gen
|
locale-gen
|
||||||
update-locale LC_ALL="${user_local}"
|
update-locale LC_ALL="${user_local}"
|
||||||
else
|
else
|
||||||
print_step_header "Locales already set correctly to ${USER_LOCALES}"
|
echo "**** Locales already set correctly to ${USER_LOCALES} ****";
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo -e "\e[34mDONE\e[0m"
|
echo "DONE"
|
||||||
|
|||||||
@@ -1,19 +1,14 @@
|
|||||||
|
|
||||||
# Configure dbus
|
echo "**** Configure pulseaudio ****"
|
||||||
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
|
if [ "${MODE}" == "s" ] | [ "${MODE}" == "secondary" ]; then
|
||||||
print_step_header "Configure pulseaudio as simple dummy audio"
|
echo "Configure pulseaudio as simple dummy audio"
|
||||||
sed -i 's|^; autospawn.*$|autospawn = no|' /etc/pulse/client.conf
|
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|^; daemon-binary.*$|daemon-binary = /bin/true|' /etc/pulse/client.conf
|
||||||
|
|
||||||
sed -i 's|^; flat-volumes.*$|flat-volumes = yes|' /etc/pulse/daemon.conf
|
sed -i 's|^; flat-volumes.*$|flat-volumes = yes|' /etc/pulse/daemon.conf
|
||||||
else
|
else
|
||||||
print_step_header "Configure pulseaudio to pipe audio to a socket"
|
echo "Configure pulseaudio to pipe audio to a socket"
|
||||||
|
|
||||||
# Ensure pulseaudio directories have the correct permissions
|
# Ensure pulseaudio directories have the correct permissions
|
||||||
mkdir -p \
|
mkdir -p \
|
||||||
@@ -38,4 +33,4 @@ else
|
|||||||
fi
|
fi
|
||||||
chown -R ${USER} /etc/pulse
|
chown -R ${USER} /etc/pulse
|
||||||
|
|
||||||
echo -e "\e[34mDONE\e[0m"
|
echo "DONE"
|
||||||
|
|||||||
@@ -1,22 +1,20 @@
|
|||||||
|
|
||||||
# Fech NVIDIA GPU device (if one exists)
|
# 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)
|
export gpu_select=$(nvidia-smi --format=csv --query-gpu=uuid 2> /dev/null | sed -n 2p)
|
||||||
elif [ "${NVIDIA_VISIBLE_DEVICES:-}X" = "X" ]; then
|
elif [ -z "${NVIDIA_VISIBLE_DEVICES:-}" ]; then
|
||||||
export gpu_select=$(nvidia-smi --format=csv --query-gpu=uuid 2>/dev/null | sed -n 2p)
|
export gpu_select=$(nvidia-smi --format=csv --query-gpu=uuid 2> /dev/null | sed -n 2p)
|
||||||
else
|
else
|
||||||
export gpu_select=$(nvidia-smi --format=csv --id=$(echo "$NVIDIA_VISIBLE_DEVICES" | cut -d ',' -f1) --query-gpu=uuid | sed -n 2p)
|
export gpu_select=$(nvidia-smi --format=csv --id=$(echo "$NVIDIA_VISIBLE_DEVICES" | cut -d ',' -f1) --query-gpu=uuid | sed -n 2p)
|
||||||
if [ "${gpu_select:-}X" = "X" ]; then
|
if [ -z "$gpu_select" ]; then
|
||||||
export gpu_select=$(nvidia-smi --format=csv --query-gpu=uuid 2>/dev/null | sed -n 2p)
|
export gpu_select=$(nvidia-smi --format=csv --query-gpu=uuid 2> /dev/null | sed -n 2p)
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# NVIDIA Params
|
# NVIDIA Params
|
||||||
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_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_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)"
|
||||||
export nvidia_host_driver_version="$(nvidia-smi 2>/dev/null | grep NVIDIA-SMI | cut -d ' ' -f3)"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Intel params
|
# Intel params
|
||||||
# This figures out if it's an intel CPU with integrated GPU
|
# This figures out if it's an intel CPU with integrated GPU
|
||||||
@@ -29,231 +27,123 @@ 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)"
|
export amd_gpu_model="$(lspci | grep -i vga | grep -i amd)"
|
||||||
|
|
||||||
function download_driver {
|
function download_driver {
|
||||||
local driver_url
|
mkdir -p ${USER_HOME}/Downloads
|
||||||
local stripped_version
|
chown -R ${USER} ${USER_HOME}/Downloads
|
||||||
|
|
||||||
mkdir -p "${USER_HOME:?}/Downloads"
|
if [[ ! -f "${USER_HOME}/Downloads/NVIDIA_${nvidia_host_driver_version}.run" ]]; then
|
||||||
chown -R ${USER:?} "${USER_HOME:?}/Downloads"
|
echo "Downloading driver v${nvidia_host_driver_version}"
|
||||||
|
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
|
||||||
|
|
||||||
if [[ ! -f "${USER_HOME:?}/Downloads/NVIDIA_${nvidia_host_driver_version:?}.run" ]]; then
|
mv /tmp/NVIDIA.run ${USER_HOME}/Downloads/NVIDIA_${nvidia_host_driver_version}.run
|
||||||
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 \
|
|
||||||
"${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
|
|
||||||
|
|
||||||
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
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
function install_nvidia_driver {
|
function install_nvidia_driver {
|
||||||
# Check here if the currently installed version matches using nvidia-settings
|
# 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=$(nvidia-settings --version 2> /dev/null | grep version | cut -d ' ' -f 4)
|
||||||
if [ "${nvidia_settings_version:-}X" != "${nvidia_host_driver_version:-}X" ]; then
|
[[ "${nvidia_settings_version}x" == "${nvidia_host_driver_version}x" ]] && return 0;
|
||||||
# Download the driver (if it does not yet exist locally)
|
|
||||||
download_driver
|
|
||||||
|
|
||||||
if (($(echo $nvidia_host_driver_version | cut -d '.' -f 1) >= 550)); then
|
# Download the driver (if it does not yet exist locally)
|
||||||
sed -i 's/--no-multigpu//g' /etc/cont-init.d/70-configure_xorg.sh
|
download_driver
|
||||||
fi
|
|
||||||
|
|
||||||
if (($(echo $nvidia_host_driver_version | cut -d '.' -f 1) > 500)); then
|
# if command -v pacman &> /dev/null; then
|
||||||
print_step_header "Installing NVIDIA driver v${nvidia_host_driver_version:?} to match what is running on the host"
|
# echo "Install NVIDIA vulkan utils" \
|
||||||
chmod +x "${USER_HOME:?}/Downloads/NVIDIA_${nvidia_host_driver_version:?}.run"
|
# && pacman -Syu --noconfirm --needed \
|
||||||
"${USER_HOME:?}/Downloads/NVIDIA_${nvidia_host_driver_version:?}.run" \
|
# lib32-nvidia-utils \
|
||||||
--silent \
|
# lib32-vulkan-icd-loader
|
||||||
--accept-license \
|
# nvidia-utils \
|
||||||
--skip-depmod \
|
# vulkan-icd-loader \
|
||||||
--skip-module-unload \
|
# && echo
|
||||||
--no-kernel-modules \
|
# fi
|
||||||
--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
|
|
||||||
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 {
|
echo "Installing NVIDIA driver v${nvidia_host_driver_version} to match what is running on the host"
|
||||||
# REF: https://github.com/keylase/nvidia-patch#docker-support
|
chmod +x ${USER_HOME}/Downloads/NVIDIA_${nvidia_host_driver_version}.run
|
||||||
if [ "${NVIDIA_PATCH_VERSION:-}X" != "X" ]; then
|
${USER_HOME}/Downloads/NVIDIA_${nvidia_host_driver_version}.run \
|
||||||
# Don't fail boot if something goes wrong here. Set +e
|
--silent \
|
||||||
(
|
--accept-license \
|
||||||
set +e
|
--skip-depmod \
|
||||||
if [ ! -f "${USER_HOME:?}/Downloads/nvidia-patch.${NVIDIA_PATCH_VERSION:?}.sh" ]; then
|
--skip-module-unload \
|
||||||
print_step_header "Fetch NVIDIA NVENC patch"
|
--no-kernel-modules \
|
||||||
wget -q --show-progress --progress=bar:force:noscroll \
|
--no-kernel-module-source \
|
||||||
-O "${USER_HOME:?}/Downloads/nvidia-patch.${NVIDIA_PATCH_VERSION:?}.sh" \
|
--install-compat32-libs \
|
||||||
"https://raw.githubusercontent.com/keylase/nvidia-patch/${NVIDIA_PATCH_VERSION:?}/patch.sh"
|
--no-nouveau-check \
|
||||||
fi
|
--no-nvidia-modprobe \
|
||||||
if [ ! -f "${USER_HOME:?}/Downloads/nvidia-patch-fbc.${NVIDIA_PATCH_VERSION:?}.sh" ]; then
|
--no-systemd \
|
||||||
print_step_header "Fetch NVIDIA NvFBC patch"
|
--no-distro-scripts \
|
||||||
wget -q --show-progress --progress=bar:force:noscroll \
|
--no-rpms \
|
||||||
-O "${USER_HOME:?}/Downloads/nvidia-patch-fbc.${NVIDIA_PATCH_VERSION:?}.sh" \
|
--no-backup \
|
||||||
"https://raw.githubusercontent.com/keylase/nvidia-patch/${NVIDIA_PATCH_VERSION:?}/patch-fbc.sh"
|
--no-check-for-alternate-installs \
|
||||||
fi
|
--no-libglx-indirect \
|
||||||
chmod +x \
|
--no-install-libglvnd \
|
||||||
"${USER_HOME:?}/Downloads/nvidia-patch.${NVIDIA_PATCH_VERSION:?}.sh" \
|
> ${USER_HOME}/Downloads/nvidia_gpu_install.log 2>&1
|
||||||
"${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 {
|
function install_amd_gpu_driver {
|
||||||
if command -v pacman &>/dev/null; then
|
echo "Install AMD vulkan driver"
|
||||||
print_step_header "Install AMD Mesa driver"
|
if command -v pacman &> /dev/null; then
|
||||||
pacman -Syu --noconfirm --needed \
|
pacman -Syu --noconfirm --needed \
|
||||||
|
lib32-mesa \
|
||||||
lib32-vulkan-icd-loader \
|
lib32-vulkan-icd-loader \
|
||||||
lib32-vulkan-radeon \
|
lib32-vulkan-radeon \
|
||||||
vulkan-icd-loader \
|
vulkan-icd-loader \
|
||||||
vulkan-radeon
|
vulkan-radeon
|
||||||
elif command -v apt-get &>/dev/null; then
|
# There is currently nothing to install inside the debian container. This already comes with the vulken drives that are required
|
||||||
install_deb_mesa
|
# 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
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
function install_intel_gpu_driver {
|
function install_intel_gpu_driver {
|
||||||
if command -v pacman &>/dev/null; then
|
echo "Install Intel vulkan driver"
|
||||||
print_step_header "Install Intel Mesa driver"
|
if command -v pacman &> /dev/null; then
|
||||||
pacman -Syu --noconfirm --needed \
|
pacman -Syu --noconfirm --needed \
|
||||||
|
lib32-mesa \
|
||||||
lib32-vulkan-icd-loader \
|
lib32-vulkan-icd-loader \
|
||||||
lib32-vulkan-intel \
|
lib32-vulkan-intel \
|
||||||
vulkan-icd-loader \
|
vulkan-icd-loader \
|
||||||
vulkan-intel
|
vulkan-intel
|
||||||
elif command -v apt-get &>/dev/null; then
|
# There is currently nothing to install inside the debian container. This already comes with the vulken drives that are required
|
||||||
install_deb_mesa
|
# 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
|
||||||
fi
|
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
|
# Intel Arc GPU or Intel CPU with possible iGPU
|
||||||
if [ "${intel_gpu_model:-}X" != "X" ]; then
|
if [[ ! -z ${intel_gpu_model} ]]; then
|
||||||
print_header "Found Intel device '${intel_gpu_model:?}'"
|
echo "**** Found Intel device '${intel_gpu_model}' ****";
|
||||||
install_intel_gpu_driver
|
install_intel_gpu_driver
|
||||||
elif [ "${intel_cpu_model:-}X" != "X" ]; then
|
elif [[ ! -z ${intel_cpu_model} ]]; then
|
||||||
print_header "Found Intel device '${intel_cpu_model:?}'"
|
echo "**** Found Intel device '${intel_cpu_model}' ****";
|
||||||
install_intel_gpu_driver
|
install_intel_gpu_driver
|
||||||
else
|
else
|
||||||
print_header "No Intel device found"
|
echo "**** No Intel device found ****";
|
||||||
fi
|
fi
|
||||||
# AMD GPU
|
# AMD GPU
|
||||||
if [ "${amd_gpu_model:-}X" != "X" ]; then
|
if [[ ! -z ${amd_gpu_model} ]]; then
|
||||||
print_header "Found AMD device '${amd_gpu_model:?}'"
|
echo "**** Found AMD device '${amd_gpu_model}' ****";
|
||||||
install_amd_gpu_driver
|
install_amd_gpu_driver
|
||||||
else
|
else
|
||||||
print_header "No AMD device found"
|
echo "**** 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
|
fi
|
||||||
|
|
||||||
echo -e "\e[34mDONE\e[0m"
|
echo "DONE"
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
|
|
||||||
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,42 +30,32 @@ fi
|
|||||||
|
|
||||||
# Configure a NVIDIA X11 config
|
# Configure a NVIDIA X11 config
|
||||||
function configure_nvidia_x_server {
|
function configure_nvidia_x_server {
|
||||||
print_step_header "Configuring X11 with GPU ID: '${gpu_select}'"
|
echo "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)
|
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})
|
IFS=":." ARR_ID=(${nvidia_gpu_hex_id})
|
||||||
unset IFS
|
unset IFS
|
||||||
bus_id=PCI:$((16#${ARR_ID[1]})):$((16#${ARR_ID[2]})):$((16#${ARR_ID[3]}))
|
bus_id=PCI:$((16#${ARR_ID[1]})):$((16#${ARR_ID[2]})):$((16#${ARR_ID[3]}))
|
||||||
print_step_header "Configuring X11 with PCI bus ID: '${bus_id}'"
|
echo "Configuring X11 with PCI bus ID: '${bus_id}'"
|
||||||
export MODELINE=$(cvt -r "${DISPLAY_SIZEW}" "${DISPLAY_SIZEH}" "${DISPLAY_REFRESH}" | sed -n 2p)
|
export MODELINE=$(cvt -r "${DISPLAY_SIZEW}" "${DISPLAY_SIZEH}" "${DISPLAY_REFRESH}" | sed -n 2p)
|
||||||
print_step_header "Writing X11 config with ${MODELINE}"
|
echo "Writing X11 config with ${MODELINE}"
|
||||||
connected_monitor="--use-display-device=None"
|
connected_monitor="--use-display-device=None"
|
||||||
if [[ "X${DISPLAY_VIDEO_PORT:-}" != "X" ]]; then
|
if [[ "X${DISPLAY_VIDEO_PORT:-}" != "X" ]]; then
|
||||||
connected_monitor="--connected-monitor=${DISPLAY_VIDEO_PORT:?}"
|
connected_monitor="--connected-monitor=${DISPLAY_VIDEO_PORT:?}"
|
||||||
fi
|
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:?}
|
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:?}
|
||||||
# Allow SteamHeadless to run with an eGPU
|
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
|
||||||
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
|
sed -i '/Section\s\+"Monitor"/a\ '"${MODELINE}" /etc/X11/xorg.conf
|
||||||
# Prevent interference between GPUs
|
# Prevent interference between GPUs
|
||||||
echo -e "Section \"ServerFlags\"\n Option \"AutoAddGPU\" \"false\"\nEndSection" | tee -a /etc/X11/xorg.conf > /dev/null
|
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
|
# Allow anybody for running x server
|
||||||
function configure_x_server {
|
function configure_x_server {
|
||||||
# Configure x to be run by anyone
|
# Configure x to be run by anyone
|
||||||
if [[ ! -f /etc/X11/Xwrapper.config ]]; then
|
if grep -Fxq "allowed_users=console" /etc/X11/Xwrapper.config; then
|
||||||
print_step_header "Create Xwrapper.config"
|
echo "Configure 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
|
sed -i "s/allowed_users=console/allowed_users=anybody/" /etc/X11/Xwrapper.config
|
||||||
echo 'needs_root_rights=yes' >> /etc/X11/Xwrapper.config
|
echo 'needs_root_rights=yes' >> /etc/X11/Xwrapper.config
|
||||||
fi
|
fi
|
||||||
@@ -79,7 +69,7 @@ function configure_x_server {
|
|||||||
# Clear out old lock files
|
# Clear out old lock files
|
||||||
display_file=${XORG_SOCKET_DIR}/X${DISPLAY#:}
|
display_file=${XORG_SOCKET_DIR}/X${DISPLAY#:}
|
||||||
if [ -S ${display_file} ]; then
|
if [ -S ${display_file} ]; then
|
||||||
print_step_header "Removing ${display_file} before starting"
|
echo "Removing ${display_file} before starting"
|
||||||
rm -f /tmp/.X${DISPLAY#:}-lock
|
rm -f /tmp/.X${DISPLAY#:}-lock
|
||||||
rm ${display_file}
|
rm ${display_file}
|
||||||
fi
|
fi
|
||||||
@@ -90,46 +80,43 @@ function configure_x_server {
|
|||||||
chmod 1777 /tmp/.ICE-unix/
|
chmod 1777 /tmp/.ICE-unix/
|
||||||
|
|
||||||
# Check if this container is being run as a secondary instance
|
# Check if this container is being run as a secondary instance
|
||||||
if ([ "${MODE}" = "p" ] || [ "${MODE}" = "primary" ]); then
|
if [ "${MODE}" == "p" ] | [ "${MODE}" == "primary" ]; then
|
||||||
print_step_header "Configure container as primary the X server"
|
echo "Configure container as primary the X server"
|
||||||
# Enable supervisord script
|
# Enable supervisord script
|
||||||
sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/xorg.ini
|
sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/xorg.ini
|
||||||
elif [ "${MODE}" == "fb" ] | [ "${MODE}" == "framebuffer" ]; then
|
elif [ "${MODE}" == "fb" ] | [ "${MODE}" == "framebuffer" ]; then
|
||||||
print_step_header "Configure container to use a virtual framebuffer as the X server"
|
echo "Configure container to use a virtual framebuffer as the X server"
|
||||||
# Disable xorg supervisord script
|
# Disable xorg supervisord script
|
||||||
sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/xorg.ini
|
sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/xorg.ini
|
||||||
# Enable xvfb supervisord script
|
# Enable xvfb supervisord script
|
||||||
sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/xvfb.ini
|
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
|
fi
|
||||||
|
|
||||||
# Enable KB/Mouse input capture with Xorg if configured
|
# Enable KB/Mouse input capture with Xorg if configured
|
||||||
if [ ${ENABLE_EVDEV_INPUTS:-} = "true" ]; then
|
if [ ${ENABLE_EVDEV_INPUTS:-} = "true" ]; then
|
||||||
print_step_header "Enabling evdev input class on pointers, keyboards, touchpads, touch screens, etc."
|
echo "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
|
cp -fv /usr/share/X11/xorg.conf.d/10-evdev.conf /etc/X11/xorg.conf.d/10-evdev.conf
|
||||||
else
|
else
|
||||||
print_step_header "Leaving evdev inputs disabled"
|
echo "Leaving evdev inputs disabled"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Configure dummy config if no monitor is connected (not applicable to NVIDIA)
|
# Configure dummy config if no monitor is connected (not applicable to NVIDIA)
|
||||||
if ([ "X${monitor_connected}" = "X" ] || [ "${FORCE_X11_DUMMY_CONFIG}" = "true" ]); then
|
if [[ "X${monitor_connected}" == "X" ]]; then
|
||||||
print_step_header "No monitors connected. Installing dummy xorg.conf"
|
echo "No monitors connected. Installing dummy xorg.conf"
|
||||||
# Use a dummy display input
|
# Use a dummy display input
|
||||||
cp -f /templates/xorg/xorg.dummy.conf /etc/X11/xorg.conf
|
cp -fv /templates/xorg/xorg.dummy.conf /etc/X11/xorg.conf
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
if ([ "${MODE}" != "s" ] && [ "${MODE}" != "secondary" ]); then
|
if ([ "${MODE}" != "s" ] && [ "${MODE}" != "secondary" ]); then
|
||||||
if [[ -z ${nvidia_gpu_hex_id} ]]; then
|
if [[ -z ${nvidia_gpu_hex_id} ]]; then
|
||||||
print_header "Generate default xorg.conf"
|
echo "**** Generate default xorg.conf ****";
|
||||||
configure_x_server
|
configure_x_server
|
||||||
else
|
else
|
||||||
print_header "Generate NVIDIA xorg.conf"
|
echo "**** Generate NVIDIA xorg.conf ****";
|
||||||
configure_x_server
|
configure_x_server
|
||||||
configure_nvidia_x_server
|
configure_nvidia_x_server
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo -e "\e[34mDONE\e[0m"
|
echo "DONE"
|
||||||
|
|||||||
24
overlay/etc/cont-init.d/80-configure-dind.sh
Normal file
24
overlay/etc/cont-init.d/80-configure-dind.sh
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
|
||||||
|
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"
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
|
|
||||||
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 @@
|
|||||||
|
|
||||||
print_header "Configure Neko"
|
echo "**** Configure Neko ****"
|
||||||
# REF: https://neko.m1k1o.net/#/getting-started/configuration
|
# REF: https://neko.m1k1o.net/#/getting-started/configuration
|
||||||
|
|
||||||
if ([ "${MODE}" != "s" ] && [ "${MODE}" != "secondary" ]); then
|
if ([ "${MODE}" != "s" ] && [ "${MODE}" != "secondary" ]); then
|
||||||
if [ ${WEB_UI_MODE} = "neko" ]; then
|
if [ ${WEB_UI_MODE} = "neko" ]; then
|
||||||
print_step_header "Enable Neko server"
|
echo "Enable Neko server"
|
||||||
sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/neko.ini
|
sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/neko.ini
|
||||||
|
|
||||||
# Make directories for neko
|
# Make directories for neko
|
||||||
@@ -15,9 +15,9 @@ if ([ "${MODE}" != "s" ] && [ "${MODE}" != "secondary" ]); then
|
|||||||
# Configure nat1to1 if it is not already set
|
# Configure nat1to1 if it is not already set
|
||||||
if [[ -z ${NEKO_NAT1TO1} ]]; then
|
if [[ -z ${NEKO_NAT1TO1} ]]; then
|
||||||
export NEKO_NAT1TO1=$(ip route get 1 | awk '{print $(NF-2);exit}')
|
export NEKO_NAT1TO1=$(ip route get 1 | awk '{print $(NF-2);exit}')
|
||||||
print_step_header "Setting NEKO_NAT1TO1=${NEKO_NAT1TO1}"
|
echo "Setting NEKO_NAT1TO1=${NEKO_NAT1TO1}"
|
||||||
else
|
else
|
||||||
print_step_header "User provided setting NEKO_NAT1TO1=${NEKO_NAT1TO1}"
|
echo "User provided setting NEKO_NAT1TO1=${NEKO_NAT1TO1}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Configure hardware acceleration if it is not already set
|
# 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}"
|
export NEKO_SCREEN="${DISPLAY_SIZEW}x${DISPLAY_SIZEH}@${DISPLAY_REFRESH}"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
print_step_header "Disable Neko server"
|
echo "Disable Neko server"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
print_step_header "Neko server not available when container is run in 'secondary' mode"
|
echo "Neko server not available when container is run in 'secondary' mode"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo -e "\e[34mDONE\e[0m"
|
echo "DONE"
|
||||||
|
|||||||
@@ -1,134 +0,0 @@
|
|||||||
|
|
||||||
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 @@
|
|||||||
|
|
||||||
print_header "Configure Sunshine"
|
echo "**** Configure Sunshine ****"
|
||||||
|
|
||||||
if ([ "${MODE}" != "s" ] && [ "${MODE}" != "secondary" ]); then
|
if ([ "${MODE}" != "s" ] && [ "${MODE}" != "secondary" ]); then
|
||||||
if [ "${ENABLE_SUNSHINE:-}" = "true" ]; then
|
if [ "${ENABLE_SUNSHINE:-}" = "true" ]; then
|
||||||
print_step_header "Enable Sunshine server"
|
echo "Enable Sunshine server"
|
||||||
sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/sunshine.ini
|
sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/sunshine.ini
|
||||||
else
|
else
|
||||||
print_step_header "Disable Sunshine server"
|
echo "Disable Sunshine server"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
print_step_header "Sunshine server not available when container is run in 'secondary' mode"
|
echo "Sunshine server not available when container is run in 'secondary' mode"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo -e "\e[34mDONE\e[0m"
|
echo "DONE"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
print_header "Configure VNC"
|
echo "**** Configure VNC ****"
|
||||||
|
|
||||||
function get_next_unused_port() {
|
function get_next_unused_port() {
|
||||||
local __start_port=${1}
|
local __start_port=${1}
|
||||||
@@ -15,37 +15,66 @@ 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
|
# 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
|
# 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_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}
|
export PORT_VNC=${PORT_VNC:-$DYNAMIC_PORT_VNC}
|
||||||
print_step_header "Configure VNC service port '${PORT_VNC}'"
|
echo "Configure VNC service port '${PORT_VNC}'"
|
||||||
DYNAMIC_PORT_AUDIO_STREAM=$(get_next_unused_port ${DYNAMIC_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}'"
|
||||||
export PORT_AUDIO_STREAM=${PORT_AUDIO_STREAM:-$DYNAMIC_PORT_AUDIO_STREAM}
|
export PORT_AUDIO_STREAM=${PORT_AUDIO_STREAM:-$DYNAMIC_PORT_AUDIO_STREAM}
|
||||||
print_step_header "Configure pulseaudio encoded stream port '${PORT_AUDIO_STREAM}'"
|
echo "Configure pulseaudio encoded stream port '${PORT_AUDIO_STREAM}'"
|
||||||
|
|
||||||
if ([ "${MODE}" != "s" ] && [ "${MODE}" != "secondary" ]); then
|
if ([ "${MODE}" != "s" ] && [ "${MODE}" != "secondary" ]); then
|
||||||
|
|
||||||
if [ "${WEB_UI_MODE:-}" = "vnc" ]; then
|
if [ ${WEB_UI_MODE} = "vnc" ]; then
|
||||||
print_step_header "Enable VNC server"
|
echo "Enable VNC server"
|
||||||
sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/vnc.ini
|
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
|
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
|
# Enable supervisord script
|
||||||
sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/vnc-audio.ini
|
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
|
else
|
||||||
print_step_header "Disable audio stream"
|
echo "Disable audio stream"
|
||||||
print_step_header "Disable audio websock"
|
echo "Disable audio websock"
|
||||||
# Disable supervisord script
|
# Disable supervisord script
|
||||||
sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/vnc-audio.ini
|
sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/vnc-audio.ini
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
print_step_header "Disable VNC server"
|
echo "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
|
fi
|
||||||
else
|
else
|
||||||
print_step_header "VNC server not available when container is run in 'secondary' mode"
|
echo "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
|
fi
|
||||||
|
|
||||||
echo -e "\e[34mDONE\e[0m"
|
echo "DONE"
|
||||||
|
|||||||
37
overlay/etc/cont-init.d/95-configure_secondary.sh
Normal file
37
overlay/etc/cont-init.d/95-configure_secondary.sh
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
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"
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
#!/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
|
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
[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
|
||||||
@@ -47,25 +47,4 @@
|
|||||||
</property>
|
</property>
|
||||||
</property>
|
</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>
|
</channel>
|
||||||
@@ -7,14 +7,15 @@
|
|||||||
<property name="dark-mode" type="bool" value="true"/>
|
<property name="dark-mode" type="bool" value="true"/>
|
||||||
<property name="panel-1" type="empty">
|
<property name="panel-1" type="empty">
|
||||||
<property name="position" type="string" value="p=6;x=0;y=0"/>
|
<property name="position" type="string" value="p=6;x=0;y=0"/>
|
||||||
<property name="length" type="double" value="100"/>
|
<property name="length" type="uint" value="100"/>
|
||||||
<property name="position-locked" type="bool" value="true"/>
|
<property name="position-locked" type="bool" value="true"/>
|
||||||
<property name="icon-size" type="uint" value="36"/>
|
<property name="icon-size" type="uint" value="16"/>
|
||||||
<property name="size" type="uint" value="40"/>
|
<property name="size" type="uint" value="26"/>
|
||||||
<property name="plugin-ids" type="array">
|
<property name="plugin-ids" type="array">
|
||||||
<value type="int" value="1"/>
|
<value type="int" value="1"/>
|
||||||
<value type="int" value="2"/>
|
<value type="int" value="2"/>
|
||||||
<value type="int" value="3"/>
|
<value type="int" value="3"/>
|
||||||
|
<value type="int" value="4"/>
|
||||||
<value type="int" value="5"/>
|
<value type="int" value="5"/>
|
||||||
<value type="int" value="6"/>
|
<value type="int" value="6"/>
|
||||||
<value type="int" value="8"/>
|
<value type="int" value="8"/>
|
||||||
@@ -22,17 +23,13 @@
|
|||||||
<value type="int" value="11"/>
|
<value type="int" value="11"/>
|
||||||
<value type="int" value="12"/>
|
<value type="int" value="12"/>
|
||||||
<value type="int" value="13"/>
|
<value type="int" value="13"/>
|
||||||
|
<value type="int" value="14"/>
|
||||||
</property>
|
</property>
|
||||||
<property name="background-style" type="uint" value="0"/>
|
<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>
|
</property>
|
||||||
<property name="plugins" type="empty">
|
<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="plugin-2" type="string" value="tasklist">
|
||||||
<property name="grouping" type="uint" value="1"/>
|
<property name="grouping" type="uint" value="1"/>
|
||||||
</property>
|
</property>
|
||||||
@@ -40,6 +37,7 @@
|
|||||||
<property name="expand" type="bool" value="true"/>
|
<property name="expand" type="bool" value="true"/>
|
||||||
<property name="style" type="uint" value="0"/>
|
<property name="style" type="uint" value="0"/>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="plugin-4" type="string" value="pager"/>
|
||||||
<property name="plugin-5" type="string" value="separator">
|
<property name="plugin-5" type="string" value="separator">
|
||||||
<property name="style" type="uint" value="0"/>
|
<property name="style" type="uint" value="0"/>
|
||||||
</property>
|
</property>
|
||||||
@@ -55,11 +53,10 @@
|
|||||||
<property name="plugin-11" type="string" value="separator">
|
<property name="plugin-11" type="string" value="separator">
|
||||||
<property name="style" type="uint" value="0"/>
|
<property name="style" type="uint" value="0"/>
|
||||||
</property>
|
</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="plugin-13" type="string" value="separator">
|
||||||
<property name="style" type="uint" value="0"/>
|
<property name="style" type="uint" value="0"/>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="plugin-14" type="string" value="actions"/>
|
||||||
</property>
|
</property>
|
||||||
</channel>
|
</channel>
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
<property name="EnableInputFeedbackSounds" type="empty"/>
|
<property name="EnableInputFeedbackSounds" type="empty"/>
|
||||||
</property>
|
</property>
|
||||||
<property name="Xft" type="empty">
|
<property name="Xft" type="empty">
|
||||||
<property name="DPI" type="int" value="110"/>
|
<property name="DPI" type="empty"/>
|
||||||
<property name="Antialias" type="empty"/>
|
<property name="Antialias" type="empty"/>
|
||||||
<property name="Hinting" type="empty"/>
|
<property name="Hinting" type="empty"/>
|
||||||
<property name="HintStyle" type="empty"/>
|
<property name="HintStyle" type="empty"/>
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
<property name="MenuImages" type="empty"/>
|
<property name="MenuImages" type="empty"/>
|
||||||
<property name="ButtonImages" type="empty"/>
|
<property name="ButtonImages" type="empty"/>
|
||||||
<property name="MenuBarAccel" type="empty"/>
|
<property name="MenuBarAccel" type="empty"/>
|
||||||
<property name="CursorThemeName" type="string" value="default"/>
|
<property name="CursorThemeName" type="empty"/>
|
||||||
<property name="CursorThemeSize" type="empty"/>
|
<property name="CursorThemeSize" type="empty"/>
|
||||||
<property name="DecorationLayout" type="empty"/>
|
<property name="DecorationLayout" type="empty"/>
|
||||||
<property name="DialogsUseHeader" type="empty"/>
|
<property name="DialogsUseHeader" type="empty"/>
|
||||||
@@ -41,8 +41,4 @@
|
|||||||
<property name="Gdk" type="empty">
|
<property name="Gdk" type="empty">
|
||||||
<property name="WindowScalingFactor" type="empty"/>
|
<property name="WindowScalingFactor" type="empty"/>
|
||||||
</property>
|
</property>
|
||||||
<property name="Xfce" type="empty">
|
</channel>
|
||||||
<property name="LastCustomDPI" type="int" value="110"/>
|
|
||||||
<property name="SyncThemes" type="bool" value="true"/>
|
|
||||||
</property>
|
|
||||||
</channel>
|
|
||||||
14
overlay/etc/supervisor.d/dind.ini
Normal file
14
overlay/etc/supervisor.d/dind.ini
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
[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
|
||||||
14
overlay/etc/supervisor.d/sshd.ini
Normal file
14
overlay/etc/supervisor.d/sshd.ini
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
[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,7 +10,8 @@ autorestart=true
|
|||||||
startretries=50
|
startretries=50
|
||||||
user=%(ENV_USER)s
|
user=%(ENV_USER)s
|
||||||
directory=/home/%(ENV_USER)s
|
directory=/home/%(ENV_USER)s
|
||||||
command=/usr/games/steam %(ENV_STEAM_ARGS)s
|
# command=/usr/games/steam -bigpicture
|
||||||
|
command=/usr/games/steam
|
||||||
environment=HOME="/home/%(ENV_USER)s",USER="%(ENV_USER)s",DISPLAY="%(ENV_DISPLAY)s"
|
environment=HOME="/home/%(ENV_USER)s",USER="%(ENV_USER)s",DISPLAY="%(ENV_DISPLAY)s"
|
||||||
stopsignal=INT
|
stopsignal=INT
|
||||||
stdout_logfile=/home/%(ENV_USER)s/.cache/log/steam.log
|
stdout_logfile=/home/%(ENV_USER)s/.cache/log/steam.log
|
||||||
|
|||||||
@@ -12,3 +12,17 @@ stdout_logfile_backups=7
|
|||||||
stderr_logfile=/home/%(ENV_USER)s/.cache/log/audiostream.err.log
|
stderr_logfile=/home/%(ENV_USER)s/.cache/log/audiostream.err.log
|
||||||
stderr_logfile_maxbytes=10MB
|
stderr_logfile_maxbytes=10MB
|
||||||
stderr_logfile_backups=7
|
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
|
priority=30
|
||||||
autostart=false
|
autostart=false
|
||||||
autorestart=true
|
autorestart=true
|
||||||
user=root
|
user=%(ENV_USER)s
|
||||||
command=/usr/bin/start-x11vnc.sh
|
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"
|
environment=HOME="/home/%(ENV_USER)s",USER="%(ENV_USER)s",DISPLAY="%(ENV_DISPLAY)s",PORT_VNC="%(ENV_PORT_VNC)s"
|
||||||
stopsignal=INT
|
stopsignal=INT
|
||||||
@@ -14,12 +14,12 @@ stderr_logfile=/home/%(ENV_USER)s/.cache/log/x11vnc.err.log
|
|||||||
stderr_logfile_maxbytes=10MB
|
stderr_logfile_maxbytes=10MB
|
||||||
stderr_logfile_backups=7
|
stderr_logfile_backups=7
|
||||||
|
|
||||||
[program:frontend]
|
[program:novnc]
|
||||||
priority=30
|
priority=30
|
||||||
autostart=false
|
autostart=false
|
||||||
autorestart=true
|
autorestart=true
|
||||||
user=%(ENV_USER)s
|
user=%(ENV_USER)s
|
||||||
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
|
command=/opt/noVNC/utils/launch.sh --vnc localhost:%(ENV_PORT_VNC)s --listen %(ENV_PORT_NOVNC_SERVICE)s
|
||||||
environment=HOME="/home/%(ENV_USER)s",USER="%(ENV_USER)s"
|
environment=HOME="/home/%(ENV_USER)s",USER="%(ENV_USER)s"
|
||||||
stopsignal=INT
|
stopsignal=INT
|
||||||
stdout_logfile=/home/%(ENV_USER)s/.cache/log/novnc.log
|
stdout_logfile=/home/%(ENV_USER)s/.cache/log/novnc.log
|
||||||
@@ -28,3 +28,37 @@ stdout_logfile_backups=7
|
|||||||
stderr_logfile=/home/%(ENV_USER)s/.cache/log/novnc.err.log
|
stderr_logfile=/home/%(ENV_USER)s/.cache/log/novnc.err.log
|
||||||
stderr_logfile_maxbytes=10MB
|
stderr_logfile_maxbytes=10MB
|
||||||
stderr_logfile_backups=7
|
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
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
|
|
||||||
[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
|
|
||||||
40
overlay/opt/noVNC/nginx.template.conf
Normal file
40
overlay/opt/noVNC/nginx.template.conf
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,11 +4,12 @@ echo "**** Installing/upgrading Firefox via flatpak ****"
|
|||||||
|
|
||||||
# Install Firefox
|
# Install Firefox
|
||||||
flatpak --user remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
|
flatpak --user remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
|
||||||
flatpak --user install --assumeyes --or-update flathub org.mozilla.firefox
|
flatpak --user install --assumeyes --noninteractive --or-update flathub org.mozilla.firefox
|
||||||
|
|
||||||
# Configure Firefox as the default browser
|
# Configure Firefox as the default browser
|
||||||
echo "Configure Firefox..."
|
echo "Configure Firefox..."
|
||||||
custom_webbrowser="$(cat <<EOF
|
custom_webbrowser="$(cat <<EOF
|
||||||
|
"libraryfolders"
|
||||||
[Desktop Entry]
|
[Desktop Entry]
|
||||||
NoDisplay=true
|
NoDisplay=true
|
||||||
Version=1.0
|
Version=1.0
|
||||||
@@ -21,9 +22,9 @@ Name=org.mozilla.firefox
|
|||||||
X-XFCE-Commands=${USER_HOME:?}/.local/share/flatpak/exports/bin/org.mozilla.firefox
|
X-XFCE-Commands=${USER_HOME:?}/.local/share/flatpak/exports/bin/org.mozilla.firefox
|
||||||
EOF
|
EOF
|
||||||
)"
|
)"
|
||||||
if [[ ! -f "${USER_HOME:?}/.local/share/xfce4/helpers/custom-WebBrowser.desktop" ]]; then
|
if [[ ! -f ${USER_HOME:?}/.local/share/xfce4/helpers/custom-WebBrowser.desktop ]]; then
|
||||||
mkdir -p "${USER_HOME:?}/.local/share/xfce4/helpers"
|
mkdir -p ${USER_HOME:?}/.local/share/xfce4/helpers
|
||||||
echo "${custom_webbrowser}" > "${USER_HOME:?}/.local/share/xfce4/helpers/custom-WebBrowser.desktop"
|
echo "${custom_webbrowser}" > ${USER_HOME:?}/.local/share/xfce4/helpers/custom-WebBrowser.desktop
|
||||||
gio mime x-scheme-handler/http org.mozilla.firefox.desktop
|
gio mime x-scheme-handler/http org.mozilla.firefox.desktop
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -4,9 +4,9 @@ echo "**** Installing/upgrading ProtonUp-Qt via flatpak ****"
|
|||||||
|
|
||||||
# Install ProtonUp-Qt
|
# Install ProtonUp-Qt
|
||||||
flatpak --user remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
|
flatpak --user remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
|
||||||
flatpak --user install --assumeyes --or-update net.davidotek.pupgui2
|
flatpak --user install --assumeyes --noninteractive --or-update net.davidotek.pupgui2
|
||||||
|
|
||||||
# Configure ProtonUp-Qt
|
# Configure Firefox as the default browser
|
||||||
echo "Configure ProtonUp-Qt..."
|
echo "Configure ProtonUp-Qt..."
|
||||||
sed -i 's/^Categories=.*$/Categories=Utility;/' \
|
sed -i 's/^Categories=.*$/Categories=Utility;/' \
|
||||||
${USER_HOME}/.local/share/flatpak/exports/share/applications/net.davidotek.pupgui2.desktop
|
${USER_HOME}/.local/share/flatpak/exports/share/applications/net.davidotek.pupgui2.desktop
|
||||||
54
overlay/opt/scripts/install_steam.sh
Executable file
54
overlay/opt/scripts/install_steam.sh
Executable file
@@ -0,0 +1,54 @@
|
|||||||
|
#!/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"
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
[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;
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
WebBrowser=custom-WebBrowser
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
<?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>
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
[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
|
|
||||||
@@ -4,35 +4,11 @@
|
|||||||
},
|
},
|
||||||
"apps": [
|
"apps": [
|
||||||
{
|
{
|
||||||
"name": "Desktop",
|
"name": "Steam BigPicture",
|
||||||
"image-path": "desktop.png",
|
"output": "steam.txt",
|
||||||
"exclude-global-prep-cmd": "true"
|
"cmd": "",
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Steam Big Picture",
|
|
||||||
"image-path": "steam.png",
|
|
||||||
"exclude-global-prep-cmd": "true",
|
|
||||||
"detached": [
|
"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,10 +28,6 @@
|
|||||||
#
|
#
|
||||||
min_log_level = info
|
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
|
# The origin of the remote endpoint address that is not denied for HTTP method /pin
|
||||||
# Could be any of the following values:
|
# Could be any of the following values:
|
||||||
# pc|lan|wan
|
# pc|lan|wan
|
||||||
@@ -99,7 +95,7 @@ global_prep_cmd = [{"do":"/usr/bin/xfce4-minimise-all-windows","undo":"/usr/bin/
|
|||||||
# ping_timeout = 10000
|
# ping_timeout = 10000
|
||||||
|
|
||||||
# The file where configuration for the different applications that Sunshine can run during a stream
|
# The file where configuration for the different applications that Sunshine can run during a stream
|
||||||
file_apps = apps.json
|
file_apps = /home/default/sunshine/apps.json
|
||||||
|
|
||||||
# Percentage of error correcting packets per data packet in each video frame
|
# 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
|
# Higher values can correct for more network packet loss, but at the cost of increasing bandwidth usage
|
||||||
@@ -115,7 +111,7 @@ file_apps = apps.json
|
|||||||
#
|
#
|
||||||
# Unlike simply broadcasting to multiple Client, this will generate distinct video streams.
|
# Unlike simply broadcasting to multiple Client, this will generate distinct video streams.
|
||||||
# Note, CPU usage increases for each distinct video stream generated
|
# Note, CPU usage increases for each distinct video stream generated
|
||||||
channels = 2
|
# channels = 1
|
||||||
|
|
||||||
# The back/select button on the controller
|
# The back/select button on the controller
|
||||||
# On the Shield, the home and powerbutton are not passed to Moonlight
|
# On the Shield, the home and powerbutton are not passed to Moonlight
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
Section "Device"
|
Section "Device"
|
||||||
Identifier "Configured Video Device"
|
Identifier "Configured Video Device"
|
||||||
Driver "dummy"
|
Driver "dummy"
|
||||||
VideoRam 256000
|
|
||||||
EndSection
|
EndSection
|
||||||
|
|
||||||
Section "Monitor"
|
Section "Monitor"
|
||||||
Identifier "Configured Monitor"
|
Identifier "Configured Monitor"
|
||||||
HorizSync 5.0 - 1000.0
|
HorizSync 31.5-48.5
|
||||||
VertRefresh 5.0 - 200.0
|
VertRefresh 50-70
|
||||||
ModeLine "1920x1080" 148.50 1920 2448 2492 2640 1080 1084 1089 1125 +Hsync +Vsync
|
|
||||||
EndSection
|
EndSection
|
||||||
|
|
||||||
Section "Screen"
|
Section "Screen"
|
||||||
@@ -18,6 +16,6 @@ Section "Screen"
|
|||||||
DefaultDepth 24
|
DefaultDepth 24
|
||||||
SubSection "Display"
|
SubSection "Display"
|
||||||
Depth 24
|
Depth 24
|
||||||
Modes "1920x1080" "1280x800" "1024x768" "1920x1080" "1600x900" "1440x900"
|
Modes "1600x900"
|
||||||
EndSubSection
|
EndSubSection
|
||||||
EndSection
|
EndSection
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ wait_for_x() {
|
|||||||
wait_for_udev() {
|
wait_for_udev() {
|
||||||
MAX=10
|
MAX=10
|
||||||
CT=0
|
CT=0
|
||||||
while [ ! -e /run/udev/control ]; do
|
while [ ! -f /tmp/.udev-started ]; do
|
||||||
sleep 1
|
sleep 1
|
||||||
CT=$(( CT + 1 ))
|
CT=$(( CT + 1 ))
|
||||||
if [ "$CT" -ge "$MAX" ]; then
|
if [ "$CT" -ge "$MAX" ]; then
|
||||||
@@ -53,20 +53,6 @@ wait_for_docker() {
|
|||||||
echo "DOCKERD RUNNING!"
|
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)
|
# Fech NVIDIA GPU device (if one exists)
|
||||||
get_nvidia_gpu_id() {
|
get_nvidia_gpu_id() {
|
||||||
if [ "${NVIDIA_VISIBLE_DEVICES:-}" == "all" ]; then
|
if [ "${NVIDIA_VISIBLE_DEVICES:-}" == "all" ]; then
|
||||||
@@ -81,24 +67,3 @@ get_nvidia_gpu_id() {
|
|||||||
fi
|
fi
|
||||||
echo ${gpu_select}
|
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
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
#!/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"
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
#!/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
|
# File Created: Thursday, 1st January 1970 12:00:00 pm
|
||||||
# Author: Console and webGui login account (jsunnex@gmail.com)
|
# Author: Console and webGui login account (jsunnex@gmail.com)
|
||||||
# -----
|
# -----
|
||||||
# Last Modified: Saturday, 8th July 2023 6:16:47 pm
|
# Last Modified: Saturday, 8th July 2023 2:34:11 am
|
||||||
# Modified By: Console and webGui login account (jsunnex@gmail.com)
|
# Modified By: Console and webGui login account (jsunnex@gmail.com)
|
||||||
###
|
###
|
||||||
set -e
|
set -e
|
||||||
@@ -19,35 +19,24 @@ trap _term SIGTERM SIGINT
|
|||||||
|
|
||||||
|
|
||||||
# CONFIGURE:
|
# CONFIGURE:
|
||||||
# Remove lockfile
|
export $(dbus-launch)
|
||||||
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:
|
# 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 the X server to start
|
||||||
wait_for_x
|
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
|
# Run the desktop environment
|
||||||
echo "**** Starting Xfce4 ****"
|
echo "**** Starting Xfce4 ****"
|
||||||
/usr/bin/startxfce4 &
|
/usr/bin/startxfce4 &
|
||||||
desktop_pid=$!
|
desktop_pid=$!
|
||||||
touch /tmp/.started-desktop
|
|
||||||
|
|
||||||
# WAIT FOR CHILD PROCESS:
|
# WAIT FOR CHILD PROCESS:
|
||||||
wait "$desktop_pid"
|
wait "$desktop_pid"
|
||||||
|
|||||||
52
overlay/usr/bin/start-dind.sh
Executable file
52
overlay/usr/bin/start-dind.sh
Executable file
@@ -0,0 +1,52 @@
|
|||||||
|
#!/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"
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
#!/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"
|
|
||||||
45
overlay/usr/bin/start-kasmvnc.sh
Executable file
45
overlay/usr/bin/start-kasmvnc.sh
Executable file
@@ -0,0 +1,45 @@
|
|||||||
|
#!/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,6 +19,7 @@ trap _term SIGTERM SIGINT
|
|||||||
|
|
||||||
# EXECUTE PROCESS:
|
# EXECUTE PROCESS:
|
||||||
echo "PULSEAUDIO: Starting pulseaudio service"
|
echo "PULSEAUDIO: Starting pulseaudio service"
|
||||||
|
sleep 5
|
||||||
#/usr/bin/pulseaudio --disallow-module-loading --disallow-exit --exit-idle-time=-1 &
|
#/usr/bin/pulseaudio --disallow-module-loading --disallow-exit --exit-idle-time=-1 &
|
||||||
/usr/bin/pulseaudio --exit-idle-time=-1 &
|
/usr/bin/pulseaudio --exit-idle-time=-1 &
|
||||||
pulseaudio_pid=$!
|
pulseaudio_pid=$!
|
||||||
|
|||||||
@@ -5,73 +5,50 @@
|
|||||||
# File Created: Tuesday, 4th October 2022 8:22:17 pm
|
# File Created: Tuesday, 4th October 2022 8:22:17 pm
|
||||||
# Author: Josh.5 (jsunnex@gmail.com)
|
# Author: Josh.5 (jsunnex@gmail.com)
|
||||||
# -----
|
# -----
|
||||||
# Last Modified: Wednesday, 27th November 2024 3:54:19 pm
|
# Last Modified: Tuesday, 4th October 2022 8:22:17 pm
|
||||||
# Modified By: Josh5 (jsunnex@gmail.com)
|
# Modified By: Josh.5 (jsunnex@gmail.com)
|
||||||
###
|
###
|
||||||
set -e
|
set -e
|
||||||
source /usr/bin/common-functions.sh
|
source /usr/bin/common-functions.sh
|
||||||
|
|
||||||
# CATCH TERM SIGNAL:
|
# CATCH TERM SIGNAL:
|
||||||
_term() {
|
_term() {
|
||||||
kill -INT "$sunshine_pid" 2>/dev/null
|
kill -TERM "$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
|
trap _term SIGTERM SIGINT
|
||||||
|
|
||||||
|
|
||||||
# CONFIGURE:
|
# CONFIGURE:
|
||||||
# Install default configurations
|
# Install default configurations
|
||||||
mkdir -p "${USER_HOME:?}/.config/sunshine"
|
mkdir -p /home/${USER}/sunshine
|
||||||
if [ ! -f "${USER_HOME:?}/.config/sunshine/sunshine.conf" ]; then
|
if [[ ! -f /home/${USER}/sunshine/sunshine.conf ]]; then
|
||||||
cp -vf /templates/sunshine/sunshine.conf "${USER_HOME:?}/.config/sunshine/sunshine.conf"
|
cp -vf /templates/sunshine/* /home/${USER}/sunshine/
|
||||||
fi
|
# TODO: Set the default encoder '# encoder = nvenc'
|
||||||
if [ ! -f "${USER_HOME:?}/.config/sunshine/apps.json" ]; then
|
# nvidia_gpu_id=$(get_nvidia_gpu_id)
|
||||||
cp -vf /templates/sunshine/apps.json "${USER_HOME:?}/.config/sunshine/apps.json"
|
# if [[ "X${nvidia_gpu_id:-}" != "X" ]]; then
|
||||||
fi
|
# if [[ "all video" == *"${NVIDIA_DRIVER_CAPABILITIES}"* ]]; then
|
||||||
if [ ! -f "${USER_HOME:?}/.config/sunshine/sunshine_state.json" ]; then
|
# # Check if we have a nvidia GPU available
|
||||||
echo "{}" > "${USER_HOME:?}/.config/sunshine/sunshine_state.json"
|
# 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
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Reset the default username/password
|
# Reset the default username/password
|
||||||
if ([ "X${SUNSHINE_USER:-}" != "X" ] && [ "X${SUNSHINE_PASS:-}" != "X" ]); then
|
if ([ "X${SUNSHINE_USER:-}" != "X" ] && [ "X${SUNSHINE_PASS:-}" != "X" ]); then
|
||||||
/usr/bin/sunshine "${USER_HOME:?}/.config/sunshine/sunshine.conf" --creds "${SUNSHINE_USER:?}" "${SUNSHINE_PASS:?}"
|
sunshine /home/${USER}/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
|
fi
|
||||||
|
|
||||||
|
|
||||||
# EXECUTE PROCESS:
|
# EXECUTE PROCESS:
|
||||||
# Wait for the X server to start
|
# Wait for the X server to start
|
||||||
wait_for_x
|
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
|
# Start the sunshine server
|
||||||
/usr/bin/dumb-init /usr/bin/sunshine "${USER_HOME:?}/.config/sunshine/sunshine.conf" &
|
sunshine /home/${USER}/sunshine/sunshine.conf &
|
||||||
sunshine_pid=$!
|
sunshine_pid=$!
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,10 @@ _term() {
|
|||||||
}
|
}
|
||||||
trap _term SIGTERM SIGINT
|
trap _term SIGTERM SIGINT
|
||||||
|
|
||||||
|
|
||||||
# EXECUTE PROCESS:
|
# EXECUTE PROCESS:
|
||||||
|
# Remove lockfile
|
||||||
|
rm -f /tmp/.udev-started
|
||||||
# Start udev
|
# Start udev
|
||||||
if command -v udevd &>/dev/null; then
|
if command -v udevd &>/dev/null; then
|
||||||
unshare --net udevd --daemon &>/dev/null
|
unshare --net udevd --daemon &>/dev/null
|
||||||
@@ -26,8 +29,11 @@ fi
|
|||||||
# Monitor kernel uevents
|
# Monitor kernel uevents
|
||||||
udevadm monitor &
|
udevadm monitor &
|
||||||
monitor_pid=$!
|
monitor_pid=$!
|
||||||
# Wait for 5 seconds, then request device events from the kernel
|
# Touch lockfile
|
||||||
sleep 5
|
sleep 1
|
||||||
|
touch /tmp/.udev-started
|
||||||
|
# Wait for 10 seconds, then request device events from the kernel
|
||||||
|
sleep 10
|
||||||
udevadm trigger
|
udevadm trigger
|
||||||
|
|
||||||
# WAIT FOR CHILD PROCESS:
|
# WAIT FOR CHILD PROCESS:
|
||||||
|
|||||||
@@ -20,9 +20,7 @@ trap _term SIGTERM SIGINT
|
|||||||
|
|
||||||
# EXECUTE PROCESS:
|
# EXECUTE PROCESS:
|
||||||
# Wait for udev
|
# Wait for udev
|
||||||
if [ $(grep autostart /etc/supervisor.d/udev.ini 2> /dev/null) == "autostart=true" ]; then
|
wait_for_udev
|
||||||
wait_for_udev
|
|
||||||
fi
|
|
||||||
# Run X server
|
# Run X server
|
||||||
/usr/bin/Xorg \
|
/usr/bin/Xorg \
|
||||||
-ac \
|
-ac \
|
||||||
|
|||||||
@@ -1,84 +0,0 @@
|
|||||||
#!/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
|
|
||||||
@@ -1,163 +0,0 @@
|
|||||||
#!/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"
|
|
||||||
@@ -1,110 +0,0 @@
|
|||||||
#!/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"
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
#!/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
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
#!/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