Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
d73cccf
feat: add Fedora variant images alongside Ubuntu defaults
Apr 2, 2026
1d1b862
feat: add Fedora variants for all remaining GOW images
Apr 2, 2026
7c893c0
Fix Fedora 43 package availability in Dockerfiles
Apr 2, 2026
ca6dcb2
fix: prevent digest artifact collision between Ubuntu and Fedora builds
Apr 2, 2026
6af971e
chore: update GAMESCOPE_VERSION to 3.16.22
Apr 2, 2026
187196f
fix: kodi remove service command, pegasus remove missing packages
Apr 2, 2026
ebd30d5
fix: use base-app image for bwrap builder, fix pegasus download
Apr 2, 2026
1c87f79
fix: bump GitHub Actions to Node.js 24, fix deprecation warnings
Apr 2, 2026
ad0e862
Fix Fedora paths: use lib64 instead of x86_64-linux-gnu
Apr 2, 2026
0c8ba0d
fedora: address PR #305 review feedback
Apr 11, 2026
12e2837
apps: add Plex HTPC, Emby Theater, and FreeTube (YouTube ad-free)
Apr 11, 2026
7d9895d
fix: correct plex/emby/youtube install sources
Apr 11, 2026
95cfb33
plex: install Plex HTPC via Flathub at build time
Apr 11, 2026
f4fc254
Merge pull request #307 from games-on-whales/media-apps-plex-emby-you…
JBailes Apr 11, 2026
e175ac1
base: pull Ubuntu/Fedora base images from vendor mirrors
JBailes Apr 11, 2026
dc3cbbe
base-emu-fedora: dnf install --allowerasing to resolve ffmpeg conflict
JBailes Apr 11, 2026
3dc7422
xfce-fedora: guard flatpak first-run setup against missing binary
JBailes Apr 11, 2026
e8622d4
xfce-fedora: remove nonexistent gnome-software-plugin-flatpak, scope …
Apr 11, 2026
9cc27c0
fix: resolve gamescope path dynamically for Fedora compatibility
JBailes Apr 14, 2026
088f76b
prismlauncher: install from official GitHub portable release
JBailes Apr 14, 2026
b0a010d
fix: use contains/endswith in prismlauncher jq filter
JBailes Apr 14, 2026
1bf9385
Merge pull request #310 from games-on-whales/fix/fedora-gamescope-path
JBailes Apr 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 82 additions & 0 deletions .github/workflows/auto-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ jobs:
- { name: prismlauncher, docker_path: apps, platforms: "linux/amd64" }
- { name: kodi, docker_path: apps, platforms: "linux/amd64" }
- { name: xfce, docker_path: apps, platforms: "linux/amd64" }
- { name: plex, docker_path: apps, platforms: "linux/amd64" }
- { name: emby, docker_path: apps, platforms: "linux/amd64" }
- { name: youtube, docker_path: apps, platforms: "linux/amd64" }
fail-fast: false
uses: ./.github/workflows/docker-build-and-publish.yml
with:
Expand All @@ -88,3 +91,82 @@ jobs:
platforms: "${{ matrix.image.platforms }}"
secrets: inherit

# ========== Fedora variant ==========
base-fedora:
uses: ./.github/workflows/docker-build-and-publish.yml
with:
docker_path: "images"
image_name: "base"
variant: "fedora"
platforms: "linux/amd64"
secrets: inherit

base-app-fedora:
needs: [ base-fedora ]
uses: ./.github/workflows/docker-build-and-publish.yml
with:
docker_path: "images"
image_name: "base-app"
variant: "fedora"
base_image: "${{ needs.base-fedora.outputs.image_tag }}"
platforms: "linux/amd64"
secrets: inherit

base-emu-fedora:
needs: [ base-fedora, base-app-fedora ]
uses: ./.github/workflows/docker-build-and-publish.yml
with:
docker_path: "images"
image_name: "base-emu"
variant: "fedora"
base_image: "${{ needs.base-fedora.outputs.image_tag }}"
base_app_image: "${{ needs.base-app-fedora.outputs.image_tag }}"
platforms: "linux/amd64"
secrets: inherit

