120 Commits

Author SHA1 Message Date
Josh.5
0ad203f89d Testing KasmVNC 2023-07-08 04:57:25 +12:00
Josh.5
63754aaed5 Start using Flatpaks as the main install method for any desktop apps 2023-07-08 02:59:43 +12:00
Josh.5
e717cd209f Improvements to running Xorg with NVIDIA 2023-07-07 15:59:48 +12:00
Josh Sunnex
4896a5bc36 Merge pull request #46 from jflesch/master
Update Sunshine to 0.20.0
2023-06-26 20:02:11 -07:00
Jerome Flesch
5577410923 Update Sunshine to 0.20.0:
Sunshine 0.18.0 has drastically improved CPU performance.
A dependency on libboost-chrono-1.74.0 has been added, but hasn't been declared in the .deb package.
2023-06-26 11:04:52 +02:00
Josh Sunnex
6a2d55196b Merge pull request #41 from karbowiak/intel_arc
#39 - Intel Arc Support
2023-05-24 14:10:16 +12:00
Michael Karbowiak
98a4425fce If we find an Arc GPU, we need to install the Intel drivers just like if we find an intel iGPU 2023-05-22 15:09:12 +02:00
Josh Sunnex
d4e7048745 Merge pull request #35 from deviantintegral/patch-1
Note the default games path in compose file
2023-05-22 21:57:23 +12:00
Andrew Berry
7505ef3b23 Note the default games path in compose file 2023-03-30 10:22:45 -04:00
Danny Beer
9b962580ff Use protonup-ng package 2022-10-29 09:23:47 +13:00
Josh.5
0d2da789ef Ensure ~/.config/pulse is owned by the default user 2022-10-10 16:54:26 +13:00
Josh.5
2c5da29701 Fix issue where dynamic port allocation during startup would take a long time 2022-10-10 16:40:10 +13:00
Josh.5
d893d9565c Fix incorrect date format on versioning 2022-10-10 11:07:53 +13:00
Josh.5
81e378e9d0 Add documentation issue template 2022-10-10 01:37:52 +13:00
Josh.5
595e60182b Another improvement to the bug report template 2022-10-10 01:31:07 +13:00
Josh.5
6b587427b2 Fixing the platform version on the bug report template 2022-10-10 01:26:35 +13:00
Josh.5
91e414b341 Small tweak to stale issues monitor 2022-10-10 01:24:43 +13:00
Josh.5
07fe21bb1c Add some GitHub templates to project 2022-10-10 00:54:16 +13:00
Josh.5
2e9a20a87a Fix error in pulseaudio socket config 2022-10-09 23:45:56 +13:00
Josh.5
3b9311fde3 Add dummy screen on startup if no monitor is plugged in 2022-10-09 23:45:56 +13:00
Josh.5
54e4e09d29 Fix error where on a contrainer restart you could not add default user to docker gourp again 2022-10-09 23:45:56 +13:00
Josh.5
5fa3f2b968 Fix missing group permissions setup on container start 2022-10-09 23:45:56 +13:00
Josh.5
45f73da6cb Set root XDG_RUNTIME_DIR to /tmp/runtime-root 2022-10-09 23:45:56 +13:00
Josh.5
72f2543b02 Add missing env variables
These are required for the internal docker containers
2022-10-09 23:45:56 +13:00
Josh.5
03beff3ff3 Add dind config init script 2022-10-09 23:45:56 +13:00
Josh.5
4b7cf66ecf Add nvidia docker runtime 2022-10-09 23:45:56 +13:00
Josh.5
9712eede91 Add Docker in Docker 2022-10-09 23:45:56 +13:00
Josh.5
477e25f82c Some minor tweaks and improvments 2022-10-07 03:46:52 +13:00
Josh.5
f233991597 Add default sunshine config on startup if missing 2022-10-06 22:38:45 +13:00
Josh.5
1fbfd235f1 Clear X server config on startup 2022-10-06 22:38:04 +13:00
Josh.5
469b12087d Run an initial X server config on startup 2022-10-06 22:37:37 +13:00
Josh.5
54911cb97b Fix bug preventing input after the first startup of the container
Xorg was starting before udev could finish the monitor command. This prevented the X server from having access to the input devices. For some reason, any subsequent starts would be fine.

Adding a small delay to the X server start and triggering a request for device events from the kernel after a delay seems to fix this issue.
2022-10-06 22:26:50 +13:00
Josh.5
93fb8f858c Improvements to default env file
Disable sunshine by default
2022-10-06 15:22:20 +13:00
Josh.5
1e255f822d Add optional KB/Mouse input capture with Xorg 2022-10-06 15:22:20 +13:00
Josh.5
829754b8fb Add sunshine as an optional background service 2022-10-06 15:22:20 +13:00
Josh.5
a80eda6086 Update TODO in README file 2022-10-05 07:45:42 +13:00
Josh.5
341c05cecd Fix up documentation 2022-10-04 17:50:27 +13:00
Josh.5
99f9034766 Add alsa utils to docker image 2022-10-04 17:36:40 +13:00
Josh.5
703be17214 Move all default user group modifications to the 10-setup_user.sh script 2022-10-04 17:36:40 +13:00
Josh.5
db070cce96 Update compose files with env change made to Dockerfile 2022-10-04 17:36:40 +13:00
Josh.5
4441b79b1e Disable SSH service by default
I think I am going to remove this in a future update.
For now I will just disable it by default and remove it from any templates.
2022-10-04 17:36:40 +13:00
Josh.5
7b620c7918 Allow the VNC ports to be manually configure as an option
Apply dynamically allocated ports if not port is specified
2022-10-04 17:36:40 +13:00
Josh.5
145d5600a6 Add docs for setting up Steam Headless on Intel GPU with docker-compose 2022-10-04 17:36:40 +13:00
Josh.5
2c0b7b5d53 Fix desktop and udev launch scripts
These services were not responding to a SIGTERM
We need to catch the SIGTERM from the parent script and kill the child process
2022-10-04 17:36:40 +13:00
Josh.5
7614e503a7 Launch Xorg server direct from supervisor rather than a script
- Remove launcher for X11 and just call it from
- Improvements to the '/tmp/.X11-unix' directory
    - Move lockfile clearing to init script rather than launcher
    - Configure the 'XDG_RUNTIME_DIR' to something that is easily shared between containers
- Ensure all logs in home directory are readable
- Log Xorg service in home directory so they are more easily accessable to users
2022-10-04 17:36:40 +13:00
Josh.5
cfd7bbda0e Improvements to pulseaudio
- Add a DEBUGGING flag
- Make the location of the unix socket configurable

While I was here I moved all the priority configs in supervisord to the top. I like it better there
2022-10-04 17:36:40 +13:00
Josh.5
1cc4257dd5 Prevent pulseaudio from respawning
https://unix.stackexchange.com/questions/204522/how-does-pulseaudio-start
2022-10-04 17:36:40 +13:00
Josh.5
30699db581 Fix for VNC port selection being missing when running in secondary mode 2022-10-04 17:36:40 +13:00
Josh.5
c6ccb39b13 Set the pulse audio socket to a more standard path
This path is easily shared with other containers
2022-10-04 17:36:40 +13:00
Josh.5
c63e9ac0b9 Add user to pulse group in setup_user.sh script 2022-10-04 17:36:40 +13:00
Josh.5
c2abf14dd3 Fix some issues with the nginx template config after a container restart 2022-10-04 09:41:14 +13:00
Josh.5
6340f4113e Add a Nginx reverse proxy to combine all the used ports into one single port
This will allow this web UI to sit nicely behind a reverse proxy.

Dynamically set the ports used for the
- VNC service
- noVNC service
- Pulseaudio socket
- VNC audio transport websocket

Remove all mentions of the above used ports in the Dockerfile.
2022-10-04 09:41:14 +13:00
Josh.5
38d9442c7d Set neko default screen size based on current configured screen size 2022-10-04 09:41:14 +13:00
Josh.5
686f76bc95 Disable HW accelration on Neko (not sure why this is not working) 2022-10-04 09:41:14 +13:00
Josh.5
a3294eb582 Add neko log path 2022-10-04 09:41:14 +13:00
Josh.5
b088a7adf4 Tidy up GPU driver installation 2022-10-04 09:41:14 +13:00
Josh.5
9bfc3568e6 Ensure XDG_RUNTIME_DIR is available to neko 2022-10-04 09:41:14 +13:00
Josh.5
cb597e4423 Re-order the neko config to be after the X server is configured 2022-10-04 09:41:14 +13:00
Josh.5
f9149958bb Add HW acceleration to Neko config
If a ` /dev/dri/render*` device exists, enable vaapi encoding
2022-10-04 09:41:14 +13:00
Josh.5
adac278106 Add user to pulse group in setup_user.sh script 2022-10-04 09:41:14 +13:00
Josh.5
8b1de46a6d Add Niko server as an alternative to noVNC 2022-10-04 09:41:14 +13:00
Josh.5
6260809ab3 Prevent VNC from autostarting 2022-10-04 09:41:14 +13:00
Josh.5
f4734507bf Change the supervisor stop signal for all services to SIGINT 2022-10-04 09:41:14 +13:00
Josh.5
5d2ece84dc Disable VNC if 'WEB_UI_MODE' is not "vnc"
Se the new variable to default to "vnc"
2022-10-04 09:41:14 +13:00
Josh Sunnex
444cfae3fa Merge pull request #7 from chaitan3/fix_groups
Append groups when doing ensure-groups
2022-10-02 12:52:19 +13:00
Chaitanya Talnikar
5d0ce361ce Append groups when doing ensure-groups 2022-10-01 09:30:55 -04:00
Josh Sunnex
b21607c4b5 Merge pull request #6 from yourjelly/patch-1
Update 10-setup_user.sh --Correcting nuisance typo
2022-09-30 12:28:46 +13:00
Jon Xuereb
becf1c586b Update 10-setup_user.sh
UID and GUID were flipped and didn't match text in echo line.
Likewise swapped ln10&11 to maintain consistency.
2022-09-29 16:31:44 -04:00
Josh Sunnex
3a6178979f Merge pull request #5 from EmilyLove26/patch-1
Audio Fix
2022-09-16 07:13:36 +12:00
Emily Love
ae818f3080 Audio Fix
In reference to Pull Request #4, which was seemingly abandoned. This fixes the broken audio.
2022-09-15 03:09:11 -04:00
Josh.5
6fe1845a1e Github markdown does not render the HTML elements 2022-09-03 18:08:45 +12:00
Josh.5
787035fb21 Update docs - Add docs for Unraid installation 2022-09-03 17:32:28 +12:00
Josh.5
234daf876b Update README TODO list 2022-09-03 16:26:02 +12:00
Josh.5
79cb946b01 Disable the SSH server is 'PORT_SSH' variable is set to an empty string 2022-09-03 16:25:45 +12:00
Josh.5
e5bd4be2f9 Start Steam silently in tray by default 2022-09-03 15:46:00 +12:00
Josh.5
42534b2e15 Prevent overriding existing files during home directory template setup 2022-09-03 15:43:30 +12:00
Josh.5
ba01d6f523 Fix Heroic Launcher install script 2022-08-31 22:01:48 +12:00
Josh.5
63d2f726a5 Ensure the SSH port is being set based on the provided env variable 'PORT_SSH' 2022-08-31 20:59:35 +12:00
Josh.5
d49bee6547 Add a scheduled build to happen each week 2022-08-06 14:22:30 +12:00
Josh.5
6dce17ac84 Always attempt to pull all referenced images when building 2022-08-06 13:56:08 +12:00
Josh.5
4f1a693b88 Add an autorestart count to the steam.ini
This allows this container to start up before X is ready on the main container and restart the process until it becomes available.
Each restart will have a small delay of a few seconds. So 50 attempts should be a few mins.
2022-08-06 13:38:03 +12:00
Josh.5
576bf9471c Make the various used ports configurable 2022-02-19 18:07:10 +13:00
Josh.5
75c2df3115 Dont run VNC or apply the VNC audio patch when running as a secondary container 2022-02-08 14:36:19 +13:00
Josh.5
168c46ae72 Add support for running a container using only a XvFB framebuffer for the X server
As requested by a user, this gives the option to run a headless steam for the purpose of downloading games and not for playing them.
2022-02-08 08:03:56 +13:00
Josh.5
73a4af0f5c Add support for runnin a secondary instance of steam
This requires that you still have setup a primary container instance of this image.
We can then run a secondary instance of steam that will use the existing X server.

We are still limited to running one of these steam instances at a time.
2022-02-08 07:56:35 +13:00
Josh.5
74871da011 Move the default games mount for steam.
RetroArch seems to have an issue with it being `/games`
2022-01-27 00:12:14 +13:00
Josh.5
c8dde58c9a Improve XDG_RUNTIME_DIR log message 2022-01-26 17:44:16 +13:00
Josh.5
7056a225d5 Adding some missing tools 2022-01-26 17:39:16 +13:00
Josh.5
552714c75f Improvements to Debian Docker image build.
Add changes from Arch dockerfile:
- Flatpak support
- Reduce unnecessary recommends installations
- Separate mesa and vulkin installations
2022-01-26 16:48:21 +13:00
Josh.5
5213e1c9f7 Add initial build config for Arch Linux distribution
This is a WIP, and it does not yet work very well.
2022-01-26 15:46:03 +13:00
Josh.5
68b5d3df3c /etc/ssh/ssh_config does not always import from /etc/ssh/ssh_config.d on all distributions 2022-01-26 15:44:48 +13:00
Josh.5
3aa0d04d91 Add default user to video,input,audio groups 2022-01-26 15:44:13 +13:00
Josh.5
217d0eb26e Need to be able to init on any distro.
The current supervisor.d configs are configured specifically for a particular supervisor version / installation.
This decouples the configuration so we can use it on any distro.
2022-01-26 15:43:45 +13:00
Josh.5
641a7ae7a7 The HeroicBashLauncher script does not need to have the configs reloaded
This is done automatically when the game scripts are run.
2022-01-17 23:45:31 +13:00
Josh.5
a1a05675e3 Accidently used backticks for quotes 2022-01-17 23:40:47 +13:00
Josh.5
f0ab202711 Tidy up all supervisor configs
(makes them more consistent)
2022-01-16 15:21:45 +13:00
Josh.5
ada5d2a9dc Hid x11vnc from Inernet applications menu 2022-01-16 14:40:19 +13:00
Josh.5
8fc06d9621 Add HeroicBashLauncher for adding games to steam 2022-01-16 07:20:28 +13:00
Josh.5
090c274a55 Add heroic launcher installer scripts 2022-01-16 06:15:04 +13:00
Josh.5
494d0f37e3 Just read teh version file (CI is putting all required info in there) 2022-01-16 06:00:30 +13:00
Josh.5
09c2ea2109 Remove the rare menu item when it is not installed 2022-01-16 05:55:34 +13:00
Josh.5
d06582c38e Change text to Press enter to continue because that is how it works 2022-01-16 05:54:59 +13:00
Josh.5
8d90694712 Add rare/legendary installers 2022-01-16 05:40:41 +13:00
Josh.5
96f4476069 Fix build version 2022-01-16 03:23:57 +13:00
Josh.5
bb742d5b96 Add Protonup installer 2022-01-16 02:32:41 +13:00
Josh.5
61cc30d69b Add Lutris installer 2022-01-16 02:32:03 +13:00
Josh.5
1f5bfcd86a Modify the docker build stages to better reflect the priority of the elements.
Add a missin nvidia_icd.json file
Remove the config of /tmp/dump
2022-01-16 00:01:00 +13:00
Josh.5
57641f7536 Print the build version when the container starts 2022-01-15 23:57:32 +13:00
Josh.5
ba3f96c5fd Rename the xfce4 log file 2022-01-15 10:03:10 +13:00
Josh.5
963f3d553f Remove test startup script (no longer used) 2022-01-15 10:02:49 +13:00
Josh.5
9d7b27066c SSH needs to run on another port if we are using host network.
We are now forced to used host network because of udev
2022-01-15 08:38:39 +13:00
Josh.5
446a043703 Improvements to my script for testing the container generation 2022-01-15 08:37:53 +13:00
Josh.5
89e85397dd Add udev to container 2022-01-14 09:21:45 +13:00
Josh.5
07c6ebc967 Steam needed access to /tmp/dumps 2022-01-14 08:47:44 +13:00
Josh.5
ba277817a0 Use host udev and /dev/input then ensure correct permissions on files for steam 2022-01-14 08:47:18 +13:00
Josh.5
14871dcecd Pulse audio is require to stream using steam link 2022-01-14 08:45:58 +13:00
Josh.5
ad9cbb9bca Add ability to disable audio socket for webUI 2022-01-13 00:12:20 +13:00
Josh.5
0008e05848 Improvements to the init process
Move some files to locations that make more sense...
Downloads go to Downloads
Init scripts go to an "init" directory
Add a script for clearing up some memory - May or may not use it.
2022-01-12 20:53:55 +13:00
Josh.5
1ba89a9bc8 Add Python pip to default tools 2022-01-12 11:06:12 +13:00
Josh.5
8e877e3762 Improvements toward working with a shared host X server 2022-01-12 09:16:06 +13:00
87 changed files with 3484 additions and 556 deletions

View File

@@ -1 +1,2 @@
config config
devops

87
.github/ISSUE_TEMPLATE/BUG-REPORT.yml vendored Normal file
View File

