Steam Headless 的核心思路是在一台没有连接显示器的 Ubuntu 主机上,用 Docker 容器运行完整 Steam 客户端,并借助容器内置的 Web 管理界面和流媒体组件对外提供服务。这样宿主机不需要安装桌面环境,也不需要物理显示器,登录、更新、启动游戏等操作都可以在浏览器中完成。

为什么选择 Steam Headless 容器方案
传统远程玩游戏的做法通常是在服务器上安装完整桌面环境,再通过 VNC、RDP 或远程桌面软件连接过去。这种方式虽然直观,但桌面环境本身会占用大量内存和 CPU,而且 VNC 的帧率通常不高,操作延迟明显,很难获得流畅的游戏体验。尤其是没有显示器的机器,还需要额外配置虚拟显示器,步骤繁琐。
Steam Headless 把 Steam 客户端运行在 Docker 容器里,直接利用显卡硬件编码,将游戏画面以流媒体方式发送到本地网络中的其他设备。容器内已经集成了 Web UI、noVNC、Steam 客户端以及相关调度脚本,启动后只需要打开浏览器即可管理 Steam 进程。对于家庭服务器、NAS 或长期开机的小主机来说,这种方式更省资源,也更容易迁移和备份。
当然,该方案也不是万能的。部分带反作弊机制的游戏可能在容器环境中无法正常启动,个别游戏需要物理显示器或特殊输入设备。此外,NVIDIA 显卡需要正确配置容器工具包,AMD 和 Intel 核显则需要映射渲染设备。只要前置工作做好,大多数单机和局域网联机游戏都能稳定运行。
安装 Docker 与显卡驱动准备
首先更新软件源并安装 Docker。Ubuntu 官方仓库中的 docker.io 和 docker-compose-plugin 已经可以满足基本需求,适合快速部署。安装完成后将当前用户加入 docker 组,这样执行容器命令时就不需要每次都加 sudo。
sudo apt update sudo apt install -y docker.io docker-compose-plugin sudo systemctl enable --now docker sudo usermod -aG docker $USER newgrp docker
显卡驱动是 Steam Headless 能否调用硬件编码的关键。如果使用 NVIDIA 显卡,建议安装官方驱动并重启系统,然后执行 nvidia-smi 确认驱动已经加载。对于容器环境,还需要安装 NVIDIA Container Toolkit,让 Docker 能够把 GPU 设备暴露给容器。
sudo apt install -y nvidia-driver-550 sudo reboot nvidia-smi sudo apt install -y nvidia-container-toolkit sudo systemctl restart docker
如果宿主机使用 Intel 或 AMD 核显,则不需要安装 NVIDIA Container Toolkit,但要确保内核驱动正常加载,并在创建容器时映射 /dev/dri 设备。可以通过 ls /dev/dri 查看是否存在 renderD128 等渲染节点。无论哪种显卡,都建议先在宿主机上确认驱动状态,再进入容器部署环节。
部署 Steam Headless 容器
部署方式推荐使用 Docker Compose,因为持久化目录、环境变量和设备映射可以集中管理,后续修改也更方便。镜像可以选择社区维护的 josh5/steam-headless,该镜像更新活跃,内置了 Web UI 和常用依赖。下面是一个典型配置示例。
services:
steam-headless:
image: josh5/steam-headless:latest
container_name: steam-headless
restart: unless-stopped
network_mode: host
privileged: true
environment:
- PUID=1000
- PGID=1000
- TZ=Asia/Shanghai
- DISPLAY=:0
volumes:
- /opt/steam-headless:/home/default
- /dev/dri:/dev/dri
devices:
- /dev/dri:/dev/dri
shm_size: "2gb"
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
配置中 network_mode: host 表示容器直接使用宿主机网络,这样 Web UI、Steam 远程畅玩以及 Sunshine 所需的端口都会自动暴露,省去逐一映射端口的麻烦。不过 host 网络在部分环境下可能与其他服务冲突,如果更习惯端口映射,也可以改为 bridge 模式并手动映射 8083、47984 到 47990 等端口。
/opt/steam-headless 是持久化目录,Steam 客户端、游戏库和配置都会保存在这里。升级容器或重建实例时,游戏文件不会丢失。shm_size 设置为 2GB 可以避免部分游戏因共享内存不足而崩溃。privileged: true 虽然不是最安全的选择,但能减少设备访问和权限问题,在家庭内网环境中通常可以接受。
如果不想使用 Compose,也可以用 docker run 命令启动。下面是一个等价的命令行示例,注意反斜杠用于换行,执行时需要保持完整。
docker run -d \ --name=steam-headless \ --network=host \ --privileged \ -e PUID=1000 \ -e PGID=1000 \ -e TZ=Asia/Shanghai \ -e DISPLAY=:0 \ -v /opt/steam-headless:/home/default \ -v /dev/dri:/dev/dri \ --device /dev/dri:/dev/dri \ --shm-size=2gb \ --gpus all \ josh5/steam-headless:latest
启动容器后,可以通过 docker logs -f steam-headless 查看日志,确认 Web UI 是否已经监听端口。如果日志中出现权限错误或 GPU 不可用信息,需要先返回显卡驱动部分检查配置。
访问 Web 界面并完成 Steam 登录
容器正常运行后,在局域网内任意设备的浏览器地址栏中输入服务器 IP 和端口 8083,例如 http://服务器IP:8083。首次访问时,如果页面提示证书或安全警告,可以暂时信任继续访问,因为容器默认使用自签名证书。进入 Web UI 后,可以看到 Steam 的启动、停止按钮,以及系统资源占用、日志输出等信息。
点击启动 Steam 后,Web UI 会调用容器内的 noVNC 提供一个远程桌面画面。第一次登录需要输入 Steam 账号和密码,如果账号开启了手机令牌,还需要完成两步验证。登录成功后建议勾选记住凭证,避免之后每次启动容器都要重新输入。由于 Steam 客户端认为自己在无头环境下运行,部分弹窗可能不会自动获得焦点,需要手动点击窗口内的确认按钮。
完成登录后,可以先在 Steam 设置中关闭不必要的启动项和商店视频,降低后台资源消耗。进入“远程畅玩”设置页面,确认远程游玩功能已经开启。如果后续准备使用 Sunshine 和 Moonlight 进行串流,也可以在这个阶段先完成游戏库下载和默认分辨率设置。
远程串流与常见故障排查
Steam Headless 通常配合两种串流方式使用。第一种是 Steam 自带的远程畅玩,它可以自动发现局域网内的其他设备,在客户端中直接启动游戏。第二种是 Sunshine 加 Moonlight,Sunshine 作为服务端运行在容器中,Moonlight 作为客户端运行在手机、电视或笔记本上,编码延迟更低,画质选项也更丰富。无论使用哪种方式,都需要保证防火墙放行相应端口。
sudo ufw allow 8083/tcp sudo ufw allow 47984:47990/tcp sudo ufw allow 47984:47990/udp sudo ufw allow 48010/tcp sudo ufw allow 48010/udp
如果远程画面出现黑屏,可以先检查容器内是否能识别显卡。执行 docker exec -it steam-headless nvidia-smi,如果提示找不到命令或设备,说明 GPU 没有正确映射。对于 Intel 和 AMD 显卡,则要确认 /dev/dri 是否已经挂载到容器内,并且运行 Steam 的用户对渲染设备有读权限。
游戏启动后立即崩溃,很多时候与共享内存不足有关。可以尝试将 shm_size 调整为 4GB 或更高,同时确认持久化目录所在磁盘有足够空间。若远程串流时出现明显卡顿,优先使用有线网络连接客户端,并将 Moonlight 或 Steam 的编码质量从“自动”调整为固定码率。网络条件允许的情况下,将分辨率控制在 1080p 或 1440p,比盲目上 4K 更容易获得稳定帧率。
还有一类问题是游戏窗口在 noVNC 中无法显示或分辨率锁定。此时可以进入容器环境的显示设置,检查 DISPLAY 是否为 :0,并确认虚拟显示器分辨率是否符合目标游戏要求。个别游戏需要安装额外的依赖库,可以查看容器日志中给出的提示,进入容器后手动补装。
UbuntuSteam HeadlessDocker修改时间:2026-09-23 18:18:36