emus-fedora:
needs: [ base-fedora, base-app-fedora, base-emu-fedora ]
strategy:
matrix:
image:
- { name: pegasus, platforms: "linux/amd64" }
- { name: es-de, platforms: "linux/amd64" }
fail-fast: false
uses: ./.github/workflows/docker-build-and-publish.yml
with:
docker_path: "apps"
image_name: "${{ matrix.image.name }}"
variant: "fedora"
base_image: "${{ needs.base-fedora.outputs.image_tag }}"
base_app_image: "${{ needs.base-emu-fedora.outputs.image_tag }}"
platforms: "${{ matrix.image.platforms }}"
secrets: inherit

apps-fedora:
needs: [ base-fedora, base-app-fedora ]
strategy:
matrix:
image:
- { name: pulseaudio, docker_path: images, platforms: "linux/amd64" }
- { name: retroarch, docker_path: apps, platforms: "linux/amd64" }
- { name: firefox, docker_path: apps, platforms: "linux/amd64" }
- { name: steam, docker_path: apps, platforms: "linux/amd64" }
- { name: lutris, docker_path: apps, platforms: "linux/amd64" }
- { name: heroic-games-launcher, docker_path: apps, platforms: "linux/amd64" }
- { name: prismlauncher, docker_path: apps, platforms: "linux/amd64" }
- { name: kodi, docker_path: apps, platforms: "linux/amd64" }
- { name: xfce, docker_path: apps, platforms: "linux/amd64" }
- { name: plex, docker_path: apps, platforms: "linux/amd64" }
- { name: emby, docker_path: apps, platforms: "linux/amd64" }
- { name: youtube, docker_path: apps, platforms: "linux/amd64" }
fail-fast: false
uses: ./.github/workflows/docker-build-and-publish.yml
with:
docker_path: "${{ matrix.image.docker_path }}"
image_name: "${{ matrix.image.name }}"
variant: "fedora"
base_image: "${{ needs.base-fedora.outputs.image_tag }}"
base_app_image: "${{ needs.base-app-fedora.outputs.image_tag }}"
platforms: "${{ matrix.image.platforms }}"
secrets: inherit

108 changes: 60 additions & 48 deletions .github/workflows/docker-build-and-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ on:
default: "linux/amd64"
type: string
required: false
variant:
description: "Image variant (e.g. 'fedora'). Affects build dir and tag suffix."
type: string
required: false
default: ""
outputs:
image_tag:
description: "The highest-priority tag assigned to the built image"
Expand Down Expand Up @@ -137,16 +142,16 @@ jobs:
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV

- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6

- name: Cache buildx layers locally
if: github.event_name == 'pull_request'
uses: actions/cache@v4
if: ${{ needs.prepare.outputs.is_fork == 'true' }}
uses: actions/cache@v5
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ inputs.image_name }}-${{ env.PLATFORM_PAIR }}-pr-${{ github.event.number }}
key: ${{ runner.os }}-buildx-${{ inputs.image_name }}${{ inputs.variant != '' && format('-{0}', inputs.variant) || '' }}-${{ env.PLATFORM_PAIR }}-pr-${{ github.event.number }}
restore-keys: |
${{ runner.os }}-buildx-${{ inputs.image_name }}-${{ env.PLATFORM_PAIR }}-
${{ runner.os }}-buildx-${{ inputs.image_name }}${{ inputs.variant != '' && format('-{0}', inputs.variant) || '' }}-${{ env.PLATFORM_PAIR }}-

# Set derived configuration variables:
# - images: images to build (docker and/or github)
Expand All @@ -164,9 +169,10 @@ jobs:
IMAGES=""
CURRENT_PLATFORM="${{ contains(matrix.platform, 'arm64') && 'arm64' || 'x86' }}"

