DEV Community

Pascal Matthiesen
Pascal Matthiesen

Posted on

My Wife’s Steam Deck Is a Server Now. She Doesn’t Know Yet. 🫠

Hey tech adventurers! 👋

What if the hardware you already own could become part of your homelab?

That spare Linux box. An old Mac. A mini PC sitting under the TV.

Or, in my case, my wife’s Steam Deck. 😅

She can’t play 24/7, so when the Deck is idle, I figured its CPU might as well do something useful.

So I installed BarkVisor on SteamOS and turned it into another Device in my Home. It can run VMs, join my other Mac and Linux machines, and even run small local AI models with Ollama.

And yes, it still plays games. I’m not that terrible of a husband.

This post is the “I actually did it on a Steam Deck” walkthrough: practical, step-by-step, and no kernel seminar.

The bigger idea, though, is simple:

You probably already have a machine that could run BarkVisor.

What you end up with 🍕

Role Machine Listens
Home (UI + control) Mac/Linux on the LAN :7777 HTTP, :7778 mTLS
Device (this tutorial) Steam Deck (or similar SteamOS / handheld Linux) :7777 API only, :7778 agent, Ollama :11434

Example LAN: Home 192.168.10.10, Deck 192.168.8.133.

You never open the Deck’s :7777 in a browser. Pair once. Then lives in BarkVisor.

Same class of machine: Steam Deck and Lenovo Legion Go–style handhelds running SteamOS / Arch-ish Linux. The unlock + pacman bits below are SteamOS / Deck-specific. Adjust paths (/home/deck) if your user isn’t deck.

1. Prep the Deck (Desktop Mode) 🛠️

Switch to Desktop Mode. Set a sudo password if you haven’t (passwd).

SteamOS root is tiny (~5GB). BarkVisor, models, and VM disks go under /home. Do not fill the root partition. Future-you will thank present-you.

Unlock the OS and trust SteamOS package keys (once — when pacman complains about unknown trust / GitLab CI Package Builder):

Click to expand: SteamOS unlock + pacman keys
sudo steamos-readonly disable
sudo pacman-key --init
sudo pacman-key --populate archlinux
sudo pacman-key --populate holo
sudo pacman-key --lsign-key 889B5EBDDD505A683621900DAF1D2199EF0A3CCF
Enter fullscreen mode Exit fullscreen mode

Install the VM stack. Arch/SteamOS splits QEMU — qemu-base alone is not enough for BarkVisor’s virtio-gpu-pci, and cloud-init needs mkisofs from cdrtools:

Click to expand: QEMU + OVMF + cdrtools + swtpm
sudo pacman -S qemu-base edk2-ovmf \
  qemu-hw-display-virtio-gpu qemu-hw-display-virtio-gpu-pci \
  cdrtools swtpm
Enter fullscreen mode Exit fullscreen mode

Sanity check (you want a line with virtio-gpu-pci and a writable /dev/kvm):

Click to expand: host sanity checks
command -v qemu-system-x86_64 qemu-img mkisofs
qemu-system-x86_64 -device help | grep virtio-gpu-pci
ls /usr/share/edk2/x64/OVMF_CODE.4m.fd
ls -l /dev/kvm
Enter fullscreen mode Exit fullscreen mode

2. Install BarkVisor agent only (no UI) 🐕

Do not pipe install.sh into sudo on SteamOS. Use the Linux tarball under home. Agent mode = no SPA on the Deck. The Deck is a worker, not a kiosk.

Current release at time of writing: 1.0.0-alpha.3 (check GitHub releases if you’re reading this from the future).

Click to expand: download + verify + install agent under ~/.local
VER=1.0.0-alpha.3   # or whatever current release is
PREFIX="$HOME/.local/opt/barkvisor"
mkdir -p "$PREFIX" "$HOME/.local/share/barkvisor" "$HOME/.local/bin" \
  "$HOME/.config/barkvisor" "$HOME/.config/systemd/user"

cd /tmp
curl -fL -O "https://github.com/pmdroid/barkvisor/releases/download/v${VER}/barkvisor-${VER}-linux-x86_64.tar.gz"
curl -fL -O "https://github.com/pmdroid/barkvisor/releases/download/v${VER}/barkvisor-${VER}-linux-x86_64.tar.gz.sha256"
sha256sum -c "barkvisor-${VER}-linux-x86_64.tar.gz.sha256"

