mirror of
https://github.com/oqyude/nixos.git
synced 2026-10-10 05:55:24 +03:00
vtimeline added and formatted
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
xlib,
|
||||
...
|
||||
}:
|
||||
|
||||
# Veeam Timeline View — static frontend + REST API, both served by a
|
||||
# single Node.js/Express process. nginx reverse-proxies the entire
|
||||
# vtimeline.zeroq.su vhost to the local listener (see the vhost in
|
||||
# modules/server/nginx.nix — no `root`, no `try_files`).
|
||||
#
|
||||
# API surface (server.js):
|
||||
# GET /api/uploads list uploaded JSONs
|
||||
# POST /api/uploads upload (raw JSON or {name, content}, ≤ 5 MB)
|
||||
# GET /api/uploads/:name fetch parsed
|
||||
# DELETE /api/uploads/:name delete
|
||||
#
|
||||
# Auth: delegated to Authelia at the nginx layer (`auth_request
|
||||
# /authelia` on the vhost). The API itself trusts whoever reaches it —
|
||||
# the only ingress is the same-origin nginx proxy, so the wide-open
|
||||
# CORS header in server.js is a no-op in practice.
|
||||
#
|
||||
# Storage: /home/oqyude/External/Git/VeeamTimelineView/
|
||||
# ├── public_html/ static frontend (read-only at runtime)
|
||||
# ├── server.js Express app
|
||||
# ├── node_modules/ installed deps (express + transitive)
|
||||
# └── uploads/ persistent JSON uploads (read+write)
|
||||
#
|
||||
# The repo lives on the External ext4 drive (fstab). The service gates
|
||||
# on home-oqyude-External.mount so it never starts against an empty
|
||||
# directory after a cold boot without the drive plugged in.
|
||||
let
|
||||
user = xlib.device.username;
|
||||
group = "users";
|
||||
repo = "/home/oqyude/External/Git/VeeamTimelineView";
|
||||
port = 8000;
|
||||
node = pkgs.nodejs_22;
|
||||
in
|
||||
{
|
||||
# systemPackages so /run/current-system/sw/bin/node exists for any
|
||||
# operator tooling (logs, ad-hoc npm scripts). The systemd unit
|
||||
# below references the absolute Nix-store path, so this is purely
|
||||
# for the CLI path.
|
||||
environment.systemPackages = [ node ];
|
||||
|
||||
# Bind-mount public_html into /var/lib. The current vhost proxies
|
||||
# all traffic to the node listener, so nginx itself does not need
|
||||
# this — kept for parity with the pre-API setup (so any future
|
||||
# static-only fallback or external inspection has a stable
|
||||
# /home-independent path). x-systemd.automount + nofail: a missing
|
||||
# /home/oqyude/External only surfaces as a per-request 404, never a
|
||||
# boot failure.
|
||||
systemd.mounts = [
|
||||
(xlib.helpers.mkSystemdBind {
|
||||
what = "${repo}/public_html";
|
||||
where = "/var/lib/vtimeline";
|
||||
})
|
||||
];
|
||||
systemd.tmpfiles.rules = [
|
||||
(xlib.helpers.mkTmpfile "d" "/var/lib/vtimeline" "0755" "nginx" "nginx")
|
||||
];
|
||||
|
||||
systemd.services.vtimeline-api = {
|
||||
description = "Veeam Timeline View API (Node.js + Express)";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
after = [
|
||||
"network-online.target"
|
||||
"home-oqyude-External.mount"
|
||||
];
|
||||
wants = [ "network-online.target" ];
|
||||
requires = [ "home-oqyude-External.mount" ];
|
||||
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
User = user;
|
||||
Group = group;
|
||||
WorkingDirectory = repo;
|
||||
ExecStart = "${node}/bin/node ${repo}/server.js";
|
||||
Environment = "PORT=${toString port}";
|
||||
|
||||
Restart = "on-failure";
|
||||
RestartSec = "5s";
|
||||
|
||||
# Sandbox. Server.js only needs to read public_html/ +
|
||||
# node_modules/ and to read-write uploads/. ReadWritePaths
|
||||
# lifts the ProtectHome/ProtectSystem write protection for
|
||||
# uploads/ only; everywhere else stays read-only.
|
||||
NoNewPrivileges = true;
|
||||
PrivateTmp = true;
|
||||
ProtectSystem = "strict";
|
||||
ProtectHome = "read-only";
|
||||
ReadWritePaths = [ "${repo}/uploads" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user