upstream_build_from_cache_image="ghcr.io/games-on-whales/${{ inputs.image_name }}:buildcache-${CURRENT_PLATFORM}"
build_from_cache_image="ghcr.io/${{ needs.prepare.outputs.ghcr_namespace }}/${{ inputs.image_name }}:buildcache-${CURRENT_PLATFORM}"
build_to_cache_image="ghcr.io/${{ needs.prepare.outputs.ghcr_namespace }}/${{ inputs.image_name }}:buildcache-${CURRENT_PLATFORM}"
VARIANT_SUFFIX="${{ inputs.variant != '' && format('-{0}', inputs.variant) || '' }}"
upstream_build_from_cache_image="ghcr.io/games-on-whales/${{ inputs.image_name }}:buildcache${VARIANT_SUFFIX}-${CURRENT_PLATFORM}"
build_from_cache_image="ghcr.io/${{ needs.prepare.outputs.ghcr_namespace }}/${{ inputs.image_name }}:buildcache${VARIANT_SUFFIX}-${CURRENT_PLATFORM}"
build_to_cache_image="ghcr.io/${{ needs.prepare.outputs.ghcr_namespace }}/${{ inputs.image_name }}:buildcache${VARIANT_SUFFIX}-${CURRENT_PLATFORM}"

echo "==> Testing if build cache ${build_from_cache_image} exists"
docker buildx imagetools inspect "${build_from_cache_image}" 2>/dev/null || build_cache_missing=1
Expand All @@ -177,7 +183,7 @@ jobs:
echo "==> Found existing buildx cache for branch build, using image ${build_from_cache_image}"
fi

if [[ "${{ github.event_name }}" != "pull_request" ]]; then
if [[ "${{ needs.prepare.outputs.is_fork }}" == "false" ]]; then
echo "==> Setting variables for branch build"

if [ -n "${{ secrets.GITHUB_TOKEN }}" ]; then
Expand Down Expand Up @@ -248,7 +254,7 @@ jobs:

- name: Download base image artifact
id: download-base-image-artifact
if: ${{ github.event_name == 'pull_request' && steps.prep.outputs.base_image_name != '' }}
if: ${{ needs.prepare.outputs.is_fork == 'true' && steps.prep.outputs.base_image_name != '' }}
uses: dawidd6/action-download-artifact@v10
with:
name: docker-${{ steps.prep.outputs.base_image_name }}-${{ env.PLATFORM_PAIR }}.tar
Expand All @@ -261,7 +267,7 @@ jobs:

- name: Download base-app image artifact
id: download-base-app-image-artifact
if: ${{ github.event_name == 'pull_request' && steps.prep.outputs.base_app_image_name != '' }}
if: ${{ needs.prepare.outputs.is_fork == 'true' && steps.prep.outputs.base_app_image_name != '' }}
uses: dawidd6/action-download-artifact@v10
with:
name: docker-${{ steps.prep.outputs.base_app_image_name }}-${{ env.PLATFORM_PAIR }}.tar
Expand All @@ -274,50 +280,52 @@ jobs:

- name: Docker meta
id: meta
uses: docker/metadata-action@v5
uses: docker/metadata-action@v6
with:
# list of Docker images to use as base name for tags
images: ${{ steps.prep.outputs.images }}
# generate Docker tags based on the following events/attributes
tags: |
type=semver,pattern={{version}}
type=semver,pattern={{major}}
type=edge,branch=master
type=ref,event=branch
type=sha
flavor: latest=auto #latest will point to last semver version (stable)
type=semver,pattern={{version}},suffix=${{ inputs.variant != '' && format('-{0}', inputs.variant) || '' }}
type=semver,pattern={{major}},suffix=${{ inputs.variant != '' && format('-{0}', inputs.variant) || '' }}
type=edge,branch=master,suffix=${{ inputs.variant != '' && format('-{0}', inputs.variant) || '' }}
type=ref,event=branch,suffix=${{ inputs.variant != '' && format('-{0}', inputs.variant) || '' }}
type=sha,suffix=${{ inputs.variant != '' && format('-{0}', inputs.variant) || '' }}
${{ inputs.variant == 'fedora' && 'type=raw,value=fedora' || '' }}
${{ inputs.variant == 'fedora' && 'type=raw,value=fedora-43' || '' }}
flavor: |
latest=auto