tar -xzf "barkvisor-${VER}-linux-x86_64.tar.gz"
SRC="barkvisor-${VER}-linux-x86_64/root/usr/local"
install -m 0755 "$SRC/bin/barkvisor" "$PREFIX/bin/barkvisor"
ln -sfn barkvisor "$PREFIX/bin/barkvisor-agent"
cp -a "$SRC/lib/barkvisor" "$PREFIX/lib/"
# skip share/barkvisor/frontend — agent mode, no SPA
Enter fullscreen mode Exit fullscreen mode

CLI wrapper (sets the bundled Swift LD_LIBRARY_PATH — yes, Swift on a Steam Deck, we’re living deliciously):

Click to expand: ~/.local/bin/barkvisor wrapper + PATH
cat > "$HOME/.local/bin/barkvisor" << 'EOF'
#!/usr/bin/env bash
PREFIX="${HOME}/.local/opt/barkvisor"
export LD_LIBRARY_PATH="${PREFIX}/lib/barkvisor/swift:${PREFIX}/lib/barkvisor/compat${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
exec -a "$(basename "$0")" "${PREFIX}/bin/barkvisor" "$@"
EOF
chmod +x "$HOME/.local/bin/barkvisor"
ln -sfn barkvisor "$HOME/.local/bin/barkvisor-agent"

grep -q '.local/bin' ~/.bashrc || echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
export PATH="$HOME/.local/bin:$PATH"
Enter fullscreen mode Exit fullscreen mode

Env + user systemd service (data on home, no frontend dir):

Click to expand: barkvisor.env + barkvisor-agent.service
cat > "$HOME/.config/barkvisor/barkvisor.env" << EOF
BARKVISOR_PORT=7777
BARKVISOR_DATA_DIR=$HOME/.local/share/barkvisor
BARKVISOR_SOCKET_DIR=$XDG_RUNTIME_DIR/barkvisor
HOME=$HOME
LD_LIBRARY_PATH=$HOME/.local/opt/barkvisor/lib/barkvisor/swift:$HOME/.local/opt/barkvisor/lib/barkvisor/compat
EOF

cat > "$HOME/.config/systemd/user/barkvisor-agent.service" << EOF
[Unit]
Description=BarkVisor API-only Device daemon
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
WorkingDirectory=$HOME/.local/share/barkvisor
EnvironmentFile=-$HOME/.config/barkvisor/barkvisor.env
ExecStart=$HOME/.local/opt/barkvisor/bin/barkvisor-agent
Restart=on-failure
RestartSec=3
TimeoutStopSec=8
KillMode=mixed
RuntimeDirectory=barkvisor
LimitNOFILE=65536

[Install]
WantedBy=default.target
EOF

systemctl --user daemon-reload
systemctl --user enable --now barkvisor-agent.service
curl -sS http://127.0.0.1:7777/api/health
barkvisor-agent doctor
Enter fullscreen mode Exit fullscreen mode

Health should be "status":"ok". GET http://127.0.0.1:7777/ returning JSON 404 is correct for agent-only. You’re not broken. You’re disciplined.

SteamOS / Desktop Mode note: Desktop Mode already has a user session, so the service starts with that session. It will not start in Game Mode unless you enable lingering (loginctl enable-linger deck, needs root).

3. Pair the Deck to Home 🔗

On Home (the machine that already finished BarkVisor setup):

  1. Open http://<home-ip>:7777
  2. Settings → Pairing → Add a Device
  3. Pick the LAN address the Deck can reach (e.g. 192.168.10.10)
  4. Copy the full offer: barkvisor://pair/v1?code=…&host=…&port=7777&agentPort=7778&hostId=…&fp=…

The short printed code is not enough. Ask me how I know. 😅

On the Deck, with the agent already up:

Click to expand: join with full barkvisor:// offer
barkvisor-agent join --code 'barkvisor://pair/v1?code=…&host=192.168.10.10&port=7777&agentPort=7778&hostId=…&fp=…'
Enter fullscreen mode Exit fullscreen mode

Or set BARKVISOR_JOIN_CODE in barkvisor.env before first start only.

With a current build, Home should hop immediately. Refresh Home: the Deck appears reachable, workload counts populate. Join talks HTTP to Home :7777; ongoing control is mTLS to the Deck :7778.

Confirm on the Deck:

Click to expand: confirm 7777 + 7778 listening
ss -ltn | grep -E '7777|7778'
# LISTEN 0.0.0.0:7777 and 0.0.0.0:7778
Enter fullscreen mode Exit fullscreen mode

