add nix flakes
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
|||||||
build/
|
build/
|
||||||
|
result
|
||||||
node_modules/
|
node_modules/
|
||||||
tsconfig.tsbuildinfo
|
tsconfig.tsbuildinfo
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import express from "express";
|
import express from "express";
|
||||||
import expressWs from "express-ws";
|
import expressWs from "express-ws";
|
||||||
|
import path from "path";
|
||||||
import { MediaPlayer } from "./MediaPlayer";
|
import { MediaPlayer } from "./MediaPlayer";
|
||||||
import { searchInvidious, fetchThumbnail } from "./InvidiousAPI";
|
import { searchInvidious, fetchThumbnail } from "./InvidiousAPI";
|
||||||
import { PlaylistItem } from './types';
|
import { PlaylistItem } from './types';
|
||||||
@@ -158,14 +159,14 @@ apiRouter.delete("/favorites", withErrorHandling(async (req, res) => {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
// Serve static files for React app (after building)
|
// Serve static files for React app (after building)
|
||||||
app.use(express.static("dist/frontend"));
|
app.use(express.static(path.join(__dirname, "../dist/frontend")));
|
||||||
|
|
||||||
// Mount API routes under /api
|
// Mount API routes under /api
|
||||||
app.use("/api", apiRouter);
|
app.use("/api", apiRouter);
|
||||||
|
|
||||||
// Serve React app for all other routes (client-side routing)
|
// Serve React app for all other routes (client-side routing)
|
||||||
app.get("*", (req, res) => {
|
app.get("*", (req, res) => {
|
||||||
res.sendFile("dist/frontend/index.html", { root: "." });
|
res.sendFile(path.join(__dirname, "../dist/frontend/index.html"));
|
||||||
});
|
});
|
||||||
|
|
||||||
const port = process.env.PORT || 3000;
|
const port = process.env.PORT || 3000;
|
||||||
|
|||||||
61
flake.lock
generated
Normal file
61
flake.lock
generated
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"flake-utils": {
|
||||||
|
"inputs": {
|
||||||
|
"systems": "systems"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1731533236,
|
||||||
|
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1740828860,
|
||||||
|
"narHash": "sha256-cjbHI+zUzK5CPsQZqMhE3npTyYFt9tJ3+ohcfaOF/WM=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "303bd8071377433a2d8f76e684ec773d70c5b642",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-utils": "flake-utils",
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"systems": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
||||||
201
flake.nix
Normal file
201
flake.nix
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
{
|
||||||
|
description = "NodeJS application with mpv, yt-dlp, and pulseaudio dependencies";
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
|
flake-utils.url = "github:numtide/flake-utils";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = { self, nixpkgs, flake-utils }:
|
||||||
|
let
|
||||||
|
# Define the NixOS module for the systemd service
|
||||||
|
nixosModule = { config, lib, pkgs, ... }:
|
||||||
|
let
|
||||||
|
cfg = config.services.queuecube;
|
||||||
|
in {
|
||||||
|
options.services.queuecube = {
|
||||||
|
enable = lib.mkEnableOption "QueueCube media player service";
|
||||||
|
|
||||||
|
port = lib.mkOption {
|
||||||
|
type = lib.types.port;
|
||||||
|
default = 3000;
|
||||||
|
description = "Port on which QueueCube will listen";
|
||||||
|
};
|
||||||
|
|
||||||
|
enable_video = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Enable video playback";
|
||||||
|
};
|
||||||
|
|
||||||
|
invidious = lib.mkOption {
|
||||||
|
type = lib.types.submodule {
|
||||||
|
options = {
|
||||||
|
enabled = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Enable Invidious";
|
||||||
|
};
|
||||||
|
|
||||||
|
url = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "http://invidious.nor";
|
||||||
|
description = "URL of the Invidious instance to use";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
user = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "queuecube";
|
||||||
|
description = "User account under which QueueCube runs";
|
||||||
|
};
|
||||||
|
|
||||||
|
group = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "queuecube";
|
||||||
|
description = "Group under which QueueCube runs";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
users.users.${cfg.user} = lib.mkIf (cfg.user == "queuecube") {
|
||||||
|
isSystemUser = true;
|
||||||
|
group = cfg.group;
|
||||||
|
description = "QueueCube service user";
|
||||||
|
home = "/var/lib/queuecube";
|
||||||
|
createHome = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
users.groups.${cfg.group} = lib.mkIf (cfg.group == "queuecube") {};
|
||||||
|
|
||||||
|
systemd.services.queuecube = {
|
||||||
|
description = "QueueCube media player service";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
after = [ "network.target" ];
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = "${self.packages.${pkgs.system}.queuecube}/bin/queuecube";
|
||||||
|
Restart = "on-failure";
|
||||||
|
User = cfg.user;
|
||||||
|
Group = cfg.group;
|
||||||
|
|
||||||
|
# Audio/Video access
|
||||||
|
SupplementaryGroups = [ "audio" "video" ];
|
||||||
|
|
||||||
|
# Allow access to X11 for mpv
|
||||||
|
Environment = [ "DISPLAY=:0" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
environment = {
|
||||||
|
PORT = toString cfg.port;
|
||||||
|
ENABLE_VIDEO = if cfg.enable_video then "1" else "0";
|
||||||
|
USE_INVIDIOUS = if cfg.invidious.enabled then "1" else "0";
|
||||||
|
INVIDIOUS_URL = cfg.invidious.url;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
flake-utils.lib.eachDefaultSystem (system:
|
||||||
|
let
|
||||||
|
pkgs = nixpkgs.legacyPackages.${system};
|
||||||
|
|
||||||
|
# Define the package using buildNpmPackage
|
||||||
|
queuecube = pkgs.buildNpmPackage {
|
||||||
|
pname = "queuecube";
|
||||||
|
version = "0.1.0";
|
||||||
|
|
||||||
|
src = ./.;
|
||||||
|
|
||||||
|
# Skip the standard buildPhase and provide our own
|
||||||
|
dontNpmBuild = true;
|
||||||
|
buildPhase = ''
|
||||||
|
# First install all dependencies
|
||||||
|
npm install
|
||||||
|
|
||||||
|
# Then run the build with workspaces flag
|
||||||
|
npm run build --workspaces
|
||||||
|
'';
|
||||||
|
|
||||||
|
# Runtime dependencies
|
||||||
|
buildInputs = with pkgs; [
|
||||||
|
mpv
|
||||||
|
yt-dlp
|
||||||
|
pulseaudio
|
||||||
|
];
|
||||||
|
|
||||||
|
# Create a wrapper script to ensure runtime deps are available
|
||||||
|
postInstall = ''
|
||||||
|
# Create the necessary directories
|
||||||
|
mkdir -p $out/lib/node_modules/queuecube
|
||||||
|
|
||||||
|
# Copy the entire project with built files
|
||||||
|
cp -r . $out/lib/node_modules/queuecube
|
||||||
|
|
||||||
|
# Install the frontend build to the backend dist directory
|
||||||
|
mkdir -p $out/lib/node_modules/queuecube/backend/dist/
|
||||||
|
cp -r frontend/dist $out/lib/node_modules/queuecube/backend/dist/frontend
|
||||||
|
|
||||||
|
# Create bin directory if it doesn't exist
|
||||||
|
mkdir -p $out/bin
|
||||||
|
|
||||||
|
# Create executable script
|
||||||
|
cat > $out/bin/queuecube <<EOF
|
||||||
|
#!/bin/sh
|
||||||
|
exec ${pkgs.nodejs}/bin/node $out/lib/node_modules/queuecube/backend/build/server.js
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Make it executable
|
||||||
|
chmod +x $out/bin/queuecube
|
||||||
|
|
||||||
|
# Wrap the program to include runtime deps in PATH
|
||||||
|
wrapProgram $out/bin/queuecube \
|
||||||
|
--prefix PATH : ${pkgs.lib.makeBinPath [
|
||||||
|
pkgs.mpv
|
||||||
|
pkgs.yt-dlp
|
||||||
|
pkgs.pulseaudio
|
||||||
|
]}
|
||||||
|
'';
|
||||||
|
|
||||||
|
# Let buildNpmPackage handle npm package hash
|
||||||
|
npmDepsHash = "sha256-BqjJ4CxTPc14Od88sAm/ASwsLszkvcHHeNoZupotlFw=";
|
||||||
|
|
||||||
|
meta = with pkgs.lib; {
|
||||||
|
description = "NodeJS application with media playback capabilities";
|
||||||
|
platforms = platforms.linux;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
in {
|
||||||
|
packages = {
|
||||||
|
default = queuecube;
|
||||||
|
queuecube = queuecube;
|
||||||
|
};
|
||||||
|
|
||||||
|
apps.default = {
|
||||||
|
type = "app";
|
||||||
|
program = "${queuecube}/bin/queuecube";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Development environment
|
||||||
|
devShells.default = pkgs.mkShell {
|
||||||
|
buildInputs = with pkgs; [
|
||||||
|
nodejs_20
|
||||||
|
nodePackages.npm
|
||||||
|
mpv
|
||||||
|
yt-dlp
|
||||||
|
pulseaudio
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
# Add a basic check to verify the package builds
|
||||||
|
checks.queuecube = queuecube;
|
||||||
|
}
|
||||||
|
) // {
|
||||||
|
# Export the NixOS module
|
||||||
|
nixosModules.default = nixosModule;
|
||||||
|
nixosModules.queuecube = nixosModule;
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user