Sunshine Docker 容器化部署完全指南:标签体系、端口映射与自建镜像

原创2026-10-02 12:28:091,734 阅读
文章标签:音视频后端桌面应用

Sunshine Docker 容器化部署完全指南:标签体系、端口映射与自建镜像

本文是一份面向开发者的 Sunshine(自托管游戏串流主机,兼容 Moonlight 客户端)Docker 部署技术指南,完整讲解其镜像标签命名规范、六种操作系统镜像变体、docker run / docker-compose / podman 三种部署方式、端口与数据卷映射、PUID/PGID 用户权限机制,并结合本仓库 docker/ 目录下的真实 Dockerfile 源码剖析镜像的构建流程与配置目录落盘逻辑,帮助读者在容器环境中稳定、安全地运行 Sunshine 串流服务。

重要提示:v0.18.0 起的标签命名变更

自 v0.18.0 起,Sunshine 的 Docker 镜像标签命名规则发生了破坏性变更:

  • 不再支持 latest、master、vX.X.X 这类单独使用的版本标签;
  • 所有镜像标签都必须采用 <SUNSHINE_VERSION>-<SUNSHINE_OS> 的组合格式,例如 latest-ubuntu-24.04。

这意味着,沿用旧习惯执行 docker pull lizardbyte/sunshine:latest 将无法获取镜像。在编写 docker run、docker-compose.yml 或 FROM 指令时,务必显式同时指定版本与操作系统后缀。从源码结构看,该命名策略与 docker/ 目录下按发行版划分的多份 Dockerfile 一一对应,正是为了在单个仓库中维护多发行版、多架构镜像而设计的。

基于官方镜像构建你自己的容器

官方镜像提供了一种便捷方式,让你能够在自己构建的 Docker 项目中直接使用最新的 Sunshine 发布版本。官方文档明确说明:该镜像目前并非设计为独立运行的容器,而是作为其他 Docker 项目的基础镜像使用,属于实验性特性。

最小 Dockerfile 模板

在 Dockerfile 中通过 ARG 声明版本与操作系统,再以 FROM 组合出完整镜像标签:

ARG SUNSHINE_VERSION=latest
ARG SUNSHINE_OS=ubuntu-22.04
FROM lizardbyte/sunshine:${SUNSHINE_VERSION}-${SUNSHINE_OS}

# install Steam, Wayland, etc.

ENTRYPOINT steam && sunshine

FROM 行会在构建时把 SUNSHINE_VERSION 与 SUNSHINE_OS 拼接成 <版本>-<系统> 形式的完整标签(如 latest-ubuntu-22.04)。在基础镜像之上,你可以自由安装 Steam、Wayland 等串流场景所需的软件,最后自定义 ENTRYPOINT,例如示例中的 steam && sunshine——先拉起 Steam 再启动 Sunshine,以支撑游戏串流场景。

SUNSHINE_VERSION:版本参数

SUNSHINE_VERSION 支持以下取值:

  • latest、master、vX.X.X:分别对应最新发布版、主分支构建、指定版本号构建;
  • commit hash:仓库中任意一次提交的哈希值,用于构建特定代码状态的镜像。

SUNSHINE_OS:操作系统参数

Sunshine 镜像按基础镜像发行版提供以下标签后缀:

  • archlinux
  • debian-bookworm
  • fedora-39
  • fedora-40
  • ubuntu-22.04
  • ubuntu-24.04

标签组合规则

拉取镜像时必须组合 SUNSHINE_VERSION 与 SUNSHINE_OS,格式为 <SUNSHINE_VERSION>-<SUNSHINE_OS>。例如:

  • latest-ubuntu-24.04
  • master-debian-bookworm
  • v0.18.0-archlinux

官方在 Docker Hub(lizardbyte/sunshine)与 GHCR(ghcr.io/lizardbyte/sunshine)上发布镜像。由于本任务无法确认该仓库是否已同步推送镜像,上文镜像地址仅供参考,实际拉取请以对应镜像仓库当前的可用标签为准。

源码佐证:docker/ 目录下的镜像构建实现

本仓库 docker/ 目录中的 6 份发行版 Dockerfile 与官方文档所述标签一一对应,且均采用多阶段构建:

发行版 Dockerfile 产物格式 架构
Arch Linux docker/archlinux.dockerfile .pkg.tar.zst(pacman) amd64
Debian 12 docker/debian-bookworm.dockerfile .deb(apt) amd64/arm64
Fedora 39 docker/fedora-39.dockerfile .rpm(dnf) amd64
Fedora 40 docker/fedora-40.dockerfile .rpm(dnf) amd64
Ubuntu 22.04 docker/ubuntu-22.04.dockerfile .deb(apt) amd64/arm64
Ubuntu 24.04 docker/ubuntu-24.04.dockerfile .deb(apt) amd64/arm64