# Prepare for multi-arch
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
uses: docker/setup-qemu-action@v4
with:
platforms: all

- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@v4
with:
install: true
version: latest
driver-opts: image=moby/buildkit:master${{ github.event_name == 'pull_request' && ',network=host' || '' }}

- name: Login to DockerHub
if: steps.prep.outputs.has_docker_token != ''
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
username: ${{ env.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Login to GitHub Container Registry
if: steps.prep.outputs.has_github_token != ''
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Load base image
if: github.event_name == 'pull_request' && steps.prep.outputs.base_image_name != ''
if: needs.prepare.outputs.is_fork == 'true' && steps.prep.outputs.base_image_name != ''
run: |
set -e
echo "==> Loading base image from artifact"
Expand All @@ -327,7 +335,7 @@ jobs:
docker push "${{ inputs.base_image }}"

- name: Load base-app image
if: github.event_name == 'pull_request' && steps.prep.outputs.base_app_image_name != ''
if: needs.prepare.outputs.is_fork == 'true' && steps.prep.outputs.base_app_image_name != ''
run: |
set -e
echo "==> Loading base-app image from artifact"
Expand All @@ -338,11 +346,11 @@ jobs:

- name: Build and Push
id: docker_build
uses: docker/build-push-action@v6
uses: docker/build-push-action@v7
with:
builder: ${{ steps.buildx.outputs.name }}
context: ./${{ inputs.docker_path }}/${{ inputs.image_name }}/build
file: ./${{ inputs.docker_path }}/${{ inputs.image_name }}/build/Dockerfile
context: ./${{ inputs.docker_path }}/${{ inputs.image_name }}/build${{ inputs.variant != '' && format('-{0}', inputs.variant) || '' }}
file: ./${{ inputs.docker_path }}/${{ inputs.image_name }}/build${{ inputs.variant != '' && format('-{0}', inputs.variant) || '' }}/Dockerfile
platforms: ${{ matrix.platform }}
outputs: ${{ steps.prep.outputs.buildx_outputs }}
tags: ${{ steps.meta.outputs.tags }}
Expand All @@ -354,10 +362,10 @@ jobs:
cache-to: ${{ steps.prep.outputs.cache_to }}

- name: Upload docker image as artifact
if: github.event_name == 'pull_request'
uses: actions/upload-artifact@v4
if: ${{ needs.prepare.outputs.is_fork == 'true' }}
uses: actions/upload-artifact@v7
with:
name: docker-${{ inputs.image_name }}-${{ env.PLATFORM_PAIR }}.tar
name: docker-${{ inputs.image_name }}${{ inputs.variant != '' && format('-{0}', inputs.variant) || '' }}-${{ env.PLATFORM_PAIR }}.tar
path: /tmp/${{ inputs.image_name }}-*.tar
if-no-files-found: error
retention-days: 1
Expand All @@ -366,7 +374,7 @@ jobs:
# https://github.com/docker/build-push-action/issues/252
# https://github.com/moby/buildkit/issues/1896
- name: Cleanup buildx cache
if: github.event_name == 'pull_request'
if: ${{ needs.prepare.outputs.is_fork == 'true' }}
run: |
rm -rf /tmp/.buildx-cache
mv /tmp/.buildx-cache-new /tmp/.buildx-cache
Expand All @@ -375,7 +383,7 @@ jobs:
run: echo "${{ inputs.image_name }} > ${{ steps.docker_build.outputs.digest }}"

- name: Export digest
if: github.event_name != 'pull_request'
if: ${{ needs.prepare.outputs.is_fork == 'false' }}
id: export-digest
run: |
mkdir -p /tmp/digests
Expand All @@ -384,10 +392,10 @@ jobs:
echo "hash=${digest#sha256:}" >> $GITHUB_OUTPUT

- name: Upload digest
if: github.event_name != 'pull_request'
uses: actions/upload-artifact@v4
if: ${{ needs.prepare.outputs.is_fork == 'false' }}
uses: actions/upload-artifact@v7
with:
name: digests-${{ inputs.image_name }}-${{ env.PLATFORM_PAIR }}
name: digests-${{ inputs.variant != '' && format('{0}-', inputs.variant) || '' }}${{ inputs.image_name }}-${{ env.PLATFORM_PAIR }}
path: /tmp/digests/*
if-no-files-found: error
overwrite: true
Expand All @@ -399,44 +407,48 @@ jobs:
merge:
runs-on: ubuntu-latest
needs: [ prepare, docker ]
if: github.event_name != 'pull_request'
if: ${{ needs.prepare.outputs.is_fork == 'false' }}
steps:
- name: Download digests
uses: actions/download-artifact@v4
uses: actions/download-artifact@v8
with:
path: /tmp/digests
pattern: digests-${{ inputs.image_name }}-*
pattern: digests-${{ inputs.variant != '' && format('{0}-', inputs.variant) || '' }}${{ inputs.image_name }}-*
merge-multiple: true

- name: Login to Docker Hub
if: needs.docker.outputs.has_docker_token != ''
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
username: ${{ env.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Login to GHCR
if: needs.docker.outputs.has_github_token != ''
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@v4

- name: Docker meta
id: meta
uses: docker/metadata-action@v5
uses: docker/metadata-action@v6
with:
images: ${{ needs.docker.outputs.images }}
tags: |
type=semver,pattern={{version}}
type=semver,pattern={{major}}
type=edge,branch=master
type=ref,event=branch
type=sha
type=semver,pattern={{version}},suffix=${{ inputs.variant != '' && format('-{0}', inputs.variant) || '' }}
type=semver,pattern={{major}},suffix=${{ inputs.variant != '' && format('-{0}', inputs.variant) || '' }}
type=edge,branch=master,suffix=${{ inputs.variant != '' && format('-{0}', inputs.variant) || '' }}
type=ref,event=branch,suffix=${{ inputs.variant != '' && format('-{0}', inputs.variant) || '' }}
type=sha,suffix=${{ inputs.variant != '' && format('-{0}', inputs.variant) || '' }}
${{ inputs.variant == 'fedora' && 'type=raw,value=fedora' || '' }}
${{ inputs.variant == 'fedora' && 'type=raw,value=fedora-43' || '' }}
flavor: |
latest=auto

- name: Create ghcr manifest list and push
if: needs.docker.outputs.has_github_token != ''
Expand Down
7 changes: 7 additions & 0 deletions apps/emby/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Emby

Emby Theater — the official living-room client for Emby Server. Streams your
personal media library with a gamepad-friendly 10-foot UI.

This image installs the upstream Emby Theater Electron build from its GitHub
releases and launches it full-screen on top of Sway.
23 changes: 23 additions & 0 deletions apps/emby/assets/wolf.config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[[apps]]
title = "Emby"
icon_png_path = "https://games-on-whales.github.io/wildlife/apps/emby/assets/icon.png"

[apps.runner]
type = "docker"
name = "WolfEmby"
image = "ghcr.io/games-on-whales/emby:edge"
mounts = []
env = ["RUN_SWAY=1", "GOW_REQUIRED_DEVICES=/dev/input/* /dev/dri/* /dev/nvidia*"]
devices = []
ports = []
base_create_json = """
{
"HostConfig": {
"IpcMode": "host",
"Privileged": false,
"CapAdd": ["NET_RAW", "MKNOD", "NET_ADMIN"],
"DeviceCgroupRules": ["c 13:* rmw", "c 244:* rmw"]
}
}
\
"""
Loading
Loading