{"slug": "my-wifes-steam-deck-is-a-server-now-she-doesnt-know-yet", "title": "My Wife’s Steam Deck Is a Server Now. She Doesn’t Know Yet. 🫠", "summary": "A developer has turned a Steam Deck into a server node for the BarkVisor homelab platform, enabling it to run VMs and local AI models via Ollama while remaining a gaming device. The walkthrough details installing BarkVisor on SteamOS, including unlocking the OS, installing QEMU components, and setting up agent mode. The project demonstrates repurposing idle handheld hardware for distributed computing.", "body_md": "Hey tech adventurers! 👋\n\nWhat if the hardware you already own could become part of your homelab?\n\nThat spare Linux box. An old Mac. A mini PC sitting under the TV.\n\nOr, in my case, my wife’s Steam Deck. 😅\n\nShe can’t play 24/7, so when the Deck is idle, I figured its CPU might as well do something useful.\n\nSo 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.\n\nAnd yes, it still plays games. I’m not that terrible of a husband.\n\nThis post is the “I actually did it on a Steam Deck” walkthrough: practical, step-by-step, and no kernel seminar.\n\nThe bigger idea, though, is simple:\n\nYou probably already have a machine that could run BarkVisor.\n\n| Role | Machine | Listens | \n|---|---|---|\n| **Home** (UI + control) | Mac/Linux on the LAN | `:7777` HTTP,`:7778` mTLS | \n| **Device** (this tutorial) | Steam Deck (or similar SteamOS / handheld Linux) | `:7777` API only,`:7778` agent, Ollama`:11434` | \n\nExample LAN: Home `192.168.10.10`, Deck `192.168.8.133`.\n\nYou **never** open the Deck’s `:7777` in a browser. Pair once. Then lives in BarkVisor.\n\nSame 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`.\n\nSwitch to **Desktop Mode**. Set a sudo password if you haven’t (`passwd`).\n\nSteamOS root is tiny (~5GB). BarkVisor, models, and VM disks go under **`/home`**. Do not fill the root partition. Future-you will thank present-you.\n\nUnlock the OS and trust SteamOS package keys (once — when `pacman` complains about unknown trust / GitLab CI Package Builder):\n\n```\nsudo steamos-readonly disable\nsudo pacman-key --init\nsudo pacman-key --populate archlinux\nsudo pacman-key --populate holo\nsudo pacman-key --lsign-key 889B5EBDDD505A683621900DAF1D2199EF0A3CCF\n```\n\nInstall 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`:\n\n```\nsudo pacman -S qemu-base edk2-ovmf \\\n  qemu-hw-display-virtio-gpu qemu-hw-display-virtio-gpu-pci \\\n  cdrtools swtpm\n```\n\nSanity check (you want a line with `virtio-gpu-pci` and a writable `/dev/kvm`):\n\n```\ncommand -v qemu-system-x86_64 qemu-img mkisofs\nqemu-system-x86_64 -device help | grep virtio-gpu-pci\nls /usr/share/edk2/x64/OVMF_CODE.4m.fd\nls -l /dev/kvm\n```\n\n**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.\n\nCurrent release at time of writing: **`1.0.0-alpha.3`** (check [GitHub releases](https://github.com/pmdroid/barkvisor/releases) if you’re reading this from the future).\n\n```\nVER=1.0.0-alpha.3   # or whatever current release is\nPREFIX=\"$HOME/.local/opt/barkvisor\"\nmkdir -p \"$PREFIX\" \"$HOME/.local/share/barkvisor\" \"$HOME/.local/bin\" \\\n  \"$HOME/.config/barkvisor\" \"$HOME/.config/systemd/user\"\n\ncd /tmp\ncurl -fL -O \"https://github.com/pmdroid/barkvisor/releases/download/v${VER}/barkvisor-${VER}-linux-x86_64.tar.gz\"\ncurl -fL -O \"https://github.com/pmdroid/barkvisor/releases/download/v${VER}/barkvisor-${VER}-linux-x86_64.tar.gz.sha256\"\nsha256sum -c \"barkvisor-${VER}-linux-x86_64.tar.gz.sha256\"\n\ntar -xzf \"barkvisor-${VER}-linux-x86_64.tar.gz\"\nSRC=\"barkvisor-${VER}-linux-x86_64/root/usr/local\"\ninstall -m 0755 \"$SRC/bin/barkvisor\" \"$PREFIX/bin/barkvisor\"\nln -sfn barkvisor \"$PREFIX/bin/barkvisor-agent\"\ncp -a \"$SRC/lib/barkvisor\" \"$PREFIX/lib/\"\n# skip share/barkvisor/frontend — agent mode, no SPA\n```\n\nCLI wrapper (sets the bundled Swift `LD_LIBRARY_PATH` — yes, Swift on a Steam Deck, we’re living deliciously):\n\n``` bash\ncat > \"$HOME/.local/bin/barkvisor\" << 'EOF'\n#!/usr/bin/env bash\nPREFIX=\"${HOME}/.local/opt/barkvisor\"\nexport LD_LIBRARY_PATH=\"${PREFIX}/lib/barkvisor/swift:${PREFIX}/lib/barkvisor/compat${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}\"\nexec -a \"$(basename \"$0\")\" \"${PREFIX}/bin/barkvisor\" \"$@\"\nEOF\nchmod +x \"$HOME/.local/bin/barkvisor\"\nln -sfn barkvisor \"$HOME/.local/bin/barkvisor-agent\"\n\ngrep -q '.local/bin' ~/.bashrc || echo 'export PATH=\"$HOME/.local/bin:$PATH\"' >> ~/.bashrc\nexport PATH=\"$HOME/.local/bin:$PATH\"\n```\n\nEnv + user systemd service (data on home, no frontend dir):\n\nClick to expand: barkvisor.env + barkvisor-agent.service\n\n```\ncat > \"$HOME/.config/barkvisor/barkvisor.env\" << EOF\nBARKVISOR_PORT=7777\nBARKVISOR_DATA_DIR=$HOME/.local/share/barkvisor\nBARKVISOR_SOCKET_DIR=$XDG_RUNTIME_DIR/barkvisor\nHOME=$HOME\nLD_LIBRARY_PATH=$HOME/.local/opt/barkvisor/lib/barkvisor/swift:$HOME/.local/opt/barkvisor/lib/barkvisor/compat\nEOF\n\ncat > \"$HOME/.config/systemd/user/barkvisor-agent.service\" << EOF\n[Unit]\nDescription=BarkVisor API-only Device daemon\nAfter=network-online.target\nWants=network-online.target\n\n[Service]\nType=simple\nWorkingDirectory=$HOME/.local/share/barkvisor\nEnvironmentFile=-$HOME/.config/barkvisor/barkvisor.env\nExecStart=$HOME/.local/opt/barkvisor/bin/barkvisor-agent\nRestart=on-failure\nRestartSec=3\nTimeoutStopSec=8\nKillMode=mixed\nRuntimeDirectory=barkvisor\nLimitNOFILE=65536\n\n[Install]\nWantedBy=default.target\nEOF\n\nsystemctl --user daemon-reload\nsystemctl --user enable --now barkvisor-agent.service\ncurl -sS http://127.0.0.1:7777/api/health\nbarkvisor-agent doctor\n```\n\nHealth 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.\n\n**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).\n\nOn **Home** (the machine that already finished BarkVisor setup):\n\n`http://<home-ip>:7777`\n`192.168.10.10`)` barkvisor://pair/v1?code=…&host=…&port=7777&agentPort=7778&hostId=…&fp=…`\nThe short printed code is **not** enough. Ask me how I know. 😅\n\nOn the Deck, with the agent already up:\n\nClick to expand: join with full barkvisor:// offer\n\n```\nbarkvisor-agent join --code 'barkvisor://pair/v1?code=…&host=192.168.10.10&port=7777&agentPort=7778&hostId=…&fp=…'\n```\n\nOr set `BARKVISOR_JOIN_CODE` in `barkvisor.env` **before first start only**.\n\nWith 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`.\n\nConfirm on the Deck:\n\nClick to expand: confirm 7777 + 7778 listening\n\n```\nss -ltn | grep -E '7777|7778'\n# LISTEN 0.0.0.0:7777 and 0.0.0.0:7778\n```\n\nWant Home’s **Models** UI to point at the handheld? Keep Ollama under `~/.local` too — not `/usr/local`.\n\n```\nmkdir -p ~/.local ~/.ollama/models\ncurl -fsSL https://ollama.com/download/ollama-linux-amd64.tar.zst \\\n  | tar --zstd -xf - -C ~/.local\n```\n\nListen on **all interfaces** so Home and guest VMs can reach it. Example user unit knobs:\n\n```\n# ~/.config/systemd/user/ollama.service\n# Environment=OLLAMA_HOST=0.0.0.0:11434\n# Environment=OLLAMA_MODELS=/home/deck/.ollama/models\n# Environment=OLLAMA_IGPU_ENABLE=1\n# ExecStart=/home/deck/.local/bin/ollama serve\n\nsystemctl --user enable --now ollama.service\ncurl -sS http://127.0.0.1:11434/api/version\ncurl -sS http://192.168.8.133:11434/api/version   # use your Deck LAN IP\nollama pull llama3.2   # example\n```\n\nSteam 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`.\n\nOn Home, with the Deck selected (or **Create VM → this Device**):\n\nNAT SSH: add a port forward (e.g. host `2222` → guest `22`) on that VM, then from your laptop:\n\n```\nssh -p 2222 ubuntu@192.168.8.133\n```\n\n(Guest default user is `ubuntu` if you used the Ubuntu template. Swap in your Deck’s LAN IP.)\n\n```\nsystemctl --user status barkvisor-agent ollama\njournalctl --user -u barkvisor-agent -f\nbarkvisor-agent doctor\n\n# disks / images live here\ndu -sh ~/.local/share/barkvisor/{disks,images,efivars}\n```\n\nHome is the UI: VMs, VNC, serial, images, pairing. The Deck just works (or complains in `journalctl`).\n\n**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.\n\n| Symptom | Check | \n|---|---|\n| Home: TLS handshake failed | `:7778` up; join completed; restart`barkvisor-agent` once if you’re on an older build | \n| `virtio-gpu-pci` is not a valid device | `pacman -S qemu-hw-display-virtio-gpu qemu-hw-display-virtio-gpu-pci` | \n| `mkisofs` /`genisoimage` not found | `pacman -S cdrtools` | \n| BdsDxe no bootable option | Cloud clone must leave GPT EFI PART at LBA 1; never run `sgdisk` on a`.qcow2` file | \n| pacman “unknown trust” | `pacman-key --lsign-key 889B5EBDDD505A683621900DAF1D2199EF0A3CCF` | \n| Ollama only on localhost | `OLLAMA_HOST=0.0.0.0:11434` and restart the user unit | \n\nClosing / pizza 🍕\n\nSteam 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.\n\nWas this a responsible use of a gaming handheld? Debatable. Does it make my LAN slightly more overbuilt? Absolutely. Built with ❤️ and questionable infrastructure decisions.\n\nP.S. Don’t want to click through every step yourself? Paste this post to your agent. They’ll have no problem doing it. 🤖\n\nMore: barkvisor.dev · github.com/pmdroid/barkvisor", "url": "https://wpnews.pro/news/my-wifes-steam-deck-is-a-server-now-she-doesnt-know-yet", "canonical_source": "https://dev.to/pmdroid/my-wifes-steam-deck-is-a-server-now-she-doesnt-know-yet-288c", "published_at": "2026-09-07 22:45:01+00:00", "updated_at": "2026-09-07 23:00:46.875849+00:00", "lang": "en", "topics": ["developer-tools", "ai-infrastructure", "ai-tools"], "entities": ["Steam Deck", "BarkVisor", "SteamOS", "Ollama", "QEMU", "Arch Linux", "Lenovo Legion Go"], "alternates": {"html": "https://wpnews.pro/news/my-wifes-steam-deck-is-a-server-now-she-doesnt-know-yet", "markdown": "https://wpnews.pro/news/my-wifes-steam-deck-is-a-server-now-she-doesnt-know-yet.md", "text": "https://wpnews.pro/news/my-wifes-steam-deck-is-a-server-now-she-doesnt-know-yet.txt", "jsonld": "https://wpnews.pro/news/my-wifes-steam-deck-is-a-server-now-she-doesnt-know-yet.jsonld"}}