Archived
Recommend systemd user lingering
This commit is contained in:
@@ -92,9 +92,15 @@ Recommended install uses npm plus systemd user services:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm install -g @jmfederico/pi-web
|
npm install -g @jmfederico/pi-web
|
||||||
|
|
||||||
|
# Recommended on servers: keep user services running after logout/reboot.
|
||||||
|
sudo loginctl enable-linger "$USER"
|
||||||
|
|
||||||
pi-web install
|
pi-web install
|
||||||
```
|
```
|
||||||
|
|
||||||
|
`loginctl enable-linger` is optional for local desktop use, but recommended on servers. It lets the user systemd manager start at boot and continue running after you log out, so Pi Web remains available without an active SSH/login session.
|
||||||
|
|
||||||
This writes and starts:
|
This writes and starts:
|
||||||
|
|
||||||
- `~/.config/systemd/user/pi-web-sessiond.service`
|
- `~/.config/systemd/user/pi-web-sessiond.service`
|
||||||
@@ -102,6 +108,12 @@ This writes and starts:
|
|||||||
|
|
||||||
The generated services run through `bash -lc` so they see a shell environment similar to running `pi` from your terminal.
|
The generated services run through `bash -lc` so they see a shell environment similar to running `pi` from your terminal.
|
||||||
|
|
||||||
|
To check whether lingering is enabled:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
loginctl show-user "$USER" -p Linger
|
||||||
|
```
|
||||||
|
|
||||||
Open <http://127.0.0.1:8504>.
|
Open <http://127.0.0.1:8504>.
|
||||||
|
|
||||||
Useful commands:
|
Useful commands:
|
||||||
@@ -236,6 +248,13 @@ Restart=no
|
|||||||
WantedBy=default.target
|
WantedBy=default.target
|
||||||
```
|
```
|
||||||
|
|
||||||
|
On servers, enable persistent user services so the user systemd manager starts at boot and remains running after logout:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo loginctl enable-linger "$USER"
|
||||||
|
loginctl show-user "$USER" -p Linger
|
||||||
|
```
|
||||||
|
|
||||||
After creating or changing units:
|
After creating or changing units:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
+32
-1
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
import { existsSync } from "node:fs";
|
import { existsSync } from "node:fs";
|
||||||
import { mkdir, rm, writeFile } from "node:fs/promises";
|
import { mkdir, rm, writeFile } from "node:fs/promises";
|
||||||
import { homedir } from "node:os";
|
import { homedir, userInfo } from "node:os";
|
||||||
import { dirname, join, resolve } from "node:path";
|
import { dirname, join, resolve } from "node:path";
|
||||||
import { spawnSync } from "node:child_process";
|
import { spawnSync } from "node:child_process";
|
||||||
import { defaultPiWebConfigPath, examplePiWebConfig } from "./config.js";
|
import { defaultPiWebConfigPath, examplePiWebConfig } from "./config.js";
|
||||||
@@ -32,6 +32,16 @@ function hasCommand(command: string): boolean {
|
|||||||
return capture("/usr/bin/env", ["bash", "-lc", `command -v ${command}`]).status === 0;
|
return capture("/usr/bin/env", ["bash", "-lc", `command -v ${command}`]).status === 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isLingerEnabled(): boolean | undefined {
|
||||||
|
if (!hasCommand("loginctl")) return undefined;
|
||||||
|
const result = capture("loginctl", ["show-user", userInfo().username, "-p", "Linger"]);
|
||||||
|
if (result.status !== 0) return undefined;
|
||||||
|
const value = result.stdout.trim();
|
||||||
|
if (value === "Linger=yes") return true;
|
||||||
|
if (value === "Linger=no") return false;
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
function parseInstallOptions(args: string[]): InstallOptions {
|
function parseInstallOptions(args: string[]): InstallOptions {
|
||||||
const options: InstallOptions = { host: "127.0.0.1", port: "8504" };
|
const options: InstallOptions = { host: "127.0.0.1", port: "8504" };
|
||||||
for (let i = 0; i < args.length; i += 1) {
|
for (let i = 0; i < args.length; i += 1) {
|
||||||
@@ -136,6 +146,16 @@ async function install(args: string[]): Promise<void> {
|
|||||||
console.log(`\nPi Web is installed and starting.`);
|
console.log(`\nPi Web is installed and starting.`);
|
||||||
console.log(`Config: ${configPath}`);
|
console.log(`Config: ${configPath}`);
|
||||||
console.log(`Open: http://${options.host === "0.0.0.0" ? "127.0.0.1" : options.host}:${options.port}`);
|
console.log(`Open: http://${options.host === "0.0.0.0" ? "127.0.0.1" : options.host}:${options.port}`);
|
||||||
|
|
||||||
|
const linger = isLingerEnabled();
|
||||||
|
if (linger === false) {
|
||||||
|
console.log("\nRecommended for server use: keep user services running after logout/reboot:");
|
||||||
|
console.log(` sudo loginctl enable-linger ${userInfo().username}`);
|
||||||
|
} else if (linger === undefined) {
|
||||||
|
console.log("\nRecommended for server use: enable systemd user lingering so services survive logout/reboot:");
|
||||||
|
console.log(` sudo loginctl enable-linger ${userInfo().username}`);
|
||||||
|
}
|
||||||
|
|
||||||
console.log("\nUseful commands:");
|
console.log("\nUseful commands:");
|
||||||
console.log(" pi-web status");
|
console.log(" pi-web status");
|
||||||
console.log(" pi-web logs");
|
console.log(" pi-web logs");
|
||||||
@@ -181,6 +201,17 @@ function doctor(): void {
|
|||||||
if (output !== "") console.log(` ${output.split("\n")[0] ?? ""}`);
|
if (output !== "") console.log(` ${output.split("\n")[0] ?? ""}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const linger = isLingerEnabled();
|
||||||
|
if (linger === true) {
|
||||||
|
console.log("✓ systemd user lingering enabled");
|
||||||
|
} else if (linger === false) {
|
||||||
|
console.log("✗ systemd user lingering disabled");
|
||||||
|
console.log(` Recommended on servers: sudo loginctl enable-linger ${userInfo().username}`);
|
||||||
|
} else {
|
||||||
|
console.log("? systemd user lingering unknown");
|
||||||
|
console.log(` Recommended on servers: sudo loginctl enable-linger ${userInfo().username}`);
|
||||||
|
}
|
||||||
|
|
||||||
if (failed) {
|
if (failed) {
|
||||||
console.log("\nIf a command works in your terminal but fails here, make sure your bash login files set PATH the same way.");
|
console.log("\nIf a command works in your terminal but fails here, make sure your bash login files set PATH the same way.");
|
||||||
process.exitCode = 1;
|
process.exitCode = 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user