4. Ollama on the Deck (optional) 🧠

Want Home’s Models UI to point at the handheld? Keep Ollama under ~/.local too — not /usr/local.

Click to expand: install Ollama under ~/.local
mkdir -p ~/.local ~/.ollama/models
curl -fsSL https://ollama.com/download/ollama-linux-amd64.tar.zst \
  | tar --zstd -xf - -C ~/.local
Enter fullscreen mode Exit fullscreen mode

Listen on all interfaces so Home and guest VMs can reach it. Example user unit knobs:

Click to expand: ollama.service env hints + start
# ~/.config/systemd/user/ollama.service
# Environment=OLLAMA_HOST=0.0.0.0:11434
# Environment=OLLAMA_MODELS=/home/deck/.ollama/models
# Environment=OLLAMA_IGPU_ENABLE=1
# ExecStart=/home/deck/.local/bin/ollama serve

systemctl --user enable --now ollama.service
curl -sS http://127.0.0.1:11434/api/version
curl -sS http://192.168.8.133:11434/api/version   # use your Deck LAN IP
ollama pull llama3.2   # example
Enter fullscreen mode Exit fullscreen mode

Steam Deck iGPU is ignored unless OLLAMA_IGPU_ENABLE=1. Then from Home: Settings / Models pointed at http://<deck-ip>:11434. Guest VMs on NAT see the Deck as 10.0.2.2:11434.

5. First Ubuntu VM from Home 🚀

On Home, with the Deck selected (or Create VM → this Device):

  1. Images — download Ubuntu 24.04 LTS (or 26.04) cloud image for x86_64. Wait until status is ready.
  2. Create VM / Ubuntu Server template.
  3. Place it on the steamdeck Device.
  4. Disk 16–64 GB; NAT is enough.
  5. Create, wait until provisioning finishes (clone + cloud-init ISO).
  6. Start.

NAT SSH: add a port forward (e.g. host 2222 → guest 22) on that VM, then from your laptop:

ssh -p 2222 ubuntu@192.168.8.133
Enter fullscreen mode Exit fullscreen mode

(Guest default user is ubuntu if you used the Ubuntu template. Swap in your Deck’s LAN IP.)

6. Everyday commands (on the Deck) 🧰

Click to expand: status, logs, doctor, disk usage
systemctl --user status barkvisor-agent ollama
journalctl --user -u barkvisor-agent -f
barkvisor-agent doctor

# disks / images live here
du -sh ~/.local/share/barkvisor/{disks,images,efivars}
Enter fullscreen mode Exit fullscreen mode

Home is the UI: VMs, VNC, serial, images, pairing. The Deck just works (or complains in journalctl).

Good at / not great at ⚖️

Good: extra QEMU capacity on the LAN. Ollama on the Deck iGPU (~16GB visible VRAM on a Z2 Go-class machine). Agent-only so you’re not burning cycles on a SPA nobody will open.

If something looks wrong 🧯

Symptom Check
Home: TLS handshake failed :7778 up; join completed; restart barkvisor-agent once if you’re on an older build
virtio-gpu-pci is not a valid device pacman -S qemu-hw-display-virtio-gpu qemu-hw-display-virtio-gpu-pci
mkisofs / genisoimage not found pacman -S cdrtools
BdsDxe no bootable option Cloud clone must leave GPT EFI PART at LBA 1; never run sgdisk on a .qcow2 file
pacman “unknown trust” pacman-key --lsign-key 889B5EBDDD505A683621900DAF1D2199EF0A3CCF
Ollama only on localhost OLLAMA_HOST=0.0.0.0:11434 and restart the user unit

Closing / pizza 🍕
Steam Deck as a headless BarkVisor Device: agent tarball in $HOME, SteamOS QEMU plus virtio-gpu and cdrtools, pair with a full barkvisor:// offer, optional Ollama on 0.0.0.0:11434. Control everything from Home on the LAN. The Deck just runs VMs and models.

Was this a responsible use of a gaming handheld? Debatable. Does it make my LAN slightly more overbuilt? Absolutely. Built with ❤️ and questionable infrastructure decisions.

P.S. Don’t want to click through every step yourself? Paste this post to your agent. They’ll have no problem doing it. 🤖

More: barkvisor.dev · github.com/pmdroid/barkvisor

Top comments (0)