以 docker/ubuntu-22.04.dockerfile 为例,其构建流程清晰呈现了完整链路:

  1. sunshine-build 阶段:复制仓库源码后调用 ./scripts/linux_build.sh 完成依赖安装、CMake 配置与编译(DEB/RPM 打包逻辑可参见 scripts/linux_build.sh,其中会传入 --publisher-name、--publisher-website、--publisher-issue-url 与 --sudo-off);
  2. 测试阶段:使用 Xvfb 创建虚拟显示 :1,执行 ./test_sunshine --gtest_color=yes 运行仓库单元测试(对应 tests/ 下的 googletest 用例),确保产物通过自检;
  3. artifacts 阶段:从 scratch 空镜像中仅保留 build/cpack_artifacts/Sunshine.deb 构建产物;
  4. sunshine 最终阶段:安装 DEB 包,声明端口,创建 lizard 用户并设置默认 PUID=1000、PGID=1000、TZ="UTC",最后以 ENTRYPOINT ["/usr/bin/sunshine"] 启动。

最终阶段中关键的一行是配置目录落盘逻辑:

mkdir -p ${HOME}/.config/sunshine
ln -s ${HOME}/.config/sunshine /config

即容器内的 /config 是指向 $HOME/.config/sunshine 的软链接。这与 src/platform/linux/misc.cpp 中 Sunshine 的配置目录解析逻辑一致:进程会依次检查 CONFIGURATION_DIRECTORY 环境变量、XDG_CONFIG_HOME 环境变量,最后回退到 $HOME/.config/sunshine。因此将宿主机数据目录挂载到 /config,即可持久化全部配置、凭据与状态文件。macOS 平台下同样的 $HOME/.config/sunshine 约定可参见 src/platform/macos/misc.mm。

端口与数据卷映射

下面分别给出 docker run、docker-compose、podman run 三种方式的完整示例(尖括号 <values> 需替换为你的实际取值)。所有列出的端口均为 Sunshine 正常提供服务所必需,不可省略。

使用 docker run

docker run -d \
  --device /dev/dri/ \
  --name=<image_name> \
  --restart=unless-stopped \
  --ipc=host \
  -e PUID=<uid> \
  -e PGID=<gid> \
  -e TZ=<timezone> \
  -v <path to data>:/config \
  -p 47984-47990:47984-47990/tcp \
  -p 48010:48010 \
  -p 47998-48000:47998-48000/udp \
  <image>

使用 docker-compose

version: '3'
services:
  <image_name>:
    image: <image>
    container_name: sunshine
    restart: unless-stopped
    volumes:
      - <path to data>:/config
    environment:
      - PUID=<uid>
      - PGID=<gid>
      - TZ=<timezone>
    ipc: host
    ports:
      - "47984-47990:47984-47990/tcp"
      - "48010:48010"
      - "47998-48000:47998-48000/udp"

使用 podman run

podman run -d \
  --device /dev/dri/ \
  --name=<image_name> \
  --restart=unless-stopped \
  --userns=keep-id \
  -e PUID=<uid> \
  -e PGID=<gid> \
  -e TZ=<timezone> \
  -v <path to data>:/config \
  -p 47984-47990:47984-47990/tcp \
  -p 48010:48010 \
  -p 47998-48000:47998-48000/udp \
  <image>

要点解读:

  • --device /dev/dri/:将宿主机 GPU 的 DRM 设备透传给容器,这是容器内 Sunshine 完成视频编码(VA-API 等硬件加速路径)的前提;podman 场景下配合 --userns=keep-id 可解决用户命名空间下的设备访问与权限问题;
  • --ipc=host(compose 中写作 ipc: host):共享宿主机的 IPC 命名空间;
  • --restart=unless-stopped:容器异常退出时自动重启,保证串流服务可用性;
  • 端口映射必须完整覆盖:TCP 段 47984-47990、TCP/UDP 单端口 48010、UDP 段 47998-48000。

参数说明表