@@ -0,0 +1,87 @@
---
name: Bug Report
description: Please do not use bug reports for support issues.
title: "[Bug]: "
labels: ['status:awaiting-triage', 'type:bug']
body:
- type: markdown
attributes:
value: |
**THIS IS NOT THE PLACE TO ASK FOR SUPPORT!** Please use [Discord](https://unmanic.app/discord) for support issues.
- type: textarea
id: description
attributes:
label: Describe the Bug
description: A clear and concise description of the bug.
validations:
required: true
- type: textarea
id: steps
attributes:
label: Steps to Reproduce
description: List each action required in order to reproduce the issue.
placeholder: |
1. First Step '...'
2. Second Step '...'
3. So on '...'
4. See error
- type: textarea
id: expected
attributes:
label: Expected Behavior
description: A clear and concise description of what you expected to happen.
- type: textarea
id: screenshots
attributes:
label: Screenshots
description: Provide screenshots to help explain your problem.
- type: textarea
id: relevant
attributes:
label: Relevant Settings
description: Include all settings/configuration that are relevant to your setup.
placeholder: |
- eg. Configuration of your Docker container.
- eg. Configurations within the application/container.
- eg. External processes that you have connected to or communicating with the application/container.
- type: input
id: version
attributes:
label: Version
description: The version is the first line printed in the Docker log.
placeholder: 'Build: [10/08/22 03:09:26] [master] [477e25f82c2612b6345ca0c9777345e6b5129965]'
validations:
required: true
- type: textarea
id: platform
attributes:
label: Platform
description: |
Detail the host OS platform, version and software versions.
- Distribution: `$(. /etc/os-release; echo "${NAME} - ${VERSION}")`
- Linux Kernel: `$(uname -rpio)`
- GPU Driver versions: `$(nvidia-smi | grep 'Version:')`
- Docker: `$(docker -v)`
- Docker-compose: `$(docker compose -v)`
placeholder: |
- Distribution:
- Linux Kernel:
- GPU Driver versions:
- Docker:
- Docker-compose:
validations:
required: true
- type: textarea
id: logs
attributes:
label: Relevant log output
description: |
Please copy and paste any relevant log output.
This will be automatically formatted into code, so no need for backticks.
Note: Most relevant logs are found either in the docker logs or inside the container in /home/default/.cache/log/
render: Shell
- type: markdown
attributes:
value: |
Make sure to close your issue when it's solved! If you found the solution yourself please comment so that others benefit from it.

View File

@@ -0,0 +1,17 @@
---
name: Documentation Improvement
description: Suggest an update to documentation.
labels: ['status:awaiting-triage', 'type:documentation']
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to help improve!
- type: textarea
id: description
attributes:
label: Description
description: Provide a description of the proposed changes.
validations:
required: true

View File

@@ -0,0 +1,33 @@
---
name: Feature Request
description: Suggest a new feature.
labels: ['status:awaiting-triage', 'type:enhancement']
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to help improve!
- type: textarea
id: problem
attributes:
label: Is your feature request related to a problem?
description: If so, please provide clear and concise description of the problem.
placeholder: eg. I'm always frustrated when '...'
- type: textarea
id: feature
attributes:
label: What is your feature request?
description: A clear and concise description of the feature.
validations:
required: true
- type: textarea
id: workaround
attributes:
label: Are there any workarounds?
description: A clear and concise description of any alternative solutions or features you've considered.
- type: textarea
id: additional
attributes:
label: Additional Context
description: Add any other context or screenshots about the feature request here.

10
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,10 @@
---
blank_issues_enabled: false
contact_links:
- name: Discord support
url: https://unmanic.app/discord
about: Ask questions in Discord.
- name: Unraid Forum
url: https://forums.unraid.net/topic/118390-support-josh5-steam-headless/
about: For Unraid users, please check the forums to see if your question has already been answered.

50
.github/label-actions.yml vendored Normal file
View File

@@ -0,0 +1,50 @@
---
# Configuration for Label Actions - https://github.com/dessant/label-actions
added:
comment: >
This feature has been added and will be available in the next release.
This issue will be automatically closed once the update is available.
fixed:
comment: >
This bug has been fixed and will be available in the next release.
This issue will be automatically closed once the update is available.
invalid:duplicate:
comment: >
:wave: @{issue-author}, this appears to be a duplicate of a pre-existing issue.
close: true
lock: true
unlabel: 'status:awaiting-triage'
-invalid:duplicate:
reopen: true
unlock: true
invalid:support:
comment: >
:wave: @{issue-author}, we use the issue tracker exclusively for bug reports.
However, this issue appears to be a support request. Please use our
[Discord Server](https://unmanic.app/discord) to get help. Thanks.
close: true
lock: true
lock-reason: 'off-topic'
unlabel: 'status:awaiting-triage'
-invalid:support:
reopen: true
unlock: true
invalid:template-incomplete:
issues:
comment: >
:wave: @{issue-author}, please edit your issue to complete the template with
all the required info. Your issue will be automatically closed in 5 days if
the template is not completed. Thanks.
prs:
comment: >
:wave: @{issue-author}, please edit your PR to complete the template with
all the required info. Your PR will be automatically closed in 5 days if
the template is not completed. Thanks.

View File

@@ -1,3 +1,5 @@
---
name: Build and Deploy CI name: Build and Deploy CI
on: on:
@@ -6,6 +8,9 @@ on:
tags: [ '**' ] tags: [ '**' ]
pull_request: pull_request:
branches: [ staging, master ] branches: [ staging, master ]
schedule:
# At 02:30 on Saturday
- cron: '30 2 * * 6'
jobs: jobs:
@@ -59,6 +64,8 @@ jobs:
fi fi
fi fi
echo "Build: [$(date +"%F %T")] [${GITHUB_REF_NAME}] [${GITHUB_SHA}]" > ./overlay/version.txt
DOCKER_PUSH="true" DOCKER_PUSH="true"
if [[ ${DOCKER_IMAGE} != 'docker.io/josh5/steam-headless' ]]; then if [[ ${DOCKER_IMAGE} != 'docker.io/josh5/steam-headless' ]]; then
DOCKER_PUSH="false" DOCKER_PUSH="false"
@@ -100,6 +107,7 @@ jobs:
with: with:
context: . context: .
file: Dockerfile file: Dockerfile
pull: true
platforms: ${{ steps.prepare.outputs.docker_platforms }} platforms: ${{ steps.prepare.outputs.docker_platforms }}
push: ${{ steps.prepare.outputs.docker_push }} push: ${{ steps.prepare.outputs.docker_push }}
tags: | tags: |

51
.github/workflows/issues-stale.yml vendored Normal file
View File

@@ -0,0 +1,51 @@
---
name: Stale Issues / PRs
on:
schedule:
- cron: '00 00 * * *'
jobs:
stale:
name: Check Stale Issues / PRs
runs-on: ubuntu-latest
steps:
- name: Stale
uses: actions/stale@v5
with:
close-issue-message: >
This issue was closed because it has been stalled for 5 days with no activity.
close-pr-message: >
This PR was closed because it has been stalled for 10 days with no activity.
days-before-stale: 60
days-before-close: 10
exempt-all-assignees: true
exempt-issue-labels: 'added,fixed,type:enhancement,status:awaiting-triage,status:in-progress'
exempt-pr-labels: 'type:dependencies,status:in-progress,status:in-review'
stale-issue-label: 'stale'
stale-issue-message: >
This issue is stale because it has been open for 30 days with no activity.
Comment or remove the stale label, otherwise this will be closed in 5 days.
stale-pr-label: 'stale'
stale-pr-message: >
This PR is stale because it has been open for 60 days with no activity.
Comment or remove the stale label, otherwise this will be closed in 10 days.
- name: Invalid Template
uses: actions/stale@v5
with:
close-issue-message: >
This issue was closed because the the template was not completed after 5 days.
close-pr-message: >
This PR was closed because the the template was not completed after 5 days.
days-before-stale: 0
days-before-close: 5
exempt-pr-labels: 'type:dependencies,status:in-progress,status:in-review'
only-labels: 'invalid:template-incomplete'
stale-issue-label: 'invalid:template-incomplete'
stale-issue-message: >
Invalid issues template.
stale-pr-label: 'invalid:template-incomplete'
stale-pr-message: >
Invalid PR template.

17
.github/workflows/issues.yml vendored Normal file
View File

@@ -0,0 +1,17 @@
---
name: Issues
on:
issues:
types: [labeled, unlabeled]
jobs:
label:
name: Label Issues
runs-on: ubuntu-latest
steps:
- name: Label Issues
uses: dessant/label-actions@v2
with:
github-token: ${{ github.token }}

View File

@@ -1,4 +1,5 @@
FROM debian:bullseye-slim FROM debian:bullseye-slim
LABEL maintainer="Josh.5 <jsunnex@gmail.com>"
# Update package repos # Update package repos
ARG DEBIAN_FRONTEND=noninteractive ARG DEBIAN_FRONTEND=noninteractive
@@ -14,9 +15,8 @@ RUN \
&& apt-get update \ && apt-get update \
&& \ && \
echo "**** Install and configure locals ****" \ echo "**** Install and configure locals ****" \
&& apt-get -y install --no-install-recommends \ && apt-get install -y --no-install-recommends \
locales \ locales \
procps \
&& echo 'en_US.UTF-8 UTF-8' > /etc/locale.gen \ && echo 'en_US.UTF-8 UTF-8' > /etc/locale.gen \
&& locale-gen \ && locale-gen \
&& \ && \
@@ -40,7 +40,7 @@ RUN \
&& apt-get update \ && apt-get update \
&& \ && \
echo "**** Install certificates ****" \ echo "**** Install certificates ****" \
&& apt-get -y install --reinstall \ && apt-get install -y --reinstall \
ca-certificates \ ca-certificates \
&& \ && \
echo "**** Section cleanup ****" \ echo "**** Section cleanup ****" \
@@ -59,53 +59,37 @@ RUN \
&& apt-get update \ && apt-get update \
&& \ && \
echo "**** Install tools ****" \ echo "**** Install tools ****" \
&& apt-get -y install \ && apt-get install -y --no-install-recommends \
bash \ bash \
bash-completion \ bash-completion \
gcc \ curl \
git \ git \
kmod \ jq \
less \ less \
make \
nano \
sudo \
vim \
wget \
&& \
echo "**** Section cleanup ****" \
&& apt-get clean autoclean -y \
&& apt-get autoremove -y \
&& rm -rf \
/var/lib/apt/lists/* \
/var/tmp/* \
/tmp/* \
&& \
echo
# Install desktop requirements
RUN \
echo "**** Update apt database ****" \
&& apt-get update \
&& \
echo "**** Install desktop requirements ****" \
&& apt-get -y install --no-install-recommends \
dbus-x11 \
libxcomposite-dev \
libxcursor1 \
man-db \ man-db \
mlocate \ mlocate \
nano \
net-tools \ net-tools \
patch \
pciutils \ pciutils \
pkg-config \ pkg-config \
procps \
psmisc \
psutils \
rsync \
screen \
sudo \
unzip \
vim \
wget \
xz-utils \
&& \
echo "**** Install python ****" \
&& apt-get install -y --no-install-recommends \
python3 \ python3 \
python3-numpy \ python3-numpy \
python3-pip \
python3-setuptools \ python3-setuptools \
rsync \
x11vnc \
xauth \
xorg \
xserver-xorg-legacy \
xvfb \
&& \ && \
echo "**** Section cleanup ****" \ echo "**** Section cleanup ****" \
&& apt-get clean autoclean -y \ && apt-get clean autoclean -y \
@@ -123,7 +107,7 @@ RUN \
&& apt-get update \ && apt-get update \
&& \ && \
echo "**** Install supervisor ****" \ echo "**** Install supervisor ****" \
&& apt-get -y install \ && apt-get install -y \
supervisor \ supervisor \
&& \ && \
echo "**** Section cleanup ****" \ echo "**** Section cleanup ****" \
@@ -136,15 +120,36 @@ RUN \
&& \ && \
echo echo
# Install openssh server # Install mesa and vulkan requirements
RUN \ RUN \
echo "**** Update apt database ****" \ echo "**** Update apt database ****" \
&& dpkg --add-architecture i386 \
&& apt-get update \ && apt-get update \
&& \ && \
echo "**** Install openssh server ****" \ echo "**** Install mesa requirements ****" \
&& apt-get -y install \ && apt-get install -y --no-install-recommends \
openssh-server \ libgl1-mesa-dri \
&& echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config \ 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 ****" \ echo "**** Section cleanup ****" \
&& apt-get clean autoclean -y \ && apt-get clean autoclean -y \
@@ -156,6 +161,190 @@ RUN \
&& \ && \
echo echo
# Install X Server requirements
RUN \
echo "**** Update apt database ****" \
&& apt-get update \
&& \
echo "**** Install X Server requirements ****" \
&& apt-get install -y --no-install-recommends \
avahi-utils \
dbus-x11 \
libxcomposite-dev \
libxcursor1 \
wmctrl \
x11-utils \
x11-xfs-utils \
x11-xkb-utils \
x11-xserver-utils \
x11vnc \
xauth \
xbindkeys \
xclip \
xdotool \
xfishtank \
xfonts-base \
xinit \
xorg \
xserver-xorg-core \
xserver-xorg-input-evdev \
xserver-xorg-input-libinput \
xserver-xorg-legacy \
xserver-xorg-video-all \
xserver-xorg-video-dummy \
xvfb \
&& \
echo "**** Section cleanup ****" \
&& apt-get clean autoclean -y \
&& apt-get autoremove -y \
&& rm -rf \
/var/lib/apt/lists/* \
/var/tmp/* \
/tmp/* \
&& \
echo
# Install audio requirements
RUN \
echo "**** Update apt database ****" \
&& apt-get update \
&& \
echo "**** Install X Server requirements ****" \
&& apt-get install -y --no-install-recommends \
pulseaudio \
alsa-utils \
libasound2 \
libasound2-plugins \
&& \
echo "**** Section cleanup ****" \
&& apt-get clean autoclean -y \
&& apt-get autoremove -y \
&& rm -rf \
/var/lib/apt/lists/* \
/var/tmp/* \
/tmp/* \
&& \
echo
# Install desktop environment
RUN \
echo "**** Update apt database ****" \
&& apt-get update \
&& \
echo "**** Install desktop environment ****" \
&& apt-get install -y \
xfce4 \
xfce4-terminal \
msttcorefonts \
fonts-vlgothic \
gedit \
# Delete these as they are not needed at all
&& rm -f \
/usr/share/applications/software-properties-drivers.desktop \
/usr/share/applications/xfce4-about.desktop \
/usr/share/applications/xfce4-session-logout.desktop \
# Hide these apps. They can be displayed if a user really wants them.
&& sed -i '/[Desktop Entry]/a\NoDisplay=true' /usr/share/applications/xfce4-accessibility-settings.desktop \
&& sed -i '/[Desktop Entry]/a\NoDisplay=true' /usr/share/applications/xfce4-color-settings.desktop \
&& sed -i '/[Desktop Entry]/a\NoDisplay=true' /usr/share/applications/xfce4-mail-reader.desktop \
&& sed -i '/[Desktop Entry]/a\NoDisplay=true' /usr/share/applications/vim.desktop \
&& sed -i '/[Desktop Entry]/a\NoDisplay=true' /usr/share/applications/thunar-settings.desktop \
&& sed -i '/[Desktop Entry]/a\NoDisplay=true' /usr/share/applications/thunar.desktop \
&& sed -i '/[Desktop Entry]/a\NoDisplay=true' /usr/share/applications/pavucontrol.desktop \
&& sed -i '/[Desktop Entry]/a\NoDisplay=true' /usr/share/applications/debian-uxterm.desktop \
&& sed -i '/[Desktop Entry]/a\NoDisplay=true' /usr/share/applications/debian-xterm.desktop \
# Force these apps to be "System" Apps rather than "Categories=System;Utility;Core;GTK;Filesystem;"
&& sed -i 's/^Categories=.*$/Categories=System;/' /usr/share/applications/xfce4-appfinder.desktop \
&& sed -i 's/^Categories=.*$/Categories=System;/' /usr/share/applications/thunar-bulk-rename.desktop \
&& sed -i 's/^Categories=.*$/Categories=System;/' /usr/share/applications/org.gnome.gedit.desktop \
&& \
echo "**** Section cleanup ****" \
&& apt-get clean autoclean -y \
&& apt-get autoremove -y \
&& rm -rf \
/var/lib/apt/lists/* \
/var/tmp/* \
/tmp/* \
&& \
echo
# Add support for flatpaks
RUN \
echo "**** Update apt database ****" \
&& apt-get update \
&& \
echo "**** Install flatpak support ****" \
&& apt-get install -y \
bridge-utils \
flatpak \
gnome-software-plugin-flatpak \
libpam-cgfs \
libvirt0 \
lxc \
uidmap \
&& \
echo "**** Configure flatpak ****" \
&& chmod u+s /usr/bin/bwrap \
&& flatpak remote-add flathub https://flathub.org/repo/flathub.flatpakrepo \
&& \
echo "**** Section cleanup ****" \
&& apt-get clean autoclean -y \
&& apt-get autoremove -y \
&& rm -rf \
/var/lib/apt/lists/* \
/var/tmp/* \
/tmp/* \
&& \
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 # Install noVNC
ARG NOVNC_VERSION=1.2.0 ARG NOVNC_VERSION=1.2.0
RUN \ RUN \
@@ -182,8 +371,18 @@ RUN \
&& sed -i '/ document.title =/c\ document.title = "Steam Headless - noVNC";' \ && sed -i '/ document.title =/c\ document.title = "Steam Headless - noVNC";' \
/opt/noVNC/app/ui.js \ /opt/noVNC/app/ui.js \
&& \ && \
echo "**** Update apt database ****" \
&& apt-get update \
&& \
echo "**** Install nginx support ****" \
&& apt-get install -y \
nginx \
&& \
echo "**** Section cleanup ****" \ echo "**** Section cleanup ****" \
&& apt-get clean autoclean -y \
&& apt-get autoremove -y \
&& rm -rf \ && rm -rf \
/var/lib/apt/lists/* \
/tmp/noVNC* \ /tmp/noVNC* \
/tmp/novnc.tar.gz /tmp/novnc.tar.gz
@@ -211,104 +410,34 @@ RUN \
/tmp/websockify-* \ /tmp/websockify-* \
/tmp/websockify.tar.gz /tmp/websockify.tar.gz
# Install desktop environment # Setup audio streaming deps
RUN \
echo "**** Update apt database ****" \
&& apt-get update \
&& \
echo "**** Install desktop environment ****" \
&& apt-get -y install \
xfce4 \
xfce4-terminal \
msttcorefonts \
fonts-vlgothic \
gedit \
&& \
echo "**** Section cleanup ****" \
&& apt-get clean autoclean -y \
&& apt-get autoremove -y \
&& rm -rf \
/var/lib/apt/lists/* \
/var/tmp/* \
/tmp/* \
&& \
echo
# Install firefox
RUN \
echo "**** Update apt database ****" \
&& apt-get update \
&& \
echo "**** Install firefox ****" \
&& apt-get -y install \
firefox-esr \
&& \
echo "**** Section cleanup ****" \
&& apt-get clean autoclean -y \
&& apt-get autoremove -y \
&& rm -rf \
/var/lib/apt/lists/* \
/var/tmp/* \
/tmp/* \
&& \
echo
# Install Steam
RUN \
echo "**** Install steam ****" \
&& dpkg --add-architecture i386 \
&& apt-get update \
&& echo steam steam/question select "I AGREE" | debconf-set-selections \
&& echo steam steam/license note '' | debconf-set-selections \
&& apt-get -y install \
steam \
steam-devices \
vulkan-tools \
mesa-utils \
mesa-vulkan-drivers \
libglx-mesa0:i386 \
mesa-vulkan-drivers:i386 \
libgl1-mesa-dri:i386 \
&& \
echo "**** Section cleanup ****" \
&& apt-get clean autoclean -y \
&& apt-get autoremove -y \
&& rm -rf \
/var/lib/apt/lists/* \
/var/tmp/* \
/tmp/* \
&& \
echo
# Setup browser audio streaming deps
RUN \ RUN \
echo "**** Update apt database ****" \ echo "**** Update apt database ****" \
&& apt-get update \ && apt-get update \
&& \ && \
echo "**** Install audio streaming deps ****" \ echo "**** Install audio streaming deps ****" \
&& apt-get -y install --no-install-recommends \ && apt-get install -y --no-install-recommends \
bzip2 \ bzip2 \
gstreamer1.0-alsa \ gstreamer1.0-alsa \
gstreamer1.0-gl \ gstreamer1.0-gl \
gstreamer1.0-gtk3 \ gstreamer1.0-gtk3 \
gstreamer1.0-libav \ gstreamer1.0-libav \
gstreamer1.0-plugins-bad \
gstreamer1.0-plugins-base \ gstreamer1.0-plugins-base \
gstreamer1.0-plugins-good \ gstreamer1.0-plugins-good \
gstreamer1.0-plugins-ugly \
gstreamer1.0-pulseaudio \ gstreamer1.0-pulseaudio \
gstreamer1.0-qt5 \ gstreamer1.0-qt5 \
gstreamer1.0-tools \ gstreamer1.0-tools \
gstreamer1.0-vaapi \
gstreamer1.0-x \ gstreamer1.0-x \
libglu1-mesa \
libgstreamer1.0-0 \ libgstreamer1.0-0 \
libgtk2.0-0 \
libncursesw5 \ libncursesw5 \
libopenal1 \ libopenal1 \
libsdl-image1.2 \ libsdl-image1.2 \
libsdl-ttf2.0-0 \ libsdl-ttf2.0-0 \
libsdl1.2debian \ libsdl1.2debian \
libsndfile1 \ libsndfile1 \
novnc \
pulseaudio \
ucspi-tcp \ ucspi-tcp \
&& \ && \
echo "**** Section cleanup ****" \ echo "**** Section cleanup ****" \
@@ -321,8 +450,35 @@ RUN \
&& \ && \
echo echo
# Setup video streaming deps
RUN \
echo "**** Update apt database ****" \
&& apt-get update \
&& \
echo "**** Install Intel media drivers and VAAPI ****" \
&& apt-get install -y --no-install-recommends \
intel-media-va-driver-non-free \
i965-va-driver-shaders \
libva2 \
vainfo \
vdpauinfo \
&& \
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 # Configure default user and set env
ENV \ ENV \
PUID=99 \
PGID=100 \
UMASK=000 \
USER="default" \ USER="default" \
USER_PASSWORD="password" \ USER_PASSWORD="password" \
USER_HOME="/home/default" \ USER_HOME="/home/default" \
@@ -332,12 +488,12 @@ RUN \
echo "**** Configure default user '${USER}' ****" \ echo "**** Configure default user '${USER}' ****" \
&& mkdir -p \ && mkdir -p \
${USER_HOME} \ ${USER_HOME} \
/games \
&& useradd -d ${USER_HOME} -s /bin/bash ${USER} \ && useradd -d ${USER_HOME} -s /bin/bash ${USER} \
&& chown -R ${USER} \ && chown -R ${USER} \
${USER_HOME} \ ${USER_HOME} \
/games \ && echo "${USER} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers \
&& echo "${USER} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers && \
echo
# Add FS overlay # Add FS overlay
COPY overlay / COPY overlay /
@@ -345,18 +501,40 @@ COPY overlay /
# Set display environment variables # Set display environment variables
ENV \ ENV \
DISPLAY_CDEPTH="24" \ DISPLAY_CDEPTH="24" \
DISPLAY_DPI="96" \ 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=":0" \ DISPLAY=":55" \
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/"
# Be sure that the noVNC port is exposed # Set pulseaudio environment variables
ENV \
PULSE_SOCKET_DIR="/tmp/pulse" \
PULSE_SERVER="unix:/tmp/pulse/pulse-socket"
# Set container configuration environment variables
ENV \
MODE="primary" \
WEB_UI_MODE="vnc" \
ENABLE_VNC_AUDIO="true" \
NEKO_PASSWORD=neko \
NEKO_PASSWORD_ADMIN=admin \
ENABLE_SUNSHINE="false" \
ENABLE_EVDEV_INPUTS="false"
# Configure required ports
ENV \
PORT_SSH="" \
PORT_NOVNC_WEB="8083" \
NEKO_NAT1TO1=""
# Expose the required ports
EXPOSE 8083 EXPOSE 8083
EXPOSE 32123
# Set entrypoint # Set entrypoint
RUN chmod +x /entrypoint.sh RUN chmod +x /entrypoint.sh

425
Dockerfile.arch Normal file
View File

@@ -0,0 +1,425 @@
# Steam Headless (Arch Linux)
# (WIP) An Arch variant of the steam-headless image
# It is curerently my intent to switch to arch as the main
# image base once SteamOS 3 is released (pending review)
#
FROM archlinux:latest
LABEL maintainer="Josh.5 <jsunnex@gmail.com>"
# Update package repos
RUN \
echo "**** Update package manager ****" \
&& sed -i 's/^NoProgressBar/#NoProgressBar/g' /etc/pacman.conf \
&& echo -e "[multilib]\nInclude = /etc/pacman.d/mirrorlist" >> /etc/pacman.conf \
&& \
echo
# Update locale
RUN \
echo "**** Configure locals ****" \
&& echo 'en_US.UTF-8 UTF-8' > /etc/locale.gen \
&& locale-gen \
&& \
echo
ENV \
LANG=en_US.UTF-8 \
LANGUAGE=en_US:en \
LC_ALL=en_US.UTF-8
# Re-install certificates
RUN \
echo "**** Install certificates ****" \
&& pacman -Syu --noconfirm --needed \
ca-certificates \
&& \
echo "**** Section cleanup ****" \
&& pacman -Scc --noconfirm \
&& \
echo
# Install core packages
RUN \
echo "**** Install tools ****" \
&& pacman -Syu --noconfirm --needed \
bash \
bash-completion \
curl \
git \
less \
man-db \
nano \
net-tools \
pkg-config \
rsync \
screen \
sudo \
unzip \
vim \
wget \
xz \
&& \
echo "**** Install python ****" \
&& pacman -Syu --noconfirm --needed \
python \
python-numpy \
python-pip \
python-setuptools \
&& \
echo "**** Section cleanup ****" \
&& pacman -Scc --noconfirm \
&& \
echo
# Install supervisor
RUN \
echo "**** Install supervisor ****" \
&& pacman -Syu --noconfirm --needed \
supervisor \
&& \
echo "**** Section cleanup ****" \
&& pacman -Scc --noconfirm \
&& \
echo
# XFS requirements
RUN \
echo "**** Install XFS requirements ****" \
&& pacman -Syu --noconfirm --needed \
xfsdump \
xfsprogs \
&& \
echo "**** Section cleanup ****" \
&& pacman -Scc --noconfirm \
&& \
echo
# Install mesa requirements
RUN \
echo "**** Install mesa and vulkan requirements ****" \
&& pacman -Syu --noconfirm --needed \
glu \
libva-mesa-driver \
mesa-utils \
mesa-vdpau \
opencl-mesa \
pciutils \
vulkan-mesa-layers \
&& \
echo "**** Section cleanup ****" \
&& pacman -Scc --noconfirm \
&& \
echo
# Install X Server requirements
# TODO: Remove doubles
# TODO: Things that are not required
RUN \
echo "**** Install X Server requirements ****" \
&& pacman -Syu --noconfirm --needed \
avahi \
dbus \
lib32-fontconfig \
ttf-liberation \
x11vnc \
xorg \
xorg-apps \
xorg-font-util \
xorg-fonts-misc \
xorg-fonts-type1 \
xorg-server \
xorg-server-xephyr \
xorg-server-xvfb \
xorg-xauth \
xorg-xbacklight \
xorg-xhost \
xorg-xinit \
xorg-xinput \
xorg-xkill \
xorg-xprop \
xorg-xrandr \
xorg-xsetroot \
xorg-xwininfo \
&& \
echo "**** Section cleanup ****" \
&& pacman -Scc --noconfirm \
&& \
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
RUN \
echo "**** Install X Server requirements ****" \
&& pacman -Syu --noconfirm --needed \
pulseaudio \
&& \
echo "**** Section cleanup ****" \
&& pacman -Scc --noconfirm \
&& \
echo
# Install openssh server
RUN \
echo "**** Install openssh server ****" \
&& pacman -Syu --noconfirm --needed \
openssh \
&& echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config \
&& \
echo "**** Section cleanup ****" \
&& pacman -Scc --noconfirm \
&& \
echo
# Install noVNC
# TODO: Add nginx
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 "**** Section cleanup ****" \
&& rm -rf \
/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
# Install firefox
# TODO: MOve under de
RUN \
echo "**** Install firefox ****" \
&& pacman -Syu --noconfirm --needed \
firefox \
&& \
echo "**** Section cleanup ****" \
&& pacman -Scc --noconfirm \
&& \
echo
# # Install Steam
# RUN \
# echo "**** Install steam ****" \
# && pacman -Syu --noconfirm --needed \
# lib32-vulkan-icd-loader
# steam \
# vulkan-icd-loader \
# && \
# echo "**** Section cleanup ****" \
# && pacman -Scc --noconfirm \
# && \
# echo
# Install desktop environment
RUN \
echo "**** Install desktop environment ****" \
&& pacman -Syu --noconfirm --needed \
gedit \
xfce4 \
xfce4-terminal \
&& \
echo "**** Section cleanup ****" \
&& pacman -Scc --noconfirm \
&& \
echo
# Add support for flatpaks
RUN \
echo "**** Install flatpak support ****" \
&& pacman -Syu --noconfirm --needed \
flatpak \
xdg-desktop-portal-gtk \
&& \
echo "**** Section cleanup ****" \
&& pacman -Scc --noconfirm \
&& \
echo
# TODO Append to tools
RUN \
echo "**** Install flatpak support ****" \
&& pacman -Syu --noconfirm --needed \
patch \
&& \
echo "**** Section cleanup ****" \
&& pacman -Scc --noconfirm \
&& \
echo
# # Install desktop environment
# RUN \
# echo "**** Install desktop environment ****" \
# && pacman -Syu --noconfirm --needed \
# kde-system-meta \
# konsole \
# plasma-desktop \
# && \
# echo "**** Section cleanup ****" \
# && pacman -Scc --noconfirm \
# && \
# echo
# # Install desktop environment
# RUN \
# echo "**** Install desktop environment ****" \
# && pacman -Syu --noconfirm --needed \
# cinnamon \
# polkit-gnome \
# gnome-terminal \
# && \
# echo "**** Section cleanup ****" \
# && pacman -Scc --noconfirm \
# && \
# echo
# # Setup browser audio streaming deps
# RUN \
# echo "**** Update apt database ****" \
# && apt-get update \
# && \
# echo "**** Install audio streaming deps ****" \
# && apt-get install -y --no-install-recommends \
# bzip2 \
# gstreamer1.0-alsa \
# gstreamer1.0-gl \
# gstreamer1.0-gtk3 \
# gstreamer1.0-libav \
# gstreamer1.0-plugins-base \
# gstreamer1.0-plugins-good \
# gstreamer1.0-pulseaudio \
# gstreamer1.0-qt5 \
# gstreamer1.0-tools \
# gstreamer1.0-x \
# libgstreamer1.0-0 \
# libncursesw5 \
# libopenal1 \
# libsdl-image1.2 \
# libsdl-ttf2.0-0 \
# libsdl1.2debian \
# libsndfile1 \
# ucspi-tcp \
# && \
# echo "**** Section cleanup ****" \
# && apt-get clean autoclean -y \
# && apt-get autoremove -y \
# && rm -rf \
# /var/lib/apt/lists/* \
# /var/tmp/* \
# /tmp/* \
# && \
# echo
# Configure default user and set env
ENV \
USER="default" \
USER_PASSWORD="password" \
USER_HOME="/home/default" \
TZ="Pacific/Auckland" \
USER_LOCALES="en_US.UTF-8 UTF-8"
RUN \
echo "**** Configure default user '${USER}' ****" \
&& mkdir -p \
${USER_HOME} \
&& useradd -d ${USER_HOME} -s /bin/bash ${USER} \
&& chown -R ${USER} \
${USER_HOME} \
&& echo "${USER} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
# Add FS overlay
COPY overlay /
# Set display environment variables
ENV \
DISPLAY_CDEPTH="24" \
DISPLAY_REFRESH="60" \
DISPLAY_SIZEH="900" \
DISPLAY_SIZEW="1600" \
DISPLAY_VIDEO_PORT="DFP" \
DISPLAY=":55" \
NVIDIA_DRIVER_CAPABILITIES="all" \
NVIDIA_VISIBLE_DEVICES="all"
# Set container configuration environment variables
ENV \
MODE="primary" \
ENABLE_VNC_AUDIO="true"
# Configure required ports
ENV \
PORT_SSH="" \
PORT_NOVNC_WEB="8083"
# Expose the required ports
EXPOSE 8083
# Set entrypoint
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]

View File

@@ -1,41 +1,66 @@
# Headless Steam Service # Headless Steam Service
![](./images/banner.jpg)
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 in the browser with audio. Connect another device and use it with Steam Remote Play. Easily deploy a Steam Docker instance in seconds.
## Features: ## Features:
- Full video/audio noVNC web access to a Xfce4 Desktop
- NVIDIA GPU support - NVIDIA GPU support
- AMD GPU support
- Full video/audio noVNC web access to a Xfce4 Desktop
- Root access - Root access
- SSH server for remote terminal access
--- ---
## Notes: ## Notes:
### ADDITIONAL SOFTWARE: ### ADDITIONAL SOFTWARE:
If you wish to install additional applications, you can generate a If you wish to install additional applications, you can generate a script inside the `~/init.d` directory ending with ".sh".
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.
### 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. 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. 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.
### GAMES LIBRARY: ### GAMES LIBRARY:
It is recommended that you mount your games library to `/games` and configure Steam to add that path. It is recommended that you mount your games library to `/mnt/games` and configure Steam to add that path.
### AUTO START APPLICATIONS: ### AUTO START APPLICATIONS:
In this container, Steam is configured to automatically start. If you wish to add additional services to automatically start, add them under **Applications > Settings > Session and Startup** in the WebUI. In this container, Steam is configured to automatically start. If you wish to add additional services to automatically start,
add them under **Applications > Settings > Session and Startup** in the WebUI.
### NETWORK MODE: ### NETWORK MODE:
If you want to use the container as a Steam Remote Play (previously "In Home Streaming") host device you should create a custom network and assign this container it's own IP, if you don't do this the traffic will be routed through the internet since Steam thinks you are on a different network. If you want to use the container as a Steam Remote Play (previously "In Home Streaming") host device you should create a custom network and assign this container it's own IP, if you don't do this the traffic will be routed through the internet since Steam thinks you are on a different network.
### USING HOST X SERVER:
If your host is already running X, you can just use that. To do this, be sure to configure:
- DISPLAY=:0
**(Variable)** - *Configures the sceen to use the primary display. Set this to whatever your host is using*
- MODE=secondary
**(Variable)** - *Configures the container to not start an X server of its own*
- HOST_DBUS=true
**(Variable)** - *Optional - Configures the container to use the host dbus process*
- /run/dbus:/run/dbus:ro
**(Mount)** - *Optional - Configures the container to use the host dbus process*
--- ---
## Running: ## Installation:
- [Docker Compose](./docs/docker-compose.md)
- [Unraid](./docs/unraid.md)
- [Ubuntu Server](./docs/ubuntu-server.md)
---
## Running locally:
For a development environment, I have created a script in the devops directory. For a development environment, I have created a script in the devops directory.
--- ---
## TODO: ## TODO:
- Configure xorg.conf with no NVIDIA GPU - Remove SSH
- Lock SSH access to user only (remove root access)
- Require user to enter password for sudo - Require user to enter password for sudo
- Document how to run this container - Document how to run this container:
- Other server OS
- TrueNAS Scale

View File

@@ -5,62 +5,132 @@
# File Created: Saturday, 8th January 2022 2:34:23 pm # File Created: Saturday, 8th January 2022 2:34:23 pm
# Author: Josh.5 (jsunnex@gmail.com) # Author: Josh.5 (jsunnex@gmail.com)
# ----- # -----
# Last Modified: Monday, 10th January 2022 11:04:51 pm # Last Modified: Tuesday, 8th February 2022 8:00:29 am
# Modified By: Josh.5 (jsunnex@gmail.com) # Modified By: Console and webGui login account (jsunnex@gmail.com)
### ###
script_path=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ); script_path=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd );
project_base_path=$(realpath ${script_path}/..); project_base_path=$(realpath ${script_path}/..);
if [[ ${1} == "stop" ]]; then # Parse params
docker stop steam-headless additional_docker_params=""
docker rm steam-headless 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 $? exit $?
elif [[ ${1} == "tail" ]]; then elif [[ "${script_mode}" == "tail" ]]; then
docker logs -f steam-headless docker logs -f ${container_name}
exit $? exit $?
elif [[ ${1} == "user" ]]; then elif [[ "${script_mode}" == "user" ]]; then
docker exec -ti --user default steam-headless bash docker exec -ti --user default ${container_name} bash
exit $? exit $?
elif [[ ${1} == "root" ]]; then elif [[ "${script_mode}" == "root" ]]; then
docker exec -ti --user 0 steam-headless bash docker exec -ti --user 0 ${container_name} bash
exit $? exit $?
fi fi
docker stop steam-headless # Stop previous instance
docker rm steam-headless docker stop ${container_name}
docker rm ${container_name}
sleep 1 sleep 1
docker run -d --name='steam-headless' \ # Run
--privileged=true \ cmd="docker run -d --name='${container_name}' \
--net='br0' --ip='192.168.1.208' \ --privileged=true \
--cpuset-cpus='3,9,4,10,5,11' \ -e PUID='99' \
-e PUID="99" \ -e PGID='100' \
-e PGID="100" \
-e UMASK='000' \ -e UMASK='000' \
-e USER_PASSWORD="password" \ -e USER_PASSWORD='password' \
-e USER="default" \ -e USER='default' \
-e HOME="/home/test" \ -e USER_HOME='/home/default' \
-e USER_HOME="/home/default" \ -e TZ='Pacific/Auckland' \
-e TZ="Pacific/Auckland" \ -e USER_LOCALES='en_US.UTF-8 UTF-8' \
-e USER_LOCALES="en_US.UTF-8 UTF-8" \ -e DISPLAY_CDEPTH='24' \
-e DISPLAY_CDEPTH="24" \ -e DISPLAY_REFRESH='60' \
-e DISPLAY_DPI="96" \ -e DISPLAY_SIZEH='720' \
-e DISPLAY_REFRESH="60" \ -e DISPLAY_SIZEW='1280' \
-e DISPLAY_SIZEH="720" \ -e DISPLAY_VIDEO_PORT='DFP' \
-e DISPLAY_SIZEW="1280" \ -e DISPLAY=':55' \
-e DISPLAY_VIDEO_PORT="DFP" \ -e NVIDIA_DRIVER_CAPABILITIES='all' \
-e DISPLAY=":0" \ -e NVIDIA_VISIBLE_DEVICES='all' \
-e NVIDIA_DRIVER_CAPABILITIES="all" \ -e ENABLE_VNC_AUDIO='false' \
-e NVIDIA_VISIBLE_DEVICES="all" \ -v '${project_base_path}/config/home/default-${container_name}':'/home/default':'rw' \
-v "${project_base_path}/config/home/default":'/home/default':'rw' \ -v '/tmp/.X11-unix/':'/tmp/.X11-unix/':'rw' \
--hostname='steam-headless' \ -v '/dev/input':'/dev/input':'ro' \
--hostname='${container_name}' \
--add-host=${container_name}:127.0.0.1 \
--shm-size=2G \ --shm-size=2G \
--runtime=nvidia \ ${additional_docker_params} \
josh5/steam-headless:latest josh5/steam-headless:${tag}"
echo ${cmd}
bash -c "${cmd}"
docker logs -f ${container_name}
docker logs -f steam-headless

91
docs/compose-files/.env Normal file
View File

@@ -0,0 +1,91 @@
# ____ _
# / ___| _ _ ___| |_ ___ _ __ ___
# \___ \| | | / __| __/ _ \ '_ ` _ \
# ___) | |_| \__ \ || __/ | | | | |
# |____/ \__, |___/\__\___|_| |_| |_|
# |___/
#
NAME='SteamHeadless'
TZ='Pacific/Auckland'
USER_LOCALES='en_US.UTF-8 UTF-8'
DISPLAY=':55'
SHM_SIZE='2G'
## DOCKER_RUNTIME:
## Options: ['runc', 'nvidia']
## Description: The name of an implementation of OCI Runtime Spec
## Available runtimes are listed when you run `docker info`.
## Your system may have other options available. As a simple rule, if you are
## using an NVIDIA GPU, set this to 'nvidia' for anything else, set this to 'runc'.
DOCKER_RUNTIME='runc'
# ____ __ _ _ _ _
# | _ \ ___ / _| __ _ _ _| | |_ | | | |___ ___ _ __
# | | | |/ _ \ |_ / _` | | | | | __| | | | / __|/ _ \ '__|
# | |_| | __/ _| (_| | |_| | | |_ | |_| \__ \ __/ |
# |____/ \___|_| \__,_|\__,_|_|\__| \___/|___/\___|_|
#
#
PUID='1000'
PGID='1000'
UMASK='000'
USER_PASSWORD='password'
# ____ _
# / ___| ___ _ ____ _(_) ___ ___ ___
# \___ \ / _ \ '__\ \ / / |/ __/ _ \/ __|
# ___) | __/ | \ V /| | (_| __/\__ \
# |____/ \___|_| \_/ |_|\___\___||___/
#
#
# Mode
## MODE:
## Options: ['primary', 'secondary']
## Description: Steam Headless containers can run in a secondary mode that will only start
## a Steam process that will then use the X server of either the host or another
## Steam Headless container running in 'primary' mode.
MODE='primary'
# Web UI
## WEB_UI_MODE:
## Options: ['vnc', 'neko', 'none']
## Description: Configures the WebUI to use for accessing the virtual desktop.
WEB_UI_MODE='vnc'
## ENABLE_VNC_AUDIO:
## Options: ['true', 'false']
## Description: Enables audio over for the VNC Web UI if 'WEB_UI_MODE' is set to 'vnc'.
ENABLE_VNC_AUDIO='true'
## PORT_NOVNC_WEB:
## Description: Configure the port to use for the WebUI.
PORT_NOVNC_WEB='8083'
## NEKO_NAT1TO1:
## Description: Configure nat1to1 for the neko WebUI if it is enabled by setting 'WEB_UI_MODE' to 'neko'. This will need to be the IP address of the host.
NEKO_NAT1TO1=''
# Sunshine
## ENABLE_SUNSHINE:
## Options: ['true', 'false']
## Description: Enable Sunshine streaming service.
ENABLE_SUNSHINE='false'
## SUNSHINE_USER:
## Description: Set the Sunshine service username.
#SUNSHINE_USER='admin'
## SUNSHINE_PASS:
## Description: Set the Sunshine service password.
#SUNSHINE_PASS='admin'
# Xorg
## ENABLE_EVDEV_INPUTS:
## Options: ['true', 'false']
## Description: Enable Keyboard and Mouse Passthrough. This will configure the Xorg server to catch all evdev events for Keyboard, Mouse, etc.
ENABLE_EVDEV_INPUTS='true'
# Nvidia specific config (not required for non Nvidia GPUs)
## NVIDIA_DRIVER_CAPABILITIES:
## Options: ['all', 'compute', 'compat32', 'graphics', 'utility', 'video', 'display']
## Description: Controls which driver libraries/binaries will be mounted inside the container.
NVIDIA_DRIVER_CAPABILITIES='all'
## NVIDIA_DRIVER_CAPABILITIES:
## Options: ['all', 'none', '<GPU UUID>']
## Description: Controls which GPUs will be made accessible inside the container.
NVIDIA_VISIBLE_DEVICES='all'

View 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:

41
docs/docker-compose.md Normal file
View File

@@ -0,0 +1,41 @@
# Docker Compose
Follow these instructions to configure a docker-compose.yml for your system.
> __Note__
>
> These instructions assume that you have docker and docker-compose installed for your system.
>
> Depending on how you have installed this, the commands to execute docker compose may vary.
## PREPARE DIRECTORY:
> __Warning__
>
> These commands are meant to be run as your user. Do not run them as root.
>
> 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:
```
sudo mkdir -p /opt/container-services/steam-headless
sudo chown -R $(id -u):$(id -g) /opt/container-services/steam-headless
```
Create a directory for your service config data:
```
sudo mkdir -p /opt/container-data/steam-headless/{home,.X11-unix,pulse}
sudo chown -R $(id -u):$(id -g) /opt/container-data/steam-headless
```
Create a Steam Headless `/opt/container-services/steam-headless/docker-compose.yml` file.
Populate this file with the contents of the default [Docker Compose File](./compose-files/docker-compose.default.yml).
## CONFIGURE ENV:
Create a Steam Headless `/opt/container-services/steam-headless/.env` file with the contents found in this example [Environment File](./compose-files/.env).
Edit these variables as required.

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

22
docs/ubuntu-server.md Normal file
View File

@@ -0,0 +1,22 @@
# Ubuntu Server
Follow these instructions to install Steam Headless on Ubuntu Server.
> __Note__
>
> This assumes that your Ubuntu Server has not be configured to run any desktop environment!
>
> This will not work with Ubuntu Desktop.
## INSTALL DOCKER:
Install docker-ce to your Ubuntu server following the [official instrctions](https://docs.docker.com/engine/install/ubuntu/).
Ensure you install the `docker-compose-plugin` mentioned within these instructions
## CONFIGURE DOCKER COMPOSE:
Once you have installed docker, follow the [Compose Files](./docker-compose.md) section and select the right configuration file for your hardware.

58
docs/unraid.md Normal file
View File

@@ -0,0 +1,58 @@
# Unraid
Follow these instructions to install Steam Headless on Unraid
## CONTAINER TEMPLATE:
1. Navigate to "**APPS**" tab.
2. Search for "*steam-headless*"
3. Select either **Install** or **Actions > Install** from the search result.
![](./images/install-steam-headless-unraid-ca.png)
4. Configure the template as required.
## GPU CONFIGURATION:
This container can use your dedicated GPU.
In order for it to do this you need to have either the Nvidia-Driver or Radeon-Top plugin installed.
### NVIDIA
1. Install the [Nvidia-Driver Plugin](https://forums.unraid.net/topic/98978-plugin-nvidia-driver/) by [ich777](https://forums.unraid.net/profile/72388-ich777/). This will maintain an up-to-date NVIDIA driver installation on your Unraid server.
![](./images/unraid-nvidia-plugin.png)
2. Toggle the steam-headless Docker Container template editor to "**Advanced View**".
3. In the "**Extra Parameters**" field, ensure that you have the "--runtime=nvidia" parameter added.
![](./images/unraid-steam-headless-template-nvidia-extra-params.png)
4. (Optional - This step is only necessary if you only multiple NVIDIA GPUs. If you have a single GPU, then leaving this as "all" is fine.) Expand the **Show more settings...** section near the bottom of the template. In the **Nvidia GPU UUID**: (NVIDIA_VISIBLE_DEVICES) variable, copy your GPU UUID (can be found in the Unraid Nvidia Plugin. See that forum thread for details).
### AMD
1. Install the [Radeon-Top Plugin](https://forums.unraid.net/topic/92865-support-ich777-amd-vendor-reset-coraltpu-hpsahba/) by [ich777](https://forums.unraid.net/profile/72388-ich777/).
![](./images/unraid-amd-plugin.png)
2. Profit
## ADDING CONTROLLER SUPPORT:
Unraid's Linux kernel by default does not have the modules required to support controller input. Steam requires these modules to be able to create the virtual "Steam Input Gamepad Emulation" device that it can then map buttons to.
[ich777](https://forums.unraid.net/profile/72388-ich777/) has kindly offered to build and maintain the required modules for the Unraid kernel as he already has a CI/CD pipeline in place and a small number of other kernel modules that he is maintaining for other projects. So a big thanks to him for that!
> __Note__
>
> This may no longer be required with Unraid v6.11 release (TBD). The required uinput module should be added to the kernel for that release.
1. Install the **uinput** plugin from the **Apps** tab.
![](./images/unraid-steam-headless-install-uinput-plugin.png)
2. The container will not be able to receive kernel events from the host unless the **Network Type:** is set to "*host*". Ensure that you container is configured this way.
![](./images/unraid-steam-headless-configure-network-as-host.png)
> __Warning__
>
> Be aware that, by default, this container requires at least 8083 available for the WebUI to work. It will also require any ports that Steam requires for Steam Remote Play.
You can override the default ports used by the container with these variables:
- PORT_NOVNC_WEB (Default: 8083)
- WEB_UI_MODE (Default: 'vnc' - Set to 'none' to disable the WebUI)
3. No server restart is required, however. Ensure that the **steam-headless** Docker container is recreated after installing the **uinput** plugin for it to be able to detect the newly added module.

BIN
images/banner.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 KiB

View File

@@ -1,12 +1,12 @@
#!/usr/bin/env bash #!/usr/bin/env bash
### ###
# File: entrypoint.sh # File: entrypoint.sh
# Project: docker-steamos # Project: docker-steam-headless
# File Created: Saturday, 8th January 2022 7:08:46 pm # File Created: Saturday, 8th January 2022 7:08:46 pm
# Author: Josh.5 (jsunnex@gmail.com) # Author: Josh.5 (jsunnex@gmail.com)
# ----- # -----
# Last Modified: Tuesday, 11th January 2022 1:02:16 am # Last Modified: Saturday, 22nd January 2022 8:03:33 pm
# Modified By: Josh.5 (jsunnex@gmail.com) # Modified By: Console and webGui login account (jsunnex@gmail.com)
### ###
set -e set -e
@@ -17,8 +17,13 @@ if [ ! -z "$@" ]; then
exit $? exit $?
fi fi
# Execute all init scripts # Print the current version (if the file exists)
for init_script in /scripts/*.sh ; do if [[ -f /version.txt ]]; then
cat /version.txt
fi
# Execute all container init scripts
for init_script in /etc/cont-init.d/*.sh ; do
echo echo
echo "[ ${init_script}: executing... ]" echo "[ ${init_script}: executing... ]"
sed -i 's/\r$//' "${init_script}" sed -i 's/\r$//' "${init_script}"
@@ -37,11 +42,25 @@ for user_init_script in ${USER_HOME}/init.d/*.sh ; do
echo echo
echo "[ USER:${user_init_script}: executing... ]" echo "[ USER:${user_init_script}: executing... ]"
sed -i 's/\r$//' "${user_init_script}" sed -i 's/\r$//' "${user_init_script}"
source "${user_init_script}"
# Execute user script in sub process.
# This way if it is messed up, we dont get caught in an init loop
chmod +x "${user_init_script}"
cat "${user_init_script}" | bash
fi fi
done done
# Ensure all scripts are executable
chmod a+rwx /opt/scripts/*.sh
# Start supervisord
echo
echo "**** Starting supervisord ****"; echo "**** Starting supervisord ****";
exec /usr/bin/supervisord -c /etc/supervisor/supervisord.conf --nodaemon echo "Logging all root services to '/var/log/supervisor/'"
echo "Logging all user services to '/home/${USER}/.cache/log/'"
echo
mkdir -p /var/log/supervisor
chmod a+rw /var/log/supervisor
exec /usr/bin/supervisord -c /etc/supervisord.conf --nodaemon --user root

View File

@@ -0,0 +1,102 @@
#!/usr/bin/env bash
###
# File: 10-setup_user.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:27:10 am
# Modified By: Josh.5 (jsunnex@gmail.com)
###
PUID=${PUID:-99}
PGID=${PGID:-100}
UMASK=${UMASK:-000}
USER_PASSWORD=${USER_PASSWORD:-password}
echo "**** Configure default user ****"
echo "Setting default user uid=${PUID}(${USER}) gid=${PGID}(${USER})"
usermod -o -u "${PUID}" ${USER}
groupmod -o -g "${PGID}" ${USER}
echo "Adding default user to video, audio, input and pulse groups"
usermod -a -G video,audio,input,pulse ${USER}
echo "Adding default user to any additional required device groups"
device_nodes=( /dev/uinput /dev/input/event* /dev/dri/* )
added_groups=""
for dev in "${device_nodes[@]}"; do
# Only process $dev if it's a character device
if [[ ! -c "${dev}" ]]; then
continue
fi
# Get group name and ID
dev_group=$(stat -c "%G" "${dev}")
dev_gid=$(stat -c "%g" "${dev}")
# Dont add root
if [[ "${dev_gid}" = 0 ]]; then
continue
fi
# Create a name for the group ID if it does not yet already exist
if [[ "${dev_group}" = "UNKNOWN" ]]; then
dev_group="user-gid-${dev_gid}"
groupadd -g $dev_gid "${dev_group}"
fi
# Add group to user
if [[ "${added_groups}" != *"${dev_group}"* ]]; then
echo "Adding user '${USER}' to group: '${dev_group}' for device: ${dev}"
usermod -a -G ${dev_group} ${USER}
added_groups=" ${added_groups} ${dev_group} "
fi
done
echo "Setting umask to ${UMASK}";
umask ${UMASK}
# TODO: Move this to its own 'display' init script. It does not really belong here
# Configure the 'XDG_RUNTIME_DIR' path
echo "Create the user XDG_RUNTIME_DIR path '${XDG_RUNTIME_DIR}'"
mkdir -p ${XDG_RUNTIME_DIR}
# Ensure it is owned by the 'default' user
chown -R ${PUID}:${PGID} ${XDG_RUNTIME_DIR}
# Ensure only the 'default' user can access this directory
chmod 700 ${XDG_RUNTIME_DIR}
# Set the default background
mkdir -p /etc/alternatives
ln -sf /usr/share/backgrounds/steam.jpg /etc/alternatives/desktop-background
chmod a+r /etc/alternatives/desktop-background
# Setup home directory and permissions
echo "Adding default home directory template"
mkdir -p ${USER_HOME}
chown -R ${PUID}:${PGID} /etc/home_directory_template
rsync -aq --ignore-existing /etc/home_directory_template/ ${USER_HOME}/
# Setup services log path
echo "Setting ownership of all log files in '${USER_HOME}/.cache/log'"
mkdir -p "${USER_HOME}/.cache/log"
chown -R ${PUID}:${PGID} "${USER_HOME}/.cache/log"
# Set the root and user password
echo "Setting root password"
echo "root:${USER_PASSWORD}" | chpasswd
echo "Setting user password"
echo "${USER}:${USER_PASSWORD}" | chpasswd
# Set root XDG_RUNTIME_DIR path
mkdir -p /tmp/runtime-root
chown root:root /tmp/runtime-root
echo "DONE"

View 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"

View File

@@ -0,0 +1,26 @@
# Configure dbus
echo "**** Configure container dbus ****";
if [[ "${HOST_DBUS}" == "true" ]]; then
echo "Container configured to use the host dbus";
# Disable supervisord script
sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/dbus.ini
else
echo "Container configured to run its own dbus";
# 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
echo "DONE"

View File

@@ -0,0 +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)
###
# Running udev only works in privileged container
# Source: https://github.com/balena-io-playground/balena-base-images/
tmp_mount='/tmp/privileged_test'
mkdir -p "${tmp_mount}"
if mount -t devtmpfs none "${tmp_mount}" &> /dev/null; then
is_privileged=true
umount "${tmp_mount}"
else
is_privileged=false
fi
rm -rf "${tmp_mount}"
if [[ "${is_privileged}" == "true" ]]; then
echo "**** Configure container to run udev management ****";
# Enable supervisord script
sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/udev.ini
# Make startup script executable
chmod +x /usr/bin/start-udev.sh
# Configure udev permissions
if [[ -f /lib/udev/rules.d/60-steam-input.rules ]]; then
sed -i 's/MODE="0660"/MODE="0666"/' /lib/udev/rules.d/60-steam-input.rules
fi
else
# Disable supervisord script
sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/udev.ini
fi
if [[ -e /dev/uinput ]]; then
echo "**** Ensure the default user has permission to r/w on input devices ****";
chmod 0666 /dev/uinput
fi
echo "DONE"

View File

@@ -0,0 +1,36 @@
echo "**** Configure pulseaudio ****"
if [ "${MODE}" == "s" ] | [ "${MODE}" == "secondary" ]; then
echo "Configure pulseaudio as simple dummy audio"
sed -i 's|^; autospawn.*$|autospawn = no|' /etc/pulse/client.conf
sed -i 's|^; daemon-binary.*$|daemon-binary = /bin/true|' /etc/pulse/client.conf
sed -i 's|^; flat-volumes.*$|flat-volumes = yes|' /etc/pulse/daemon.conf
else
echo "Configure pulseaudio to pipe audio to a socket"
# Ensure pulseaudio directories have the correct permissions
mkdir -p \
${PULSE_SOCKET_DIR} \
${USER_HOME:?}/.config/pulse
chmod -R a+rw ${PULSE_SOCKET_DIR}
chown -R ${PUID}:${PGID} ${USER_HOME:?}/.config/pulse
# Configure the palse audio socket
sed -i "s|^; default-server.*$|default-server = ${PULSE_SERVER}|" /etc/pulse/client.conf
sed -i "s|^load-module module-native-protocol-unix.*$|load-module module-native-protocol-unix socket=${PULSE_SOCKET_DIR}/pulse-socket auth-anonymous=1|" \
/etc/pulse/default.pa
# Disable pulseaudio from respawning (https://unix.stackexchange.com/questions/204522/how-does-pulseaudio-start)
sed -i 's|^; autospawn.*$|autospawn = no|' /etc/pulse/client.conf
sed -i 's|^; daemon-binary.*$|daemon-binary = /bin/true|' /etc/pulse/client.conf
# Enable debug logging
if [ "X${DEBUGGING:-}" == "X" ]; then
sed -i 's|^; log-level.*$|log-level = debug|' /etc/pulse/daemon.conf
fi
fi
chown -R ${USER} /etc/pulse
echo "DONE"

View File

@@ -0,0 +1,149 @@
# Fech NVIDIA GPU device (if one exists)
if [ "${NVIDIA_VISIBLE_DEVICES:-}" == "all" ]; then
export gpu_select=$(nvidia-smi --format=csv --query-gpu=uuid 2> /dev/null | sed -n 2p)
elif [ -z "${NVIDIA_VISIBLE_DEVICES:-}" ]; then
export gpu_select=$(nvidia-smi --format=csv --query-gpu=uuid 2> /dev/null | sed -n 2p)
else
export gpu_select=$(nvidia-smi --format=csv --id=$(echo "$NVIDIA_VISIBLE_DEVICES" | cut -d ',' -f1) --query-gpu=uuid | sed -n 2p)
if [ -z "$gpu_select" ]; then
export gpu_select=$(nvidia-smi --format=csv --query-gpu=uuid 2> /dev/null | sed -n 2p)
fi
fi
# NVIDIA Params
export nvidia_pci_address="$(nvidia-smi --format=csv --query-gpu=pci.bus_id --id="${gpu_select}" 2> /dev/null | sed -n 2p | cut -d ':' -f2,3)"
export nvidia_gpu_name=$(nvidia-smi --format=csv --query-gpu=name --id="${gpu_select}" 2> /dev/null | sed -n 2p)
export nvidia_host_driver_version="$(nvidia-smi 2> /dev/null | grep NVIDIA-SMI | cut -d ' ' -f3)"
# Intel params
# This figures out if it's an intel CPU with integrated GPU
export intel_cpu_model="$(lscpu | grep 'Model name:' | grep -i intel | cut -d':' -f2 | xargs)"
# We need to check if the user has an intel ARC GPU as well
export intel_gpu_model="$(lspci | grep -i "VGA compatible controller: Intel" | cut -d':' -f3 | xargs)"
# AMD params
export amd_cpu_model="$(lscpu | grep 'Model name:' | grep -i amd | cut -d':' -f2 | xargs)"
export amd_gpu_model="$(lspci | grep -i vga | grep -i amd)"
function download_driver {
mkdir -p ${USER_HOME}/Downloads
chown -R ${USER} ${USER_HOME}/Downloads
if [[ ! -f "${USER_HOME}/Downloads/NVIDIA_${nvidia_host_driver_version}.run" ]]; then
echo "Downloading driver v${nvidia_host_driver_version}"
wget -q --show-progress --progress=bar:force:noscroll \
-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
mv /tmp/NVIDIA.run ${USER_HOME}/Downloads/NVIDIA_${nvidia_host_driver_version}.run
fi
}
function install_nvidia_driver {
# Check here if the currently installed version matches using nvidia-settings
nvidia_settings_version=$(nvidia-settings --version 2> /dev/null | grep version | cut -d ' ' -f 4)
[[ "${nvidia_settings_version}x" == "${nvidia_host_driver_version}x" ]] && return 0;
# Download the driver (if it does not yet exist locally)
download_driver
# if command -v pacman &> /dev/null; then
# echo "Install NVIDIA vulkan utils" \
# && pacman -Syu --noconfirm --needed \
# lib32-nvidia-utils \
# lib32-vulkan-icd-loader
# nvidia-utils \
# vulkan-icd-loader \
# && echo
# fi
echo "Installing NVIDIA driver v${nvidia_host_driver_version} to match what is running on the host"
chmod +x ${USER_HOME}/Downloads/NVIDIA_${nvidia_host_driver_version}.run
${USER_HOME}/Downloads/NVIDIA_${nvidia_host_driver_version}.run \
--silent \
--accept-license \
--skip-depmod \
--skip-module-unload \
--no-kernel-modules \
--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
}
function install_amd_gpu_driver {
echo "Install AMD vulkan driver"
if command -v pacman &> /dev/null; then
pacman -Syu --noconfirm --needed \
lib32-mesa \
lib32-vulkan-icd-loader \
lib32-vulkan-radeon \
vulkan-icd-loader \
vulkan-radeon
# There is currently nothing to install inside the debian container. This already comes with the vulken drives that are required
# elif command -v apt-get &> /dev/null; then
# [[ "${APT_UPDATED:-false}" == 'false' ]] && apt-get update && export APT_UPDATED=true
# apt-get install -y \
# libvulkan1 \
# libvulkan1:i386 \
# mesa-vulkan-drivers \
# mesa-vulkan-drivers:i386
fi
}
function install_intel_gpu_driver {
echo "Install Intel vulkan driver"
if command -v pacman &> /dev/null; then
pacman -Syu --noconfirm --needed \
lib32-mesa \
lib32-vulkan-icd-loader \
lib32-vulkan-intel \
vulkan-icd-loader \
vulkan-intel
# There is currently nothing to install inside the debian container. This already comes with the vulken drives that are required
# elif command -v apt-get &> /dev/null; then
# [[ "${APT_UPDATED:-false}" == 'false' ]] && apt-get update && export APT_UPDATED=true
# apt-get install -y \
# libvulkan1 \
# libvulkan1:i386 \
# mesa-vulkan-drivers \
# mesa-vulkan-drivers:i386
fi
}
# NVIDIA GPU
if [[ ! -z ${nvidia_pci_address} ]]; then
echo "**** Found NVIDIA device '${nvidia_gpu_name}' ****";
install_nvidia_driver
else
echo "**** No NVIDIA device found ****";
fi
# Intel Arc GPU or Intel CPU with possible iGPU
if [[ ! -z ${intel_gpu_model} ]]; then
echo "**** Found Intel device '${intel_gpu_model}' ****";
install_intel_gpu_driver
elif [[ ! -z ${intel_cpu_model} ]]; then
echo "**** Found Intel device '${intel_cpu_model}' ****";
install_intel_gpu_driver
else
echo "**** No Intel device found ****";
fi
# AMD GPU
if [[ ! -z ${amd_gpu_model} ]]; then
echo "**** Found AMD device '${amd_gpu_model}' ****";
install_amd_gpu_driver
else
echo "**** No AMD device found ****";
fi
echo "DONE"

View File

@@ -0,0 +1,122 @@
# Fech NVIDIA GPU device (if one exists)
if [ "${NVIDIA_VISIBLE_DEVICES:-}" == "all" ]; then
export gpu_select=$(nvidia-smi --format=csv --query-gpu=uuid 2> /dev/null | sed -n 2p)
elif [ -z "${NVIDIA_VISIBLE_DEVICES:-}" ]; then
export gpu_select=$(nvidia-smi --format=csv --query-gpu=uuid 2> /dev/null | sed -n 2p)
else
export gpu_select=$(nvidia-smi --format=csv --id=$(echo "$NVIDIA_VISIBLE_DEVICES" | cut -d ',' -f1) --query-gpu=uuid | sed -n 2p)
if [ -z "$gpu_select" ]; then
export gpu_select=$(nvidia-smi --format=csv --query-gpu=uuid 2> /dev/null | sed -n 2p)
fi
fi
export nvidia_gpu_hex_id=$(nvidia-smi --format=csv --query-gpu=pci.bus_id --id="${gpu_select}" 2> /dev/null | sed -n 2p)
export monitor_connected=$(cat /sys/class/drm/card*/status | awk '/^connected/ { print $1; }' | head -n1)
# Fech current configuration (if modified in UI)
if [ -f "${USER_HOME}/.config/xfce4/xfconf/xfce-perchannel-xml/displays.xml" ]; then
new_display_sizew=$(cat ${USER_HOME}/.config/xfce4/xfconf/xfce-perchannel-xml/displays.xml | grep Resolution | head -n1 | grep -oP '(?<=value=").*?(?=")' | cut -d'x' -f1)
new_display_sizeh=$(cat ${USER_HOME}/.config/xfce4/xfconf/xfce-perchannel-xml/displays.xml | grep Resolution | head -n1 | grep -oP '(?<=value=").*?(?=")' | cut -d'x' -f2)
new_display_refresh=$(cat ${USER_HOME}/.config/xfce4/xfconf/xfce-perchannel-xml/displays.xml | grep RefreshRate | head -n1 | grep -oP '(?<=value=").*?(?=")' | cut -d'x' -f2)
if [ "${new_display_sizew}x" != "x" ] && [ "${new_display_sizeh}x" != "x" ] && [ "${new_display_refresh}x" != "x" ]; then
export DISPLAY_SIZEW="${new_display_sizew}"
export DISPLAY_SIZEH="${new_display_sizeh}"
# Round refresh rate to closest multiple of 60
export DISPLAY_REFRESH="$(echo ${new_display_refresh} | awk '{rounded = int(($1 + 30) / 60) * 60; if (rounded < 30) rounded += 60; print rounded}')"
fi
fi
# Configure a NVIDIA X11 config
function configure_nvidia_x_server {
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)
IFS=":." ARR_ID=(${nvidia_gpu_hex_id})
unset IFS
bus_id=PCI:$((16#${ARR_ID[1]})):$((16#${ARR_ID[2]})):$((16#${ARR_ID[3]}))
echo "Configuring X11 with PCI bus ID: '${bus_id}'"
export MODELINE=$(cvt -r "${DISPLAY_SIZEW}" "${DISPLAY_SIZEH}" "${DISPLAY_REFRESH}" | sed -n 2p)
echo "Writing X11 config with ${MODELINE}"
connected_monitor="--use-display-device=None"
if [[ "X${DISPLAY_VIDEO_PORT:-}" != "X" ]]; then
connected_monitor="--connected-monitor=${DISPLAY_VIDEO_PORT:?}"
fi
nvidia-xconfig --virtual="${DISPLAY_SIZEW:?}x${DISPLAY_SIZEH:?}" --depth="${DISPLAY_CDEPTH:?}" --mode=$(echo "${MODELINE:?}" | awk '{print $2}' | tr -d '"') --allow-empty-initial-configuration --no-probe-all-gpus --busid="${bus_id:?}" --no-multigpu --no-sli --no-base-mosaic --only-one-x-screen ${connected_monitor:?}
sed -i '/Driver\s\+"nvidia"/a\ Option "ModeValidation" "NoMaxPClkCheck, NoEdidMaxPClkCheck, NoMaxSizeCheck, NoHorizSyncCheck, NoVertRefreshCheck, NoVirtualSizeCheck, NoTotalSizeCheck, NoDualLinkDVICheck, NoDisplayPortBandwidthCheck, AllowNon3DVisionModes, AllowNonHDMI3DModes, AllowNonEdidModes, NoEdidHDMI2Check, AllowDpInterlaced"\n Option "HardDPMS" "False"' /etc/X11/xorg.conf
sed -i '/Section\s\+"Monitor"/a\ '"${MODELINE}" /etc/X11/xorg.conf
# Prevent interference between GPUs
echo -e "Section \"ServerFlags\"\n Option \"AutoAddGPU\" \"false\"\nEndSection" | tee -a /etc/X11/xorg.conf > /dev/null
# Configure primary GPU
sed -i '/Driver\s\+"nvidia"/a\ Option "AllowEmptyInitialConfiguration"\n Option "PrimaryGPU" "yes"' /usr/share/X11/xorg.conf.d/nvidia-drm-outputclass.conf
}
# Allow anybody for running x server
function configure_x_server {
# Configure x to be run by anyone
if grep -Fxq "allowed_users=console" /etc/X11/Xwrapper.config; then
echo "Configure Xwrapper.config"
sed -i "s/allowed_users=console/allowed_users=anybody/" /etc/X11/Xwrapper.config
echo 'needs_root_rights=yes' >> /etc/X11/Xwrapper.config
fi
# Remove previous Xorg config
rm -f /etc/X11/xorg.conf
# Ensure the X socket path exists
mkdir -p ${XORG_SOCKET_DIR:?}
# Clear out old lock files
display_file=${XORG_SOCKET_DIR}/X${DISPLAY#:}
if [ -S ${display_file} ]; then
echo "Removing ${display_file} before starting"
rm -f /tmp/.X${DISPLAY#:}-lock
rm ${display_file}
fi
# Ensure X-windows session path is owned by root
mkdir -p /tmp/.ICE-unix
chown root:root /tmp/.ICE-unix/
chmod 1777 /tmp/.ICE-unix/
# Check if this container is being run as a secondary instance
if [ "${MODE}" == "p" ] | [ "${MODE}" == "primary" ]; then
echo "Configure container as primary the X server"
# Enable supervisord script
sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/xorg.ini
elif [ "${MODE}" == "fb" ] | [ "${MODE}" == "framebuffer" ]; then
echo "Configure container to use a virtual framebuffer as the X server"
# Disable xorg supervisord script
sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/xorg.ini
# Enable xvfb supervisord script
sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/xvfb.ini
fi
# Enable KB/Mouse input capture with Xorg if configured
if [ ${ENABLE_EVDEV_INPUTS:-} = "true" ]; then
echo "Enabling evdev input class on pointers, keyboards, touchpads, touch screens, etc."
cp -fv /usr/share/X11/xorg.conf.d/10-evdev.conf /etc/X11/xorg.conf.d/10-evdev.conf
else
echo "Leaving evdev inputs disabled"
fi
# Configure dummy config if no monitor is connected (not applicable to NVIDIA)
if [[ "X${monitor_connected}" == "X" ]]; then
echo "No monitors connected. Installing dummy xorg.conf"
# Use a dummy display input
cp -fv /templates/xorg/xorg.dummy.conf /etc/X11/xorg.conf
fi
}
if ([ "${MODE}" != "s" ] && [ "${MODE}" != "secondary" ]); then
if [[ -z ${nvidia_gpu_hex_id} ]]; then
echo "**** Generate default xorg.conf ****";
configure_x_server
else
echo "**** Generate NVIDIA xorg.conf ****";
configure_x_server
configure_nvidia_x_server
fi
fi
echo "DONE"

View 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"

View File

@@ -0,0 +1,48 @@
echo "**** Configure Neko ****"
# REF: https://neko.m1k1o.net/#/getting-started/configuration
if ([ "${MODE}" != "s" ] && [ "${MODE}" != "secondary" ]); then
if [ ${WEB_UI_MODE} = "neko" ]; then
echo "Enable Neko server"
sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/neko.ini
# Make directories for neko
mkdir -p /var/log/neko
chmod 1777 /var/log/neko
chown ${USER} /var/log/neko
# Configure nat1to1 if it is not already set
if [[ -z ${NEKO_NAT1TO1} ]]; then
export NEKO_NAT1TO1=$(ip route get 1 | awk '{print $(NF-2);exit}')
echo "Setting NEKO_NAT1TO1=${NEKO_NAT1TO1}"
else
echo "User provided setting NEKO_NAT1TO1=${NEKO_NAT1TO1}"
fi
# Configure hardware acceleration if it is not already set
# if [[ -z ${NEKO_HWENC} ]]; then
# # Enable VAAPI if device available
# if [[ ! -z $(stat -c "%g" /dev/dri/render* | tail -n 1) ]]; then
# echo "Setting Neko to use VAAPI encoder"
# export NEKO_HWENC="VAAPI"
# # Check for vp8 vaapi encoder
# echo "Setting Neko to use 264 encoding"
# # export NEKO_VP8="false"
# # export NEKO_VP9="false"
# export NEKO_H264="true"
# fi
# fi
# Configure screen size if it is not already set
if [[ -z ${NEKO_SCREEN} ]]; then
export NEKO_SCREEN="${DISPLAY_SIZEW}x${DISPLAY_SIZEH}@${DISPLAY_REFRESH}"
fi
else
echo "Disable Neko server"
fi
else
echo "Neko server not available when container is run in 'secondary' mode"
fi
echo "DONE"

View File

@@ -0,0 +1,15 @@
echo "**** Configure Sunshine ****"
if ([ "${MODE}" != "s" ] && [ "${MODE}" != "secondary" ]); then
if [ "${ENABLE_SUNSHINE:-}" = "true" ]; then
echo "Enable Sunshine server"
sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/sunshine.ini
else
echo "Disable Sunshine server"
fi
else
echo "Sunshine server not available when container is run in 'secondary' mode"
fi
echo "DONE"

View File

@@ -0,0 +1,80 @@
echo "**** Configure VNC ****"
function get_next_unused_port() {
local __start_port=${1}
local __start_port=$((__start_port+1))
local __netstat_report=$(netstat -atulnp 2> /dev/null)
for __check_port in $(seq ${__start_port} 65000); do
[[ -z $(echo "${__netstat_report}" | grep ${__check_port}) ]] && break;
done
echo ${__check_port}
}
# Configure random ports for VNC service, pulseaudio socket, noVNC service and audio transport websocket
# Note: Ports 32035-32248 are unallocated port ranges. We should be able to find something in here that we can use
# REF: https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml?&page=130
DYNAMIC_PORT_VNC=$(get_next_unused_port 32035)
DYNAMIC_PORT_NOVNC_SERVICE=$(get_next_unused_port ${DYNAMIC_PORT_VNC})
DYNAMIC_PORT_AUDIO_WEBSOCKET=$(get_next_unused_port ${DYNAMIC_PORT_NOVNC_SERVICE})
DYNAMIC_PORT_AUDIO_STREAM=$(get_next_unused_port ${DYNAMIC_PORT_AUDIO_WEBSOCKET})
export PORT_VNC=${PORT_VNC:-$DYNAMIC_PORT_VNC}
echo "Configure VNC service port '${PORT_VNC}'"
export PORT_NOVNC_SERVICE=${PORT_NOVNC_SERVICE:-$DYNAMIC_PORT_NOVNC_SERVICE}
echo "Configure noVNC service port '${PORT_NOVNC_SERVICE}'"
export PORT_AUDIO_WEBSOCKET=${PORT_AUDIO_WEBSOCKET:-$DYNAMIC_PORT_AUDIO_WEBSOCKET}
echo "Configure audio websocket port '${PORT_AUDIO_WEBSOCKET}'"
export PORT_AUDIO_STREAM=${PORT_AUDIO_STREAM:-$DYNAMIC_PORT_AUDIO_STREAM}
echo "Configure pulseaudio encoded stream port '${PORT_AUDIO_STREAM}'"
if ([ "${MODE}" != "s" ] && [ "${MODE}" != "secondary" ]); then
if [ ${WEB_UI_MODE} = "vnc" ]; then
echo "Enable VNC server"
sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/vnc.ini
# Configure Nginx proxy for the websocket and VNC
cp -f /opt/noVNC/nginx.template.conf /opt/noVNC/nginx.conf
sed -i "s|<USER>|${USER}|" /opt/noVNC/nginx.conf
sed -i "s|<PORT_NOVNC_WEB>|${PORT_NOVNC_WEB}|" /opt/noVNC/nginx.conf
sed -i "s|<PORT_NOVNC_SERVICE>|${PORT_NOVNC_SERVICE}|" /opt/noVNC/nginx.conf
sed -i "s|<PORT_AUDIO_WEBSOCKET>|${PORT_AUDIO_WEBSOCKET}|" /opt/noVNC/nginx.conf
mkdir -p /var/log/vncproxy
chown -R ${USER} /var/log/vncproxy
if [[ "${ENABLE_VNC_AUDIO}" == "true" ]]; then
# Credits for this audio patch:
# - https://github.com/novnc/noVNC/issues/302
# - https://github.com/vexingcodes/dwarf-fortress-docker
# - https://github.com/calebj/noVNC
if [ -f /opt/noVNC/audio.patch ]; then
echo "Patching noVNC with audio websocket"
# Update port specification in patch file
sed -i "s|<PORT_AUDIO_WEBSOCKET>|${PORT_AUDIO_WEBSOCKET}|" /opt/noVNC/audio.patch
# Apply patch
pushd /opt/noVNC/ &> /dev/null
patch -p1 --input=/opt/noVNC/audio.patch --batch --quiet
popd &> /dev/null
rm /opt/noVNC/audio.patch
fi
# Enable supervisord script
sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/vnc-audio.ini
# Remove x11vnc from applications menu
if ! grep -q 'Hidden=true' /usr/share/applications/x11vnc.desktop; then
echo 'Hidden=true' >> /usr/share/applications/x11vnc.desktop
fi
else
echo "Disable audio stream"
echo "Disable audio websock"
# Disable supervisord script
sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/vnc-audio.ini
fi
else
echo "Disable VNC server"
fi
else
echo "VNC server not available when container is run in 'secondary' mode"
fi
echo "DONE"

View 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"

View File

@@ -0,0 +1,8 @@
{
"runtimes": {
"nvidia": {
"path": "/usr/bin/nvidia-container-runtime",
"runtimeArgs": []
}
}
}

View File

@@ -7,3 +7,8 @@
alias ls='ls --color=auto' alias ls='ls --color=auto'
PS1='[\u@\h \W]\$ ' PS1='[\u@\h \W]\$ '
# Export user's home directory bin directories
PATH=$PATH:$HOME/.local/bin:$HOME/bin
# Export /usr/games
PATH=$PATH:/usr/games

View File

@@ -4,11 +4,10 @@ Version=0.9.4
Type=Application Type=Application
Name=Steam Name=Steam
Comment=launch steam on login Comment=launch steam on login
Exec=/usr/games/steam %U 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 Icon=steam
OnlyShowIn=XFCE; OnlyShowIn=XFCE;
RunHook=0 RunHook=0
StartupNotify=false StartupNotify=false
Terminal=false Terminal=false
Hidden=false Hidden=false

View File

@@ -27,22 +27,22 @@
<property name="workspace0" type="empty"> <property name="workspace0" type="empty">
<property name="color-style" type="int" value="1"/> <property name="color-style" type="int" value="1"/>
<property name="image-style" type="int" value="5"/> <property name="image-style" type="int" value="5"/>
<property name="last-image" type="string" value="/usr/share/images/desktop-base/default"/> <property name="last-image" type="string" value="/usr/share/backgrounds/steam.jpg"/>
</property> </property>
<property name="workspace1" type="empty"> <property name="workspace1" type="empty">
<property name="color-style" type="int" value="1"/> <property name="color-style" type="int" value="1"/>
<property name="image-style" type="int" value="5"/> <property name="image-style" type="int" value="5"/>
<property name="last-image" type="string" value="/usr/share/images/desktop-base/default"/> <property name="last-image" type="string" value="/usr/share/backgrounds/steam.jpg"/>
</property> </property>
<property name="workspace2" type="empty"> <property name="workspace2" type="empty">
<property name="color-style" type="int" value="1"/> <property name="color-style" type="int" value="1"/>
<property name="image-style" type="int" value="5"/> <property name="image-style" type="int" value="5"/>
<property name="last-image" type="string" value="/usr/share/images/desktop-base/default"/> <property name="last-image" type="string" value="/usr/share/backgrounds/steam.jpg"/>
</property> </property>
<property name="workspace3" type="empty"> <property name="workspace3" type="empty">
<property name="color-style" type="int" value="1"/> <property name="color-style" type="int" value="1"/>
<property name="image-style" type="int" value="5"/> <property name="image-style" type="int" value="5"/>
<property name="last-image" type="string" value="/usr/share/images/desktop-base/default"/> <property name="last-image" type="string" value="/usr/share/backgrounds/steam.jpg"/>
</property> </property>
</property> </property>
</property> </property>

View File

@@ -1,12 +0,0 @@
# Hide application from menu
[Desktop Entry]
Name=X11VNC Server
Comment=Share this desktop by VNC
Exec=x11vnc -gui tray=setpass -rfbport PROMPT -bg -o %%HOME/.x11vnc.log.%%VNCDISPLAY
Icon=computer
Terminal=false
Type=Application
StartupNotify=false
#StartupWMClass=x11vnc_port_prompt
Categories=Network;RemoteAccess;
Hidden=true

View File

@@ -0,0 +1,16 @@
[program:dbus]
priority=10
autostart=true
autorestart=true
directory=/
user=%(ENV_USER)s
command=dbus-daemon --config-file=/usr/share/dbus-1/system.conf --nofork --nopidfile
environment=HOME="/home/%(ENV_USER)s",USER="%(ENV_USER)s"
stopsignal=INT
stdout_logfile=/var/log/supervisor/dbus.log
stdout_logfile_maxbytes=10MB
stdout_logfile_backups=7
stderr_logfile=/var/log/supervisor/dbus.err.log
stderr_logfile_maxbytes=10MB
stderr_logfile_backups=7

View File

@@ -0,0 +1,16 @@
[program:desktop]
priority=50
autostart=true
autorestart=true
user=%(ENV_USER)s
directory=/home/%(ENV_USER)s
command=/usr/bin/start-desktop.sh
environment=HOME="/home/%(ENV_USER)s",USER="%(ENV_USER)s",DISPLAY="%(ENV_DISPLAY)s",XDG_RUNTIME_DIR="%(ENV_XDG_RUNTIME_DIR)s"
stopsignal=INT
stdout_logfile=/home/%(ENV_USER)s/.cache/log/desktop.log
stdout_logfile_maxbytes=10MB
stdout_logfile_backups=7
stderr_logfile=/home/%(ENV_USER)s/.cache/log/desktop.err.log
stderr_logfile_maxbytes=10MB
stderr_logfile_backups=7

View 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

View File

@@ -0,0 +1,19 @@
[program:neko]
priority=30
autostart=false
autorestart=true
user=%(ENV_USER)s
# /usr/bin/neko serve --static "/var/www" --display ${DISPLAY} --bind :${PORT_NOVNC_WEB}
# /usr/bin/neko serve --static "/var/www" --display ${DISPLAY} --bind :${PORT_NOVNC_WEB} --nat1to1 $(ip route get 1 | awk '{print $(NF-2);exit}') --screen 1280x720@30 --hwenc VAAPI --h264
# /usr/bin/neko serve --static "/var/www" --display ${DISPLAY} --bind :${PORT_NOVNC_WEB} --nat1to1 $(ip route get 1 | awk '{print $(NF-2);exit}') --screen 1280x720@30 --vp8
command=/usr/bin/neko serve --static "/var/www" --display %(ENV_DISPLAY)s --bind :%(ENV_PORT_NOVNC_WEB)s
environment=HOME="/home/%(ENV_USER)s",USER="%(ENV_USER)s",DISPLAY="%(ENV_DISPLAY)s",XDG_RUNTIME_DIR="%(ENV_XDG_RUNTIME_DIR)s"
stopsignal=INT
stopwaitsecs=5
stdout_logfile=/home/%(ENV_USER)s/.cache/log/neko.log
stdout_logfile_maxbytes=10MB
stdout_logfile_backups=7
stderr_logfile=/home/%(ENV_USER)s/.cache/log/neko.err.log
stderr_logfile_maxbytes=10MB
stderr_logfile_backups=7

View File

@@ -0,0 +1,15 @@
[program:pulseaudio]
priority=30
autostart=true
autorestart=true
directory=/
user=%(ENV_USER)s
command=/usr/bin/start-pulseaudio.sh
environment=HOME="/home/%(ENV_USER)s",USER="%(ENV_USER)s"
stopsignal=INT
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/home/%(ENV_USER)s/.cache/log/pulseaudio.err.log
stderr_logfile_maxbytes=2MB
stderr_logfile_backups=7

View 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

View File

@@ -0,0 +1,22 @@
# Optionally launch directly to steam big picture (disabled by default)
[program:steam]
priority=50
autostart=false
autorestart=true
# Retry a restart a few times.
# This allows this container to start up before X is ready and restart the process until it becomes available.
# Each restart will have a small delay of a few seconds. So 50 attempts should be a few mins.
startretries=50
user=%(ENV_USER)s
directory=/home/%(ENV_USER)s
# command=/usr/games/steam -bigpicture
command=/usr/games/steam
environment=HOME="/home/%(ENV_USER)s",USER="%(ENV_USER)s",DISPLAY="%(ENV_DISPLAY)s"
stopsignal=INT
stdout_logfile=/home/%(ENV_USER)s/.cache/log/steam.log
stdout_logfile_maxbytes=10MB
stdout_logfile_backups=7
stderr_logfile=/home/%(ENV_USER)s/.cache/log/steam.err.log
stderr_logfile_maxbytes=10MB
stderr_logfile_backups=7

View File

@@ -0,0 +1,20 @@
[program:sunshine]
priority=50
autostart=false
autorestart=true
# Retry a restart a few times.
# The start-sunshine.sh script has a section that will wait for the
# X server to become available before executing sunshine. However, this will time out after 30 seconds.
startretries=10
user=%(ENV_USER)s
directory=/home/%(ENV_USER)s
command=/usr/bin/start-sunshine.sh
environment=HOME="/home/%(ENV_USER)s",USER="%(ENV_USER)s",DISPLAY="%(ENV_DISPLAY)s",XDG_RUNTIME_DIR="%(ENV_XDG_RUNTIME_DIR)s"
stopsignal=INT
stdout_logfile=/home/%(ENV_USER)s/.cache/log/sunshine.log
stdout_logfile_maxbytes=10MB
stdout_logfile_backups=7
stderr_logfile=/home/%(ENV_USER)s/.cache/log/sunshine.err.log
stderr_logfile_maxbytes=10MB
stderr_logfile_backups=7

View File

@@ -0,0 +1,15 @@
[program:udev]
priority=10
autostart=false
autorestart=true
user=root
directory=/
command=/usr/bin/start-udev.sh
stopsignal=INT
stdout_logfile=/var/log/supervisor/udev.log
stdout_logfile_maxbytes=10MB
stdout_logfile_backups=7
stderr_logfile=/var/log/supervisor/udev.err.log
stderr_logfile_maxbytes=10MB
stderr_logfile_backups=7

View File

@@ -0,0 +1,28 @@
[program:audiostream]
priority=30
autostart=false
autorestart=true
user=%(ENV_USER)s
command=tcpserver 127.0.0.1 %(ENV_PORT_AUDIO_STREAM)s gst-launch-1.0 -q pulsesrc server=%(ENV_PULSE_SOCKET_DIR)s/pulse-socket ! audio/x-raw, channels=2, rate=24000 ! cutter ! opusenc ! webmmux ! fdsink fd=1
stopsignal=INT
stdout_logfile=/home/%(ENV_USER)s/.cache/log/audiostream.log
stdout_logfile_maxbytes=10MB
stdout_logfile_backups=7
stderr_logfile=/home/%(ENV_USER)s/.cache/log/audiostream.err.log
stderr_logfile_maxbytes=10MB
stderr_logfile_backups=7
[program:audiowebsock]
priority=40
autostart=false
autorestart=true
user=%(ENV_USER)s
command=/usr/local/bin/websockify %(ENV_PORT_AUDIO_WEBSOCKET)s localhost:%(ENV_PORT_AUDIO_STREAM)s
stopsignal=INT
stdout_logfile=/home/%(ENV_USER)s/.cache/log/audiowebsock.log
stdout_logfile_maxbytes=10MB
stdout_logfile_backups=7
stderr_logfile=/home/%(ENV_USER)s/.cache/log/audiowebsock.err.log
stderr_logfile_maxbytes=10MB
stderr_logfile_backups=7

View File

@@ -0,0 +1,64 @@
[program:x11vnc]
priority=30
autostart=false
autorestart=true
user=%(ENV_USER)s
command=/usr/bin/start-x11vnc.sh
environment=HOME="/home/%(ENV_USER)s",USER="%(ENV_USER)s",DISPLAY="%(ENV_DISPLAY)s",PORT_VNC="%(ENV_PORT_VNC)s"
stopsignal=INT
stdout_logfile=/home/%(ENV_USER)s/.cache/log/x11vnc.log
stdout_logfile_maxbytes=10MB
stdout_logfile_backups=7
stderr_logfile=/home/%(ENV_USER)s/.cache/log/x11vnc.err.log
stderr_logfile_maxbytes=10MB
stderr_logfile_backups=7
[program:novnc]
priority=30
autostart=false
autorestart=true
user=%(ENV_USER)s
command=/opt/noVNC/utils/launch.sh --vnc localhost:%(ENV_PORT_VNC)s --listen %(ENV_PORT_NOVNC_SERVICE)s
environment=HOME="/home/%(ENV_USER)s",USER="%(ENV_USER)s"
stopsignal=INT
stdout_logfile=/home/%(ENV_USER)s/.cache/log/novnc.log
stdout_logfile_maxbytes=10MB
stdout_logfile_backups=7
stderr_logfile=/home/%(ENV_USER)s/.cache/log/novnc.err.log
stderr_logfile_maxbytes=10MB
stderr_logfile_backups=7
[program:vncproxy]
priority=30
autostart=false
autorestart=true
numprocs=1
startsecs=0
user=%(ENV_USER)s
command=/usr/sbin/nginx -c /opt/noVNC/nginx.conf
environment=HOME="/home/%(ENV_USER)s",USER="%(ENV_USER)s"
stopsignal=INT
stdout_logfile=/home/%(ENV_USER)s/.cache/log/vncproxy.log
stdout_logfile_maxbytes=10MB
stdout_logfile_backups=7
stderr_logfile=/home/%(ENV_USER)s/.cache/log/vncproxy.err.log
stderr_logfile_maxbytes=10MB
stderr_logfile_backups=7
# [program:kasmxproxy]
# priority=30
# autostart=false
# autorestart=true
# numprocs=1
# startsecs=0
# user=%(ENV_USER)s
# command=/usr/sbin/nginx -c /opt/noVNC/nginx.conf
# environment=HOME="/home/%(ENV_USER)s",USER="%(ENV_USER)s"
# stopsignal=INT
# stdout_logfile=/home/%(ENV_USER)s/.cache/log/vncproxy.log
# stdout_logfile_maxbytes=10MB
# stdout_logfile_backups=7
# stderr_logfile=/home/%(ENV_USER)s/.cache/log/vncproxy.err.log
# stderr_logfile_maxbytes=10MB
# stderr_logfile_backups=7

View File

@@ -0,0 +1,15 @@
[program:xorg]
priority=20
autostart=false
autorestart=true
user=root
command=/usr/bin/start-xorg.sh
environment=DISPLAY="%(ENV_DISPLAY)s",XDG_RUNTIME_DIR="/tmp/runtime-root"
stopsignal=INT
stdout_logfile=/home/%(ENV_USER)s/.cache/log/xorg.log
stdout_logfile_maxbytes=10MB
stdout_logfile_backups=7
stderr_logfile=/home/%(ENV_USER)s/.cache/log/xorg.err.log
stderr_logfile_maxbytes=10MB
stderr_logfile_backups=7

View File

@@ -0,0 +1,13 @@
[program:xvfb]
priority=20
autostart=false
autorestart=true
user=root
command=/usr/bin/Xvfb %(ENV_DISPLAY)s -screen 0 "%(ENV_DISPLAY_SIZEW)sx%(ENV_DISPLAY_SIZEH)sx24"
environment=DISPLAY="%(ENV_DISPLAY)s"
stopsignal=INT
stdout_logfile_maxbytes=10MB
stdout_logfile_backups=7
stderr_logfile_maxbytes=10MB
stderr_logfile_backups=7

View File

@@ -1,130 +0,0 @@
[supervisord]
user=root
nodaemon=true
[program:ssh]
autostart=true
priority=10
directory=/
command=/usr/sbin/sshd -D
user=root
autorestart=true
stopsignal=QUIT
[program:dbus]
autostart=true
priority=10
directory=/
command=dbus-daemon --config-file=/usr/share/dbus-1/system.conf --nofork --nopidfile
user=%(ENV_USER)s
environment=HOME="/home/%(ENV_USER)s",USER="%(ENV_USER)s"
autorestart=true
stopsignal=QUIT
[program:pulseaudio]
autostart=true
priority=10
directory=/
command=/usr/bin/pulseaudio -vvvv --disallow-module-loading --disallow-exit --exit-idle-time=-1
user=%(ENV_USER)s
environment=HOME="/home/%(ENV_USER)s",USER="%(ENV_USER)s"
autorestart=true
stopsignal=QUIT
stdout_logfile=/home/%(ENV_USER)s/.cache/log/pulseaudio.log
stderr_logfile=/home/%(ENV_USER)s/.cache/log/pulseaudio.err
[program:audiostream]
autostart=true
priority=10
command=tcpserver localhost 5901 gst-launch-1.0 -q pulsesrc server=/tmp/pulseaudio.socket ! audio/x-raw, channels=2, rate=24000 ! cutter ! opusenc ! webmmux ! fdsink fd=1
autorestart=true
stopsignal=QUIT
stdout_logfile=/home/%(ENV_USER)s/.cache/log/audiostream.log
stderr_logfile=/home/%(ENV_USER)s/.cache/log/audiostream.err
[program:audiowebsock]
autostart=true
priority=10
command=/usr/local/bin/websockify 32123 localhost:5901
autorestart=true
stopsignal=QUIT
stdout_logfile=/home/%(ENV_USER)s/.cache/log/audiowebsock.log
stderr_logfile=/home/%(ENV_USER)s/.cache/log/audiowebsock.err
[program:xorg]
autostart=true
priority=20
directory=/
command=/usr/bin/Xorg vt7 -novtswitch -sharevts -dpi "%(ENV_DISPLAY_DPI)s" +extension "MIT-SHM" %(ENV_DISPLAY)s
#command=/usr/bin/Xorg -novtswitch -sharevts -dpi "%(ENV_DISPLAY_DPI)s" +extension "MIT-SHM" "%(ENV_DISPLAY)s"
user=%(ENV_USER)s
environment=HOME="/home/%(ENV_USER)s",USER="%(ENV_USER)s",DISPLAY="%(ENV_DISPLAY)s",XDG_RUNTIME_DIR="/tmp/xdg",RUNLEVEL="3"
autorestart=true
stopsignal=QUIT
stdout_logfile=/home/%(ENV_USER)s/.cache/log/xorg.log
stderr_logfile=/home/%(ENV_USER)s/.cache/log/xorg.err
# Dont use xvfb as it does not work with nvidia X11 configuration
# [program:xvfb]
# autostart=false
# priority=20
# directory=/
# command=/usr/bin/Xvfb %(ENV_DISPLAY)s -screen 0 1920x1080x24
# user=%(ENV_USER)s
# environment=HOME="/home/%(ENV_USER)s",USER="%(ENV_USER)s"
# autorestart=true
# stopsignal=QUIT
# stdout_logfile=/home/%(ENV_USER)s/.cache/log/xvfb.log
# stderr_logfile=/home/%(ENV_USER)s/.cache/log/xvfb.err
[program:x11vnc]
autostart=true
priority=30
directory=/
#command=/usr/bin/x11vnc -display %(ENV_DISPLAY)s -xkb
command=/usr/bin/x11vnc -display %(ENV_DISPLAY)s -rfbport 5900 -shared -forever
user=%(ENV_USER)s
autorestart=true
stopsignal=QUIT
stdout_logfile=/home/%(ENV_USER)s/.cache/log/x11vnc.log
stderr_logfile=/home/%(ENV_USER)s/.cache/log/x11vnc.err
[program:de]
autostart=true
priority=50
directory=/home/%(ENV_USER)s
command=/usr/bin/startxfce4
#command=/usr/bin/mate-session
#command=/usr/bin/startlxqt
#command=/usr/bin/dbus-launch startxfce4
#command=/usr/bin/dbus-launch xfce4-session
#command=/usr/bin/dbus-launch startplasma-x11
user=%(ENV_USER)s
autorestart=true
stopsignal=QUIT
environment=HOME="/home/%(ENV_USER)s",USER="%(ENV_USER)s",DISPLAY="%(ENV_DISPLAY)s"
stdout_logfile=/home/%(ENV_USER)s/.cache/log/de.log
stderr_logfile=/home/%(ENV_USER)s/.cache/log/de.err
## Experimental launch directly to steam big picture... (this is cool, but not ideal for headless)
# [program:steam]
# autostart=true
# priority=50
# directory=/home/%(ENV_USER)s
# command=/usr/bin/steam -bigpicture
# user=%(ENV_USER)s
# autorestart=true
# stopsignal=QUIT
# environment=HOME="/home/%(ENV_USER)s",USER="%(ENV_USER)s",DISPLAY="%(ENV_DISPLAY)s"
# stdout_logfile=/home/%(ENV_USER)s/.cache/log/steam.log
# stderr_logfile=/home/%(ENV_USER)s/.cache/log/steam.err
[program:novnc]
autostart=true
priority=100
command=/opt/noVNC/utils/launch.sh --vnc localhost:5900 --listen 8083
#command=/usr/share/novnc/utils/launch.sh --vnc localhost:5900 --listen 8083
#command=/usr/local/bin/websockify -D --web=/usr/share/novnc/ --cert=/etc/ssl/novnc.pem 8083 localhost:5900
user=%(ENV_USER)s
environment=HOME="/home/%(ENV_USER)s",USER="%(ENV_USER)s"
autorestart=true

View File

@@ -0,0 +1,152 @@
; Sample supervisor config file.
;
; For more information on the config file, please see:
; http://supervisord.org/configuration.html
;
; Notes:
; - Shell expansion ("~" or "$HOME") is not supported. Environment
; variables can be expanded using this syntax: "%(ENV_HOME)s".
; - Quotes around values are not supported, except in the case of
; the environment= options as shown below.
; - Comments must have a leading space: "a=b ;comment" not "a=b;comment".
; - Command will be truncated if it looks like a config file comment, e.g.
; "command=bash -c 'foo ; bar'" will truncate to "command=bash -c 'foo ".
[unix_http_server]
file=/run/supervisor.sock ; the path to the socket file
;chmod=0700 ; socket file mode (default 0700)
;chown=nobody:nogroup ; socket file uid:gid owner
;username=user ; default is no username (open server)
;password=123 ; default is no password (open server)
;[inet_http_server] ; inet (TCP) server disabled by default
;port=127.0.0.1:9001 ; ip_address:port specifier, *:port for all iface
;username=user ; default is no username (open server)
;password=123 ; default is no password (open server)
[supervisord]
logfile=/var/log/supervisord.log ; main log file; default $CWD/supervisord.log
logfile_maxbytes=50MB ; max main logfile bytes b4 rotation; default 50MB
logfile_backups=10 ; # of main logfile backups; 0 means none, default 10
loglevel=info ; log level; default info; others: debug,warn,trace
pidfile=/run/supervisord.pid ; supervisord pidfile; default supervisord.pid
nodaemon=false ; start in foreground if true; default false
minfds=1024 ; min. avail startup file descriptors; default 1024
minprocs=200 ; min. avail process descriptors;default 200
;umask=022 ; process file creation umask; default 022
;user=supervisord ; setuid to this UNIX account at startup; recommended if root
;identifier=supervisor ; supervisord identifier, default is 'supervisor'
;directory=/tmp ; default is not to cd during start
;nocleanup=true ; don't clean up tempfiles at start; default false
childlogdir=/var/log/supervisor ; 'AUTO' child log dir, default $TEMP
;environment=KEY="value" ; key value pairs to add to environment
;strip_ansi=false ; strip ansi escape codes in logs; def. false
; The rpcinterface:supervisor section must remain in the config file for
; RPC (supervisorctl/web interface) to work. Additional interfaces may be
; added by defining them in separate [rpcinterface:x] sections.
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
; The supervisorctl section configures how supervisorctl will connect to
; supervisord. configure it match the settings in either the unix_http_server
; or inet_http_server section.
[supervisorctl]
serverurl=unix:///run/supervisor.sock ; use a unix:// URL for a unix socket
;serverurl=http://127.0.0.1:9001 ; use an http:// url to specify an inet socket
;username=chris ; should be same as in [*_http_server] if set
;password=123 ; should be same as in [*_http_server] if set
;prompt=mysupervisor ; cmd line prompt (default "supervisor")
;history_file=~/.sc_history ; use readline history if available
; The sample program section below shows all possible program subsection values.
; Create one or more 'real' program: sections to be able to control them under
; supervisor.
;[program:theprogramname]
;command=/bin/cat ; the program (relative uses PATH, can take args)
;process_name=%(program_name)s ; process_name expr (default %(program_name)s)
;numprocs=1 ; number of processes copies to start (def 1)
;directory=/tmp ; directory to cwd to before exec (def no cwd)
;umask=022 ; umask for process (default None)
;priority=999 ; the relative start priority (default 999)
;autostart=true ; start at supervisord start (default: true)
;startsecs=1 ; # of secs prog must stay up to be running (def. 1)
;startretries=3 ; max # of serial start failures when starting (default 3)
;autorestart=unexpected ; when to restart if exited after running (def: unexpected)
;exitcodes=0 ; 'expected' exit codes used with autorestart (default 0)
;stopsignal=QUIT ; signal used to kill process (default TERM)
;stopwaitsecs=10 ; max num secs to wait b4 SIGKILL (default 10)
;stopasgroup=false ; send stop signal to the UNIX process group (default false)
;killasgroup=false ; SIGKILL the UNIX process group (def false)
;user=chrism ; setuid to this UNIX account to run the program
;redirect_stderr=true ; redirect proc stderr to stdout (default false)
;stdout_logfile=/a/path ; stdout log path, NONE for none; default AUTO
;stdout_logfile_maxbytes=1MB ; max # logfile bytes b4 rotation (default 50MB)
;stdout_logfile_backups=10 ; # of stdout logfile backups (0 means none, default 10)
;stdout_capture_maxbytes=1MB ; number of bytes in 'capturemode' (default 0)
;stdout_events_enabled=false ; emit events on stdout writes (default false)
;stdout_syslog=false ; send stdout to syslog with process name (default false)
;stderr_logfile=/a/path ; stderr log path, NONE for none; default AUTO
;stderr_logfile_maxbytes=1MB ; max # logfile bytes b4 rotation (default 50MB)
;stderr_logfile_backups=10 ; # of stderr logfile backups (0 means none, default 10)
;stderr_capture_maxbytes=1MB ; number of bytes in 'capturemode' (default 0)
;stderr_events_enabled=false ; emit events on stderr writes (default false)
;stderr_syslog=false ; send stderr to syslog with process name (default false)
;environment=A="1",B="2" ; process environment additions (def no adds)
;serverurl=AUTO ; override serverurl computation (childutils)
; The sample eventlistener section below shows all possible eventlistener
; subsection values. Create one or more 'real' eventlistener: sections to be
; able to handle event notifications sent by supervisord.
;[eventlistener:theeventlistenername]
;command=/bin/eventlistener ; the program (relative uses PATH, can take args)
;process_name=%(program_name)s ; process_name expr (default %(program_name)s)
;numprocs=1 ; number of processes copies to start (def 1)
;events=EVENT ; event notif. types to subscribe to (req'd)
;buffer_size=10 ; event buffer queue size (default 10)
;directory=/tmp ; directory to cwd to before exec (def no cwd)
;umask=022 ; umask for process (default None)
;priority=-1 ; the relative start priority (default -1)
;autostart=true ; start at supervisord start (default: true)
;startsecs=1 ; # of secs prog must stay up to be running (def. 1)
;startretries=3 ; max # of serial start failures when starting (default 3)
;autorestart=unexpected ; autorestart if exited after running (def: unexpected)
;exitcodes=0 ; 'expected' exit codes used with autorestart (default 0)
;stopsignal=QUIT ; signal used to kill process (default TERM)
;stopwaitsecs=10 ; max num secs to wait b4 SIGKILL (default 10)
;stopasgroup=false ; send stop signal to the UNIX process group (default false)
;killasgroup=false ; SIGKILL the UNIX process group (def false)
;user=chrism ; setuid to this UNIX account to run the program
;redirect_stderr=false ; redirect_stderr=true is not allowed for eventlisteners
;stdout_logfile=/a/path ; stdout log path, NONE for none; default AUTO
;stdout_logfile_maxbytes=1MB ; max # logfile bytes b4 rotation (default 50MB)
;stdout_logfile_backups=10 ; # of stdout logfile backups (0 means none, default 10)
;stdout_events_enabled=false ; emit events on stdout writes (default false)
;stdout_syslog=false ; send stdout to syslog with process name (default false)
;stderr_logfile=/a/path ; stderr log path, NONE for none; default AUTO
;stderr_logfile_maxbytes=1MB ; max # logfile bytes b4 rotation (default 50MB)
;stderr_logfile_backups=10 ; # of stderr logfile backups (0 means none, default 10)
;stderr_events_enabled=false ; emit events on stderr writes (default false)
;stderr_syslog=false ; send stderr to syslog with process name (default false)
;environment=A="1",B="2" ; process environment additions
;serverurl=AUTO ; override serverurl computation (childutils)
; The sample group section below shows all possible group values. Create one
; or more 'real' group: sections to create "heterogeneous" process groups.
;[group:thegroupname]
;programs=progname1,progname2 ; each refers to 'x' in [program:x] definitions
;priority=999 ; the relative start priority (default 999)
; The [include] section can just contain the "files" setting. This
; setting can list multiple files (separated by whitespace or
; newlines). It can also contain wildcards. The filenames are
; interpreted as relative to this file. Included files *cannot*
; include files themselves.
[include]
files = /etc/supervisor.d/*.ini

View File

@@ -102,14 +102,14 @@ index cb6a9fd..4d599e1 100644
UI.rfb.focus(); UI.rfb.focus();
+ +
+ let audio_url; + let audio_url;
+ let host = window.location.hostname; + // let host = window.location.hostname;
+ let port = 32123; + // let port = '<PORT_AUDIO_WEBSOCKET>';
+ if (window.location.protocol === "https:") { + if (window.location.protocol === "https:") {
+ audio_url = 'wss'; + audio_url = 'wss';
+ } else { + } else {
+ audio_url = 'ws'; + audio_url = 'ws';
+ } + }
+ audio_url += '://' + host + ':' + port; + audio_url += '://' + window.location.host + '/audiowebsock';
+ +
+ UI.webaudio = new WebAudio(audio_url); + UI.webaudio = new WebAudio(audio_url);
+ UI.toggleAudio(); + UI.toggleAudio();
@@ -326,14 +326,14 @@ index 8e2f5cb..d3cf6ab 100644
// successfully connected to a server // successfully connected to a server
function connectedToServer(e) { function connectedToServer(e) {
+ let audio_url; + let audio_url;
+ let host = window.location.hostname; + // let host = window.location.hostname;
+ let port = 32123; + // let port = '<PORT_AUDIO_WEBSOCKET>';
+ if (window.location.protocol === "https:") { + if (window.location.protocol === "https:") {
+ audio_url = 'wss'; + audio_url = 'wss';
+ } else { + } else {
+ audio_url = 'ws'; + audio_url = 'ws';
+ } + }
+ audio_url += '://' + host + ':' + port; + audio_url += '://' + window.location.host + '/audiowebsock';
+ +
+ wa = new WebAudio(audio_url); + wa = new WebAudio(audio_url);
+ document.getElementById('toggleAudioButton').style.display = "block"; + document.getElementById('toggleAudioButton').style.display = "block";
@@ -360,7 +360,7 @@ index 8e2f5cb..d3cf6ab 100644
+ if (wa.connected) { + if (wa.connected) {
+ console.log('Stopping audio...') + console.log('Stopping audio...')
+ wa.stop(); + wa.stop();
+ document.getElementById('toggleAudioButton').innerText = "Enable Audio (requires access to port 32123)"; + document.getElementById('toggleAudioButton').innerText = "Enable Audio";
+ } else { + } else {
+ console.log('Starting audio websocket on: ' + audio_url) + console.log('Starting audio websocket on: ' + audio_url)
+ wa.start(); + wa.start();
@@ -410,7 +410,7 @@ index 8e2f5cb..d3cf6ab 100644
<body> <body>
<div id="top_bar"> <div id="top_bar">
+ <div id="toggleAudioButton">Enable Audio (requires access to port 32123)</div> + <div id="toggleAudioButton">Enable Audio</div>
<div id="status">Loading</div> <div id="status">Loading</div>
<div id="sendCtrlAltDelButton">Send CtrlAltDel</div> <div id="sendCtrlAltDelButton">Send CtrlAltDel</div>
</div> </div>

View 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;
}
}
}

View File

@@ -0,0 +1,16 @@
#!/usr/bin/env bash
###
# File: drop_caches.sh
# Project: docker-steam-headless
# File Created: Wednesday, 12th January 2022 5:08:46 pm
# Author: Josh.5 (jsunnex@gmail.com)
# -----
# Last Modified: Wednesday, 12th January 2022 5:44:17 pm
# Modified By: Josh.5 (jsunnex@gmail.com)
###
# Clear out the memory page cache
echo 1 > /proc/sys/vm/drop_caches
# Flush any FS buffers
sync

View File

@@ -0,0 +1,31 @@
#!/usr/bin/env bash
echo "**** Installing/upgrading Firefox via flatpak ****"
# Install Firefox
flatpak --user remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
flatpak --user install --assumeyes --noninteractive --or-update flathub org.mozilla.firefox
# Configure Firefox as the default browser
echo "Configure Firefox..."
custom_webbrowser="$(cat <<EOF
"libraryfolders"
[Desktop Entry]
NoDisplay=true
Version=1.0
Encoding=UTF-8
Type=X-XFCE-Helper
X-XFCE-Category=WebBrowser
X-XFCE-CommandsWithParameter=${USER_HOME:?}/.local/share/flatpak/exports/bin/org.mozilla.firefox "%s"
Icon=org.mozilla.firefox
Name=org.mozilla.firefox
X-XFCE-Commands=${USER_HOME:?}/.local/share/flatpak/exports/bin/org.mozilla.firefox
EOF
)"
if [[ ! -f ${USER_HOME:?}/.local/share/xfce4/helpers/custom-WebBrowser.desktop ]]; then
mkdir -p ${USER_HOME:?}/.local/share/xfce4/helpers
echo "${custom_webbrowser}" > ${USER_HOME:?}/.local/share/xfce4/helpers/custom-WebBrowser.desktop
gio mime x-scheme-handler/http org.mozilla.firefox.desktop
fi
echo "DONE"

View File

@@ -0,0 +1,14 @@
#!/usr/bin/env bash
echo "**** Installing/upgrading ProtonUp-Qt via flatpak ****"
# Install ProtonUp-Qt
flatpak --user remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
flatpak --user install --assumeyes --noninteractive --or-update net.davidotek.pupgui2
# Configure Firefox as the default browser
echo "Configure ProtonUp-Qt..."
sed -i 's/^Categories=.*$/Categories=Utility;/' \
${USER_HOME}/.local/share/flatpak/exports/share/applications/net.davidotek.pupgui2.desktop
echo "DONE"

View 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"

View File

@@ -1,31 +0,0 @@
PUID=${PUID:-99}
PGID=${PGID:-100}
UMASK=${UMASK:-000}
USER_PASSWORD=${USER_PASSWORD:-password}
echo "**** Configure default user ****"
echo "Setting run user uid=${PGID}(${USER}) gid=${PUID}(${USER})"
groupmod -o -g "${PGID}" ${USER}
usermod -o -u "${PUID}" ${USER}
echo "Setting umask to ${UMASK}";
umask ${UMASK}
# 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 /etc/home_directory_template/ ${USER_HOME}/
# Set the root and user password
echo "Setting root password"
echo "root:${USER_PASSWORD}" | chpasswd
echo "Setting user password"
echo "${USER}:${USER_PASSWORD}" | chpasswd
echo "DONE"

View File

@@ -1,10 +0,0 @@
# 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 "DONE"

View File

@@ -1,32 +0,0 @@
# Configure system paths
echo "**** Configure system paths ****";
sed -i "/ <user>/c\ <user>${USER}</user>" /usr/share/dbus-1/system.conf
if [ ! -d /tmp/xdg ]; then
mkdir -p /tmp/xdg
fi
echo "Configure dbus";
# 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
echo "Configure X Windows context"
chown -R ${PUID}:${PGID} /tmp/xdg
chmod -R 0700 /tmp/xdg
echo "Configure X Windows session"
rm -rfv /tmp/.ICE-unix*
mkdir -p /tmp/.ICE-unix
chown root:root /tmp/.ICE-unix/
chmod 1777 /tmp/.ICE-unix/
echo "Remove old lockfiles"
find /var/run/dbus -name "pid" -exec rm -f {} \;
find /tmp -name ".X99*" -exec rm -f {} \;
echo "DONE"

View File

@@ -1,20 +0,0 @@
echo "**** Configure pulseaudio socket ****"
sed -i 's|^; default-server.*$|default-server = unix:/tmp/pulseaudio.socket|' /etc/pulse/client.conf
sed -i 's|^load-module module-native-protocol-unix.*$|load-module module-native-protocol-unix socket=/tmp/pulseaudio.socket auth-anonymous=1|' \
/etc/pulse/default.pa
chown -R ${USER} /etc/pulse
# 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 ****"
pushd /opt/noVNC/ &> /dev/null
patch -p1 --input=/opt/noVNC/audio.patch --batch --quiet
popd &> /dev/null
rm /opt/noVNC/audio.patch
fi
echo "DONE"

View File

@@ -1,64 +0,0 @@
# Fech NVIDIA GPU device (if one exists)
if [ "$NVIDIA_VISIBLE_DEVICES" == "all" ]; then
export gpu_select=$(nvidia-smi --format=csv --query-gpu=uuid 2> /dev/null | sed -n 2p)
elif [ -z "$NVIDIA_VISIBLE_DEVICES" ]; then
export gpu_select=$(nvidia-smi --format=csv --query-gpu=uuid 2> /dev/null | sed -n 2p)
else
export gpu_select=$(nvidia-smi --format=csv --id=$(echo "$NVIDIA_VISIBLE_DEVICES" | cut -d ',' -f1) --query-gpu=uuid | sed -n 2p)
if [ -z "$gpu_select" ]; then
export gpu_select=$(nvidia-smi --format=csv --query-gpu=uuid 2> /dev/null | sed -n 2p)
fi
fi
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}" | sed -n 2p 2> /dev/null)
export nvidia_host_driver_version="$(nvidia-smi 2> /dev/null | grep NVIDIA-SMI | cut -d ' ' -f3)"
function download_driver {
mkdir -p ${USER_HOME}/.cache/nvidia
if [[ ! -f "${USER_HOME}/.cache/nvidia/NVIDIA_${nvidia_host_driver_version}.run" ]]; then
echo "Downloading driver"
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
mv /tmp/NVIDIA.run ${USER_HOME}/.cache/nvidia/NVIDIA_${nvidia_host_driver_version}.run
fi
}
function install_driver {
# Check here if the currently installed version matches using nvidia-settings
nvidia_settings_version=$(nvidia-settings --version 2> /dev/null | grep version | cut -d ' ' -f 4)
[[ "${nvidia_settings_version}x" == "${nvidia_host_driver_version}x" ]] && return 0
# Download the driver (if it does not yet exist locally)
download_driver
echo "Installing driver"
chmod +x ${USER_HOME}/.cache/nvidia/NVIDIA_${nvidia_host_driver_version}.run
${USER_HOME}/.cache/nvidia/NVIDIA_${nvidia_host_driver_version}.run \
--silent \
--accept-license \
--no-kernel-module \
--install-compat32-libs \
--no-nouveau-check \
--no-nvidia-modprobe \
--no-rpms \
--no-backup \
--no-check-for-alternate-installs \
--no-libglx-indirect \
--no-install-libglvnd \
> ${USER_HOME}/.cache/nvidia/last_install.log 2>&1
}
if [[ -z ${nvidia_pci_address} ]]; then
echo "**** No NVIDIA device found ****";
else
echo "**** Found NVIDIA device '${nvidia_gpu_name}' ****";
install_driver
fi
echo "DONE"

View File

@@ -1,57 +0,0 @@
# Fech NVIDIA GPU device (if one exists)
if [ "$NVIDIA_VISIBLE_DEVICES" == "all" ]; then
export gpu_select=$(nvidia-smi --format=csv --query-gpu=uuid 2> /dev/null | sed -n 2p)
elif [ -z "$NVIDIA_VISIBLE_DEVICES" ]; then
export gpu_select=$(nvidia-smi --format=csv --query-gpu=uuid 2> /dev/null | sed -n 2p)
else
export gpu_select=$(nvidia-smi --format=csv --id=$(echo "$NVIDIA_VISIBLE_DEVICES" | cut -d ',' -f1) --query-gpu=uuid | sed -n 2p)
if [ -z "$gpu_select" ]; then
export gpu_select=$(nvidia-smi --format=csv --query-gpu=uuid 2> /dev/null | sed -n 2p)
fi
fi
export nvidia_gpu_hex_id=$(nvidia-smi --format=csv --query-gpu=pci.bus_id --id="${gpu_select}" 2> /dev/null | sed -n 2p)
# Fech current configuration (if modified in UI)
if [ -f "${USER_HOME}/.config/xfce4/xfconf/xfce-perchannel-xml/displays.xml" ]; then
new_display_sizew=$(cat ${USER_HOME}/.config/xfce4/xfconf/xfce-perchannel-xml/displays.xml | grep Resolution | head -n1 | grep -oP '(?<=value=").*?(?=")' | cut -d'x' -f1)
new_display_sizeh=$(cat ${USER_HOME}/.config/xfce4/xfconf/xfce-perchannel-xml/displays.xml | grep Resolution | head -n1 | grep -oP '(?<=value=").*?(?=")' | cut -d'x' -f2)
if [ "${new_display_sizew}x" != "x" ] && [ "${new_display_sizeh}x" != "x" ]; then
export DISPLAY_SIZEW="${new_display_sizew}"
export DISPLAY_SIZEH="${new_display_sizeh}"
fi
fi
# Configure a NVIDIA X11 config
function configure_nvidia_x_server {
# Configure x to be run by anyone
if grep -Fxq "allowed_users=console" /etc/X11/Xwrapper.config; then
echo "Configure Xwrapper.config"
sed -i "s/allowed_users=console/allowed_users=anybody/" /etc/X11/Xwrapper.config
fi
# Configure xorg for NVIDIA
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)
IFS=":." ARR_ID=(${nvidia_gpu_hex_id})
unset IFS
bus_id=PCI:$((16#${ARR_ID[1]})):$((16#${ARR_ID[2]})):$((16#${ARR_ID[3]}))
echo "Configuring X11 with PCI bus ID: '${bus_id}'"
export MODELINE=$(cvt -r "${DISPLAY_SIZEW}" "${DISPLAY_SIZEH}" "${DISPLAY_REFRESH}" | sed -n 2p)
echo "Writing X11 config with ${MODELINE}"
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}" --only-one-x-screen --connected-monitor="${DISPLAY_VIDEO_PORT}"
sed -i '/Driver\s\+"nvidia"/a\ Option "ModeValidation" "NoMaxPClkCheck, NoEdidMaxPClkCheck, NoMaxSizeCheck, NoHorizSyncCheck, NoVertRefreshCheck, NoVirtualSizeCheck, NoExtendedGpuCapabilitiesCheck, NoTotalSizeCheck, NoDualLinkDVICheck, NoDisplayPortBandwidthCheck, AllowNon3DVisionModes, AllowNonHDMI3DModes, AllowNonEdidModes, NoEdidHDMI2Check, AllowDpInterlaced"' /etc/X11/xorg.conf
sed -i '/Section\s\+"Monitor"/a\ '"${MODELINE}" /etc/X11/xorg.conf
}
if [[ -z ${nvidia_gpu_hex_id} ]]; then
echo "**** Generate default xorg.conf ****";
# TODO: Configure xorg.conf with no NVIDIA GPU
else
echo "**** Generate NVIDIA xorg.conf ****";
configure_nvidia_x_server
fi
echo "DONE"

View File

@@ -0,0 +1,15 @@
{
"env": {
"PATH": "$(PATH):$(HOME)\/.local\/bin"
},
"apps": [
{
"name": "Steam BigPicture",
"output": "steam.txt",
"cmd": "",
"detached": [
"\/usr\/games\/steam steam:\/\/open\/bigpicture"
]
}
]
}

View File

@@ -0,0 +1,286 @@
# If no external IP address is given, Sunshine will attempt to automatically detect external ip-address
# external_ip = 123.456.789.12
# Set the familly of ports used by Sunshine
# port = 47989
# The private key must be 2048 bits
# pkey = /dir/pkey.pem
# The certificate must be signed with a 2048 bit key
# cert = /dir/cert.pem
# The name displayed by Moonlight
# If not specified, the PC's hostname is used
# sunshine_name = Sunshine
# The minimum log level printed to standard out
#
# none -> no logs are printed to standard out
#
# verbose = [0]
# debug = [1]
# info = [2]
# warning = [3]
# error = [4]
# fatal = [5]
# none = [6]
#
min_log_level = info
# The origin of the remote endpoint address that is not denied for HTTP method /pin
# Could be any of the following values:
# pc|lan|wan
# pc: Only localhost may access /pin
# lan: Only those in LAN may access /pin
# wan: Anyone may access /pin
#
# origin_pin_allowed = pc
# The origin of the remote endpoint address that is not denied for HTTPS Web UI
# Could be any of the following values:
# pc|lan|wan
# pc: Only localhost may access the Web Manager
# lan: Only those in LAN may access the Web Manager
# wan: Anyone may access the Web Manager
#
# origin_web_ui_allowed = lan
# If UPnP is enabled, Sunshine will attempt to open ports for streaming over the internet
# To enable it, uncomment the following line:
# upnp = on
# The file where current state of Sunshine is stored
# file_state = sunshine_state.json
# The file where user credentials for the UI are stored
# By default, credentials are stored in `file_state`
# credentials_file = sunshine_state.json
# The display modes advertised by Sunshine
#
# Some versions of Moonlight, such as Moonlight-nx (Switch),
# rely on this list to ensure that the requested resolutions and fps
# are supported.
#
# fps = [10, 30, 60, 90, 120]
# resolutions = [
# 352x240,
# 480x360,
# 858x480,
# 1280x720,
# 1920x1080,
# 2560x1080,
# 3440x1440,
# 1920x1200,
# 3860x2160,
# 3840x1600,
# ]
# Sometimes it may be usefull to map keybindings.
# Wayland won't allow clients to capture the Win Key for example
#
# See https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
#
# Note:
# keybindings needs to have a multiple of two elements
# keybindings = [
# 0x10, 0xA0,
# 0x11, 0xA2,
# 0x12, 0xA4,
# 0x4A, 0x4B
# ]
# How long to wait in milliseconds for data from moonlight before shutting down the stream
# ping_timeout = 10000
# The file where configuration for the different applications that Sunshine can run during a stream
file_apps = /home/default/sunshine/apps.json
# 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
# The default value of 20 is what GeForce Experience uses
#
# The value must be greater than 0 and lower than or equal to 255
# fec_percentage = 20
# When multicasting, it could be usefull to have different configurations for each connected Client.
# For example:
# Clients connected through WAN and LAN have different bitrate contstraints.
# Decoders may require different settings for color
#
# Unlike simply broadcasting to multiple Client, this will generate distinct video streams.
# Note, CPU usage increases for each distinct video stream generated
# channels = 1
# The back/select button on the controller
# On the Shield, the home and powerbutton are not passed to Moonlight
# If, after the timeout, the back button is still pressed down, Home/Guide button press is emulated.
# If back_button_timeout < 0, then the Home/Guide button will not be emulated
# back_button_timeout = 2000
# !! Windows only !!
# Gamepads supported by Sunshine
# Possible values:
# x360 -- xbox 360 controller
# ds4 -- dualshock controller (PS4)
# gamepad = x360
# Control how fast keys will repeat themselves
# The initial delay in milliseconds before repeating keys
# key_repeat_delay = 500
#
# How often keys repeat every second
# This configurable option supports decimals
# key_repeat_frequency = 24.9
# The name of the audio sink used for Audio Loopback
# If you do not specify this variable, pulseaudio will select the default monitor device.
#
# You can find the name of the audio sink using the following command:
# !! Linux only !!
# pacmd list-sinks | grep "name:" if running vanilla pulseaudio
# pPipewire: Use `pactl info | grep Source`. In some causes you'd need to use the `sink` device. Try `pactl info | grep Sink`, if _Source_ doesn't work
# audio_sink = alsa_output.pci-0000_09_00.3.analog-stereo
#
# !! Windows only !!
# tools\audio-info.exe
# audio_sink = {0.0.0.00000000}.{FD47D9CC-4218-4135-9CE2-0C195C87405B}
#
# The virtual sink, is the audio device that's virtual (Like Steam Streaming Speakers), it allows Sunshine
# to stream audio, while muting the speakers.
# virtual_sink = {0.0.0.00000000}.{8edba70c-1125-467c-b89c-15da389bc1d4}
# !! Windows only !!
# You can select the video card you want to stream:
# The appropriate values can be found using the following command:
# tools\dxgi-info.exe
# adapter_name = Radeon RX 580 Series
# output_name = \\.\DISPLAY1
# !! Linux only !!
# Set the display number to stream.
# You can find them by the following command:
# xrandr --listmonitors
# Example output: "0: +HDMI-1 1920/518x1200/324+0+0 HDMI-1"
# ^ <-- You need this.
# output_name = 0
###############################################
# FFmpeg software encoding parameters
# Honestly, I have no idea what the optimal values would be.
# Play around with this :)
# Quantitization Parameter
# Some devices don't support Constant Bit Rate. For those devices, QP is used instead
# Higher value means more compression, but less quality
# qp = 28
# Minimum number of threads used by ffmpeg to encode the video.
# Increasing the value slightly reduces encoding efficiency, but the tradeoff is usually
# worth it to gain the use of more CPU cores for encoding. The ideal value is the lowest
# value that can reliably encode at your desired streaming settings on your hardware.
# min_threads = 1
# Allows the client to request HEVC Main or HEVC Main10 video streams.
# HEVC is more CPU-intensive to encode, so enabling this may reduce performance when using software encoding.
# If set to 0 (default), Sunshine will specify support for HEVC based on encoder
# If set to 1, Sunshine will not advertise support for HEVC
# If set to 2, Sunshine will advertise support for HEVC Main profile
# If set to 3, Sunshine will advertise support for HEVC Main and Main10 (HDR) profiles
# hevc_mode = 2
# Force a specific encoder, otherwise Sunshine will use the first encoder that is available
# supported encoders:
# nvenc
# amdvce # NOTE: alpha stage. The cursor is not yet displayed
# software
#
# encoder = software
##################################### Software #####################################
# See x264 --fullhelp for the different presets
# sw_preset = superfast
# sw_tune = zerolatency
#
##################################### NVENC #####################################
###### presets ###########
# default
# hp -- high performance
# hq -- high quality
# slow -- hq 2 passes
# medium -- hq 1 pass
# fast -- hp 1 pass
# bd
# ll -- low latency
# llhq
# llhp
# lossless
# losslesshp
##########################
# nv_preset = llhq
#
####### rate control #####
# auto -- let ffmpeg decide rate control
# constqp -- constant QP mode
# vbr -- variable bitrate
# cbr -- constant bitrate
# cbr_hq -- cbr high quality
# cbr_ld_hq -- cbr low delay high quality
# vbr_hq -- vbr high quality
##########################
# nv_rc = auto
###### h264 entropy ######
# auto -- let ffmpeg nvenc decide the entropy encoding
# cabac
# cavlc
##########################
# nv_coder = auto
##################################### AMD #####################################
###### presets ###########
# default
# speed
# balanced
##########################
# amd_preset = balanced
#
####### rate control #####
# auto -- let ffmpeg decide rate control
# constqp -- constant QP mode
# vbr_latency -- Latency Constrained Variable Bitrate
# vbr_peak -- Peak Contrained Variable Bitrate
# cbr -- constant bitrate
##########################
# amd_rc = auto
###### h264 entropy ######
# auto -- let ffmpeg nvenc decide the entropy encoding
# cabac
# cavlc
##########################
# amd_coder = auto
#################################### VAAPI ###################################
####### adapter ##########
# Unlike with `amdvce` and `nvenc`, it doesn't matter if video encoding is done
# on a different GPU.
# Run the following commands:
# 1. ls /dev/dri/renderD*
# to find all devices capable of VAAPI
# 2. vainfo --display drm --device /dev/dri/renderD129 | grep -E "((VAProfileH264High|VAProfileHEVCMain|VAProfileHEVCMain10).*VAEntrypointEncSlice)|Driver version"
# Lists the name and capabilities of the device.
# To be supported by Sunshine, it needs to have at the very minimum:
# VAProfileH264High : VAEntrypointEncSlice
# adapter_name = /dev/dri/renderD128
##############################################
# Some configurable parameters, are merely toggles for specific features
# The first occurrence turns it on, the second occurence turns it off, the third occurence turns it on again, etc, etc
# Here, you change the default state of any flag
#
# To set the initial state of flags -0 and -1 to on, set the following flags:
# flags = 012
#
# See: sunshine --help for all options under the header: flags

View File

@@ -0,0 +1,21 @@
Section "Device"
Identifier "Configured Video Device"
Driver "dummy"
EndSection
Section "Monitor"
Identifier "Configured Monitor"
HorizSync 31.5-48.5
VertRefresh 50-70
EndSection
Section "Screen"
Identifier "Default Screen"
Monitor "Configured Monitor"
Device "Configured Video Device"
DefaultDepth 24
SubSection "Display"
Depth 24
Modes "1600x900"
EndSubSection
EndSection

View File

@@ -0,0 +1,69 @@
#!/usr/bin/env bash
###
# File: common-functions.sh
# Project: bin
# File Created: Tuesday, 6th October 2022 9:30:00 pm
# Author: Josh.5 (jsunnex@gmail.com)
# -----
# Last Modified: Tuesday, 6th October 2022 9:30:00 pm
# Modified By: Josh.5 (jsunnex@gmail.com)
###
# Wait for X server to start
# (Credit: https://gist.github.com/tullmann/476cc71169295d5c3fe6)
wait_for_x() {
MAX=60 # About 30 seconds
CT=0
while ! xdpyinfo >/dev/null 2>&1; do
sleep 0.50s
CT=$(( CT + 1 ))
if [ "$CT" -ge "$MAX" ]; then
echo "FATAL: $0: Gave up waiting for X server $DISPLAY"
exit 11
fi
done
}
# Wait for udev init to complete
wait_for_udev() {
MAX=10
CT=0
while [ ! -f /tmp/.udev-started ]; do
sleep 1
CT=$(( CT + 1 ))
if [ "$CT" -ge "$MAX" ]; then
echo "FATAL: $0: Gave up waiting for udev server to start"
exit 11
fi
done
}
# Wait for dockerd to start
wait_for_docker() {
MAX=10
CT=0
while ! docker system info >/dev/null 2>&1; do
sleep 1
CT=$(( CT + 1 ))
if [ "$CT" -ge "$MAX" ]; then
echo "FATAL: $0: Gave up waiting for dockerd service to start"
exit 11
fi
done
echo "DOCKERD RUNNING!"
}
# Fech NVIDIA GPU device (if one exists)
get_nvidia_gpu_id() {
if [ "${NVIDIA_VISIBLE_DEVICES:-}" == "all" ]; then
gpu_select=$(nvidia-smi --format=csv --query-gpu=uuid 2> /dev/null | sed -n 2p)
elif [ -z "${NVIDIA_VISIBLE_DEVICES:-}" ]; then
gpu_select=$(nvidia-smi --format=csv --query-gpu=uuid 2> /dev/null | sed -n 2p)
else
gpu_select=$(nvidia-smi --format=csv --id=$(echo "${NVIDIA_VISIBLE_DEVICES:-}" | cut -d ',' -f1) --query-gpu=uuid | sed -n 2p)
if [ -z "$gpu_select" ]; then
gpu_select=$(nvidia-smi --format=csv --query-gpu=uuid 2> /dev/null | sed -n 2p)
fi
fi
echo ${gpu_select}
}

View File

@@ -0,0 +1,42 @@
#!/usr/bin/env bash
###
# File: start-desktop.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 2:34:11 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 "$desktop_pid" 2>/dev/null
}
trap _term SIGTERM SIGINT
# CONFIGURE:
export $(dbus-launch)
# EXECUTE PROCESS:
# Install/Upgrade user apps
if [[ ! -f /tmp/.desktop-apps-updated.lock ]]; then
source /opt/scripts/install_steam.sh
source /opt/scripts/install_firefox.sh
source /opt/scripts/install_protonup.sh
touch /tmp/.desktop-apps-updated.lock
fi
# Wait for the X server to start
wait_for_x
# Run the desktop environment
echo "**** Starting Xfce4 ****"
/usr/bin/startxfce4 &
desktop_pid=$!
# WAIT FOR CHILD PROCESS:
wait "$desktop_pid"

52
overlay/usr/bin/start-dind.sh Executable file
View 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"

View 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"

View File

@@ -0,0 +1,29 @@
#!/usr/bin/env bash
###
# File: start-desktop.sh
# Project: bin
# File Created: Thursday, 1st January 1970 12:00:00 pm
# Author: Josh.5 (jsunnex@gmail.com)
# -----
# Last Modified: Sunday, 2nd October 2022 22:58:17 pm
# Modified By: Josh.5 (jsunnex@gmail.com)
###
set -e
# CATCH TERM SIGNAL:
_term() {
kill -TERM "$pulseaudio_pid" 2>/dev/null
}
trap _term SIGTERM SIGINT
# EXECUTE PROCESS:
echo "PULSEAUDIO: Starting pulseaudio service"
sleep 5
#/usr/bin/pulseaudio --disallow-module-loading --disallow-exit --exit-idle-time=-1 &
/usr/bin/pulseaudio --exit-idle-time=-1 &
pulseaudio_pid=$!
# WAIT FOR CHILD PROCESS:
wait "$pulseaudio_pid"

View File

@@ -0,0 +1,56 @@
#!/usr/bin/env bash
###
# File: start-sunshine.sh
# Project: bin
# File Created: Tuesday, 4th October 2022 8:22:17 pm
# Author: Josh.5 (jsunnex@gmail.com)
# -----
# Last Modified: Tuesday, 4th October 2022 8:22:17 pm
# Modified By: Josh.5 (jsunnex@gmail.com)
###
set -e
source /usr/bin/common-functions.sh
# CATCH TERM SIGNAL:
_term() {
kill -TERM "$sunshine_pid" 2>/dev/null
}
trap _term SIGTERM SIGINT
# CONFIGURE:
# Install default configurations
mkdir -p /home/${USER}/sunshine
if [[ ! -f /home/${USER}/sunshine/sunshine.conf ]]; then
cp -vf /templates/sunshine/* /home/${USER}/sunshine/
# TODO: Set the default encoder '# encoder = nvenc'
# nvidia_gpu_id=$(get_nvidia_gpu_id)
# if [[ "X${nvidia_gpu_id:-}" != "X" ]]; then
# if [[ "all video" == *"${NVIDIA_DRIVER_CAPABILITIES}"* ]]; then
# # Check if we have a nvidia GPU available
# sed -i 's|^# encoder.*=.*$|encoder = nvenc|' /home/${USER}/sunshine/sunshine.conf
# fi
# else
# # TODO: Enable the vaapi device if not using nvenc
# # vainfo --display drm --device /dev/dri/renderD128 2> /dev/null | grep -E "((VAProfileH264High|VAProfileHEVCMain|VAProfileHEVCMain10).*VAEntrypointEncSlice)"
# # Loop over any render devices
# echo
# fi
fi
# Reset the default username/password
if ([ "X${SUNSHINE_USER:-}" != "X" ] && [ "X${SUNSHINE_PASS:-}" != "X" ]); then
sunshine /home/${USER}/sunshine/sunshine.conf --creds ${SUNSHINE_USER:-} ${SUNSHINE_PASS:-}
fi
# EXECUTE PROCESS:
# Wait for the X server to start
wait_for_x
# Start the sunshine server
sunshine /home/${USER}/sunshine/sunshine.conf &
sunshine_pid=$!
# WAIT FOR CHILD PROCESS:
wait "$sunshine_pid"

40
overlay/usr/bin/start-udev.sh Executable file
View File

@@ -0,0 +1,40 @@
#!/usr/bin/env bash
###
# File: start-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 "$monitor_pid" 2>/dev/null
}
trap _term SIGTERM SIGINT
# EXECUTE PROCESS:
# Remove lockfile
rm -f /tmp/.udev-started
# Start udev
if command -v udevd &>/dev/null; then
unshare --net udevd --daemon &>/dev/null
else
unshare --net /lib/systemd/systemd-udevd --daemon &>/dev/null
fi
# Monitor kernel uevents
udevadm monitor &
monitor_pid=$!
# Touch lockfile
sleep 1
touch /tmp/.udev-started
# Wait for 10 seconds, then request device events from the kernel
sleep 10
udevadm trigger
# WAIT FOR CHILD PROCESS:
wait "$monitor_pid"

30
overlay/usr/bin/start-x11vnc.sh Executable file
View File

@@ -0,0 +1,30 @@
#!/usr/bin/env bash
###
# File: start-x11vnc.sh
# Project: bin
# File Created: Tuesday, 6th October 2022 9:30:00 pm
# Author: Josh.5 (jsunnex@gmail.com)
# -----
# Last Modified: Tuesday, 6th October 2022 9:30:00 pm
# Modified By: Josh.5 (jsunnex@gmail.com)
###
set -e
source /usr/bin/common-functions.sh
# CATCH TERM SIGNAL:
_term() {
kill -TERM "$x11vnc_pid" 2>/dev/null
}
trap _term SIGTERM SIGINT
# EXECUTE PROCESS:
# Wait for the X server to start
wait_for_x
# Start the x11vnc server
/usr/bin/x11vnc -display ${DISPLAY} -rfbport ${PORT_VNC} -shared -forever&
x11vnc_pid=$!
# WAIT FOR CHILD PROCESS:
wait "$x11vnc_pid"

50
overlay/usr/bin/start-xorg.sh Executable file
View File

@@ -0,0 +1,50 @@
#!/usr/bin/env bash
###
# File: start-xorg.sh
# Project: bin
# File Created: Tuesday, 11th January 2022 8:28:52 pm
# Author: Josh.5 (jsunnex@gmail.com)
# -----
# Last Modified: Friday, 6th October 2022 9:21:00 pm
# Modified By: Josh.5 (jsunnex@gmail.com)
###
set -e
source /usr/bin/common-functions.sh
# CATCH TERM SIGNAL:
_term() {
kill -TERM "$xorg_pid" 2>/dev/null
}
trap _term SIGTERM SIGINT
# EXECUTE PROCESS:
# Wait for udev
wait_for_udev
# Run X server
/usr/bin/Xorg \
-ac \
-noreset \
-novtswitch \
-sharevts \
+extension RANDR \
+extension RENDER \
+extension GLX \
+extension XVideo \
+extension DOUBLE-BUFFER \
+extension SECURITY \
+extension DAMAGE \
+extension X-Resource \
-extension XINERAMA -xinerama \
+extension Composite +extension COMPOSITE \
-dpms \
-s off \
-nolisten tcp \
-iglx \
-verbose \
vt7 "${DISPLAY:?}" &
xorg_pid=$!
# WAIT FOR CHILD PROCESS:
wait "$xorg_pid"

Binary file not shown.

After

Width:  |  Height:  |  Size: 366 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB