You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/posts/systemd.md
+71-23Lines changed: 71 additions & 23 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -11,6 +11,9 @@ You've learned how to write Bash scripts and run Python code. But running a scri
11
11
12
12
To run something automatically when your Deck boots, we don't put it in a Startup folder like Windows. Instead, we use Linux's master service manager: **systemd**.
13
13
14
+
> [!NOTE]
15
+
> If you installed a tool through Home Manager or Linuxbrew, prefer their built-in service workflows first. Those approaches are more reproducible and easier to maintain. This chapter covers the manual `systemd` route for one-off scripts that are *not* managed by those tools.
16
+
14
17
## What is systemd?
15
18
16
19
`systemd` is the central nervous system of SteamOS (and almost all modern Linux systems). It controls what starts up, what shuts down, and what runs in the background.
@@ -22,47 +25,65 @@ When you install an app that runs in the background (like *EmuDeck's* background
22
25
23
26
## Creating Your First Service
24
27
25
-
Let's imagine you wrote a Python script called `my-cool-script.py` and saved it in your `Documents` folder. You want it to run quietly in the background as soon as you turn on your Deck.
28
+
Let's use a real example: running **Copyparty** as a personal file server in the background, so your Deck is always ready to receive or share files on your local network.
29
+
30
+
If Copyparty came from Home Manager or Linuxbrew, configure the service there instead of creating a manual unit. The manual unit below is for the unmanaged case where you installed it yourself and want a straightforward autostart.
26
31
27
32
> [!WARNING]
28
33
> You should never run custom scripts as the `root` user unless absolutely necessary. We will use `systemctl --user`, which safely limits your background script to only control things *your* user profile can touch.
29
34
30
-
### 1. Make the Service File
35
+
### 1. Create the Service File
31
36
32
37
`systemd` looks for your custom background services in a specific hidden folder:
33
-
`/home/deck/.config/systemd/user/`
38
+
`~/.config/systemd/user/`
34
39
35
-
Open Konsole and create your new service file, which must end in `.service`.
Because Copyparty is a Python package, we can use `uvx` — which you already have from the Python chapter — to run it directly without a separate install step. This keeps the unit file short and means `systemd` doesn't need to know anything about Python paths or virtual environments.
41
49
42
-
Every service file needs three basic sections: `[Unit]`, `[Service]`, and `[Install]`.
-`After=network.target` means the script will wait until your Deck connects to Wi-Fi before it runs.
61
-
-`ExecStart` is the exact command you would normally type in the terminal. **Important:** You must use full paths in `systemd` files (e.g., `/usr/bin/python3` instead of just `python3`).
62
-
-`Restart=always` tells the system: "If this script crashes, wait 10 seconds and start it again automatically."
63
-
-`WantedBy=default.target` makes sure it actually starts when you log in.
67
+
> [!NOTE]
68
+
> If you installed Copyparty through Nix instead of `uvx`, swap the `ExecStart` line for:
69
+
> ```
70
+
> ExecStart=/nix/var/nix/profiles/default/bin/nix run nixpkgs#copyparty
71
+
> ```
72
+
> The [upstream unit file](https://raw.githubusercontent.com/9001/copyparty/refs/heads/hovudstraum/contrib/systemd/copyparty.service) is available as a reference, but it targets a system-wide install and needs significant adaptation for a user service — the version above is all you need.
73
+
74
+
**What these lines mean:**
75
+
- `After=network-online.target` — wait for the network to be ready before starting. For a user service, the system will already have brought the network up by the time this runs, but the `After=` line adds an explicit ordering guarantee.
76
+
- `WorkingDirectory` — Copyparty serves the current working directory by default, so setting this to your `Sync` folder is all you need. No volume flags required.
77
+
- `ExecStart` — `uvx` fetches and runs Copyparty from PyPI in an isolated environment. The web UI is available at `http://<your-deck-ip>:3923` from any device on your network.
78
+
- `Restart=always` — if Copyparty crashes, wait 10 seconds and restart it automatically.
79
+
- `WantedBy=default.target` — the correct target for user services (not the system-wide `multi-user.target`).
80
+
81
+
Press `Ctrl+O` then `Enter` to save, then `Ctrl+X` to exit.
64
82
65
-
Press `Ctrl+O` then `Enter` to save, and `Ctrl+X` to exit out of `nano`.
83
+
Then tell systemd about the new file:
84
+
```bash
85
+
systemctl --user daemon-reload
86
+
```
66
87
67
88
## How to Control Your Service
68
89
@@ -72,27 +93,54 @@ Because we put our service in the `user/` folder, we must add the `--user` flag
72
93
73
94
### Start the script right now:
74
95
```bash
75
-
systemctl --user start my-cool-script.service
96
+
systemctl --user start copyparty.service
76
97
```
77
98
78
99
### Enable it to start automatically on every boot:
79
100
```bash
80
-
systemctl --user enablemy-cool-script.service
101
+
systemctl --user enablecopyparty.service
81
102
```
82
103
83
104
### Stop the script:
84
105
```bash
85
-
systemctl --user stop my-cool-script.service
106
+
systemctl --user stop copyparty.service
86
107
```
87
108
88
109
### Check if it's running (The ultimate troubleshooting tool):
89
110
```bash
90
-
systemctl --user status my-cool-script.service
111
+
systemctl --user status copyparty.service
112
+
```
113
+
The `status` command shows whether Copyparty is running and prints the last few lines of its output. If your file server is not reachable, this is the very first command you should run.
114
+
115
+
### See the full log output:
116
+
```bash
117
+
journalctl --user -u copyparty.service
91
118
```
92
-
The `status` command will even print out the last few lines of `print()` statements or errors your script spit out. If your background app isn't working, this is the very first command you should run!
119
+
This streams the complete journal for Copyparty. When it starts successfully, you should see a QR code and URL appear in the logs. If it fails, the error message here will be your best clue to what went wrong.
120
+
121
+
> [!TIP]
122
+
> Add `-f` to follow the log live: `journalctl --user -u copyparty.service -f`. Press `Ctrl+C` to stop following.
123
+
124
+
## Surviving Game Mode: Enable Lingering
125
+
126
+
There's one gotcha you should know about. By default, Linux only runs your `--user` services while you have an active login session (like Desktop Mode). When you switch back to Game Mode, the system may consider your desktop session "closed" and quietly kill all your background scripts.
127
+
128
+
The fix is a one-time command called `loginctl enable-linger`:
129
+
130
+
```bash
131
+
loginctl enable-linger deck
132
+
```
133
+
134
+
This tells `systemd`: "Keep this user's services running even when they don't have a desktop session open." After running this once, your services will stay alive in the background whether you're in Desktop Mode, Game Mode, or even if you never open the desktop at all.
135
+
136
+
> [!TIP]
137
+
> You only need to run `loginctl enable-linger` once — it's permanent. You can verify it's active with `loginctl show-user deck | grep Linger`, which should print `Linger=yes`. Run `loginctl disable-linger deck` to revert if you change your mind.
138
+
139
+
> [!CAUTION]
140
+
> Background services consume CPU and battery even while you're gaming. If you notice shorter battery life, a runaway service may be the culprit — check with `systemctl --user status copyparty.service`. Also keep in mind that when your Deck goes to **sleep**, all services are suspended until it wakes back up. If your service needs to do work on a strict schedule, those intervals will slip during sleep.
93
141
94
142
## The Power of Auto-Start
95
143
96
-
You just leveled up. Turning scripts into resilient, auto-starting `systemd` services is a core Linux skill. This ensures that your customizations survive reboots, seamlessly blending into the console-like experience of Game Mode.
144
+
You just leveled up. Turning scripts into resilient, auto-starting `systemd` services is a core Linux skill for unmanaged, one-off scripts. With lingering enabled, your customizations survive reboots*and* mode switches, seamlessly running in the background whether you're gaming or tinkering.
0 commit comments