参数分为两半,以冒号分隔:左侧代表宿主机,右侧代表容器。例如 -p external:internal 表示把容器内部端口映射到宿主机端口,因此 -p 47990:47990 会把容器内的 47990 端口暴露到宿主机 IP 的 47990 端口上(访问 http://<host_ip>:47990 即可打开 Web UI)。容器内部端口必须保持 47990 不变,宿主机侧端口可以自由修改(例如 -p 8080:47990)。

参数 作用 示例值 是否必需
-p <port>:47990 Web UI 端口 47990 是
-v <path to data>:/config 数据卷映射 /home/sunshine 是
-e PUID=<uid> 用户 ID 1001 否
-e PGID=<gid> 组 ID 1001 否
-e TZ=<timezone> 时区(取值参考 TZ 数据库时区列表) America/New_York 否

配置文件将保存到容器内的 /config 目录(如前述,其实际指向 $HOME/.config/sunshine)。更多进阶配置方式,官方推荐参考 Games on Whales 项目的 sunshine 配置示例。

PUID / PGID:解决宿主机与容器间的权限问题

使用数据卷(-v)挂载时,宿主机与容器之间可能出现文件权限冲突。为此镜像提供 PUID(用户 ID)与 PGID(组 ID)两个环境变量:确保宿主机上数据卷目录的属主与你指定的 UID/GID 一致,容器内 Sunshine 进程便会以该身份读写配置。

在示例中 PUID=1001、PGID=1001。查询你本机用户的 ID 方式如下:

$ id dockeruser
uid=1001(dockeruser) gid=1001(dockergroup) groups=1001(dockergroup)

注意:如果需要在镜像构建完成后更改 PUID/PGID,必须重新构建镜像——因为这两个变量在 Dockerfile 的 ARG/ENV 阶段(用户创建步骤)就已固化到镜像层中,运行时仅凭 -e 无法重建容器内用户身份。这一点可从上文 Dockerfile 源码中的 ARG PGID / ARG PUID / ENV PGID / ENV PUID 声明得到印证。

补充说明:本仓库各 Dockerfile 中,docker/archlinux.dockerfile、docker/debian-bookworm.dockerfile、docker/fedora-39.dockerfile、docker/fedora-40.dockerfile、docker/ubuntu-22.04.dockerfile 的默认值为 1000,而 docker/ubuntu-24.04.dockerfile 的默认值为 1001,各版本间存在差异,部署时建议显式指定而非依赖默认值。

支持的架构

指定 lizardbyte/sunshine:latest-<SUNSHINE_OS> 或 ghcr.io/lizardbyte/sunshine:latest-<SUNSHINE_OS> 时,镜像仓库会按架构自动匹配。各标签后缀支持的架构如下:

tag suffix amd64/x86_64 arm64/aarch64
archlinux ✅ ❌
debian-bookworm ✅ ✅
fedora-39 ✅ ❌
fedora-40 ✅ ❌
ubuntu-22.04 ✅ ✅
ubuntu-24.04 ✅ ✅

架构选择建议: ARM 设备(如树莓派、ARM 云主机)应优先选择 debian-bookworm、ubuntu-22.04 或 ubuntu-24.04 后缀;archlinux 与 fedora-* 目前仅提供 x86_64 架构镜像。这一点与 Dockerfile 顶部的 # platforms: 注释完全对应——例如 docker/ubuntu-22.04.dockerfile 声明 linux/amd64,linux/arm64/v8,而 docker/archlinux.dockerfile 因 Arch 无 arm64 基础镜像仅声明 linux/amd64。

已知的 Docker 集成项目

官方文档列出的、基于 Sunshine 镜像构建的典型 Docker 项目为 Games on Whales(GoW)——一个通过容器方式提供串流服务的开源项目,其 compose 配置中直接引用 Sunshine 镜像并将 Steam 等游戏运行环境打包在一起,与本文开头的基础镜像使用方式一致。若你基于 Sunshine 镜像构建了自己的项目,也可以向项目维护者反馈收录。

部署检查清单

完成容器部署后,可依次核对以下要点:

  1. 端口可达:宿主机上执行 ss -tlnp | grep -E '47990|48010' 与 ss -ulnp | grep -E '47998|48000' 确认 TCP/UDP 端口均已监听;Web UI 可通过 https://<host_ip>:47990 访问(首次访问会提示创建凭据,浏览器可能对本地自签名证书给出安全警告,此为正常现象);
  2. 配置持久化:确认宿主机 <path to data> 目录下已生成 Sunshine 配置文件,说明 /config 挂载生效;
  3. GPU 透传:在容器内执行 ls /dev/dri/ 检查 DRM 设备是否可见,必要时核对宿主机 GPU 驱动与容器内 VA-API 环境;
  4. 权限一致:确认数据卷目录属主的 UID/GID 与 PUID/PGID 一致,避免容器写入失败或权限错误;
  5. 客户端配对:使用 Moonlight 客户端添加主机并按界面提示完成 PIN 配对,随后即可发起串流会话。

相关背景资料可继续阅读仓库内 docs/building.md(Linux 构建指南)、docs/changelog.md(版本变更记录)与 docs/third_party_packages.md(第三方包说明)。

登录后查看全文
foundation-sunshine