---
title: How to make the Steam Machine a Server
date: "2026-08-17"
updated: ["2026-10-14"]
description: "How to backup files to the Valve Steam Machine."
kind: essay
draft: false
---

![Picture of Valve Steam Machine](./steam-machine.webp)

The Valve Steam Machine is a gaming console that can be retro-fitted to be a personal mini-server. The machine has a custom x86_64 CPU with 6 cores and a TDP of 30W. For memory it has 16GB DDR5 system memory and 8GB DDR6 video memory. The retail prices for a Valve Steam Machine do not make a compelling offer currently[^price]. This is not to say that the platform and the engineering don't have merits.The form-factor being an approximately 6 inch cube makes it one of the smallest personal computers or gaming console you can purchase on the market today. Another more important fact for making the Steam Machine a personal mini-server, is Valve choosing to build it's operating system and software stack on top of Arch Linux. Valve made the conscious choice as well to make the Steam Machine architecture open. 

[^price]: See [DRAM prices](https://pcpartpicker.com/trends/price/memory/)

When I purchased the Steam Machine, I intended to use it as a mini-server primarily and a gaming console second[^swear]. This would allow me to move my services off virtual private servers and onto hardware I own. Below I detail the steps I took to set up the Valve Steam Machine to be a mini-server.

[^swear]: I swear!

## 1. First boot: firmware, CEC, and getting a terminal


For the process of turning the steam machine into a server, this is the only part that requires a display out! The first setting to change from the default configuration is to turn off the HDMI-CEC poweroff feature, where the steam machine turns off with a display turn off. Good for power saving, bad for always on display. We then need to switch into Desktop Mode from Big Picture to access a terminal Emulator Konsole. Once in Desktop Mode we can open the Konsole application to input commands (you can use the app launcher in the bottom left and search for the app in the search bar).

## 2. Get SSH access to the machine

To start the process of making the steam machine a server, we should let it be interacted with in a headless mode. To do this we can enable sshd. Initially SteamOS's user `deck` has no password so we must set that ourselves.

```bash
deck$ passwd
deck$ sudo systemctl enable --now sshd
deck$ ip addr | grep inet
```

## 3. Install Tailscale

To access the steam machine while not on the local network and make it more convenient to access, we can use Tailscale; a Wireguard manager. To install Tailscale we use a community script that installs the binaries into writable locations as the steam machine has a read-only root filesystem. The community script is available from a github repo. If Tailscale is installed correctly and has been connected to your Tailscale account, you should now have a ip address, this ip address is then usable from any of your other devices that has Tailscale installed and is on the same VPN.

```bash
deck$ curl -fsSL https://tailscale.com/install.sh | sh
deck$ git clone https://github.com/tailscale-dev/deck-tailscale.git ~/deck-tailscale
deck$ sudo -i

root# export TERM=xterm
root# cd ~deck/deck-tailscale
root# bash tailscale.sh
root# source /etc/profile.d/tailscale.sh
root# tailscale update
root# exit

deck$ tailscale ip -4
  # e.g. 100.64.0.10 — note it down
```

## 4. Harden SSH: keys only, no passwords

To add an additional layer of security, and make it easier to access the steam machine, we will create a ssh config and keys. Most of the steps in this section occur on the client machine `client$`. The steps in order are to create a SSH key that can be copied to the steam machine, requiring the last use of the passwd that we previously set for `sudo` as a method to connect to the machine. Then we add the steam machine to the ssh config so that we can alias the machine and use the correct SSH key every time. Finally we turn off `PasswordAuthentication` on the steam machine and restart sshd.

```bash
client$ tailscale status
  # find the machine's <tailscale-ip> address

client$ ssh-keygen -t ed25519 -f ~/.ssh/<sshkey-name>
  # skip if you already have a key

client$ ssh-copy-id deck@<tailscale-ip>
  # uses the password one last time

client$ cat >> ~/.ssh/config << 'EOF'
Host steam-machine
    # machine's Tailscale IP (from `tailscale status`)
    IdentityFile ~/.ssh/<sshkey-name>
    HostName <tailscale-ip>
    User deck
EOF
client$ ssh steam-machine
  # prove it works before proceeding

deck$ sudo vim /etc/ssh/sshd_config
  # PasswordAuthentication no
  # KbdInteractiveAuthentication no

deck$ sudo systemctl restart sshd
```

## 5. Make sure the machine won't sleep

To make sure that steam machine doesn't suspend when we are idle, I've taken the liberty to disable most of the the systemd services that relate to power mode sleep actions.

```bash
root# systemctl status sleep.target
root# loginctl show-logind | grep -E 'IdleAction|IdleActionUSec|HandleLid'
root# systemd-analyze cat-config systemd/logind.conf | grep -E '^(IdleAction|IdleActionSec|HandleLid)'
root# systemd-inhibit --list
root# exit
```

## 6. Install Nix, then SFTPGo

To add software to the steam machine, I've decided to use the Nix package management system. A benefit of this approach is that packages install in `/nix` and the user's home rather than in the read-only sections of the device. There are a few flags that matter to how I want to install Nix but aren't strictly necessary for getting things working like nix-command and flakes. We will need to allow unfree packages to install `sftpgo` into the user profile.

```bash
deck$ findmnt /nix
deck$ sudo chown -R $USER:$USER /nix
deck$ sh <(curl -L https://nixos.org/nix/install) --no-daemon
deck$ . ~/.nix-profile/etc/profile.d/nix.sh
deck$ echo '. ~/.nix-profile/etc/profile.d/nix.sh' >> ~/.bashrc
deck$ nix-channel --update nixpkgs
deck$ mkdir -p ~/.config/nix
deck$ echo "experimental-features = nix-command flakes" >> ~/.config/nix/nix.conf
deck$ mkdir -p ~/.config/nixpkgs
deck$ vim ~/.config/nixpkgs/config.nix
  # allowUnfree = true

deck$ export NIXPKGS_ALLOW_UNFREE=1
deck$ nix profile add nixpkgs#sftpgo --impure
```

## 7. Configure SFTPGo and test-run it

Once `sftpgo` is installed we should make the associated folders for its operation. Then generate the configuration files for the service, and test it out and set up the admin user account through connecting to the HTTP server over tailscale.

```bash
deck$ mkdir -p ~/.local/share/sftpgo/{data,backups} ~/.config/sftpgo
deck$ tailscale ip -4
  # needed again for §8's unit file

deck$ sftpgo gen config ~/.config/sftpgo
deck$ STORE_SHARE=$(dirname $(dirname $(readlink -f $(which sftpgo))))/share/sftpgo
deck$ cp -r "$STORE_SHARE/templates" "$STORE_SHARE/static" ~/.config/sftpgo/
deck$ sftpgo serve -c ~/.config/sftpgo
deck$ tail -30 ~/.config/sftpgo/sftpgo.log

deck$ sudo reboot
```

## 8. Make SFTPGo survive reboots

To get SFTPGo working nicely on the steam machine requires a bit of finagling. SteamOS requires us to create the data folder in the user's home directory. So we will need to run as a systemd *user* service and bind to sftpd on port `2022` and the web admin port on `8080` of the tailscale IP. We also should turn on `enable-linger` so the user services start at boot.

```bash
root# mkdir -p /home/deck/.local/share/sftpgo/data
root# exit

deck$ tailscale ip -4                        # for <tailscale ip>
deck$ mkdir -p ~/.config/systemd/user
deck$ cat > ~/.config/systemd/user/sftpgo.service << 'EOF'
[Unit]
Description=SFTPGo
After=network-online.target tailscaled.service
Wants=network-online.target

[Service]
Environment=SFTPGO_SFTPD__BINDINGS__0__ADDRESS=<tailscale ip>
Environment=SFTPGO_SFTPD__BINDINGS__0__PORT=2022
Environment=SFTPGO_HTTPD__BINDINGS__0__ADDRESS=<tailscale ip>
Environment=SFTPGO_HTTPD__BINDINGS__0__PORT=8080
ExecStart=%h/.nix-profile/bin/sftpgo serve -c %h/.config/sftpgo
Restart=on-failure
RestartSec=5

[Install]
WantedBy=default.target
EOF
deck$ systemctl --user daemon-reload
deck$ systemctl --user enable --now sftpgo
deck$ sudo loginctl enable-linger deck
```
