1{
2 inputs = {
3 nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
4 };
5
6 outputs = {
7 self,
8 nixpkgs,
9 }: let
10 supportedSystems = ["x86_64-linux" "aarch64-linux" "aarch64-darwin"];
11 forAllSystems = nixpkgs.lib.genAttrs supportedSystems;
12 nixpkgsFor = forAllSystems (system:
13 import nixpkgs {
14 inherit system;
15 overlays = [
16 self.overlays.default
17 ];
18 });
19 in {
20 overlays.default = final: prev: let
21 pname = "lurker";
22 version = "0.1.0";
23 in {
24 node_modules = with final;
25 stdenv.mkDerivation {
26 pname = "lurker-node-modules";
27 version = "0.0.1";
28 impureEnvVars =
29 lib.fetchers.proxyImpureEnvVars
30 ++ ["GIT_PROXY_COMMAND" "SOCKS_SERVER"];
31 src = ./.;
32 nativeBuildInputs = [bun];
33 buildInputs = [nodejs-slim_latest];
34 dontConfigure = true;
35 dontFixup = true;
36 buildPhase = ''
37 bun install --no-progress --frozen-lockfile
38 '';
39 installPhase = ''
40 mkdir -p $out/node_modules
41 cp -R ./node_modules/* $out/node_modules
42 ls -la $out/node_modules
43 '';
44 outputHash = "sha256-UiD/gqwaU1+qLNkeds2i7kVgCjlrgxsTcqQDbO8+gG8=";
45 outputHashAlgo = "sha256";
46 outputHashMode = "recursive";
47 };
48 lurker = with final;
49 stdenv.mkDerivation {
50 inherit pname version;
51 src = ./.;
52 nativeBuildInputs = [makeBinaryWrapper];
53 buildInputs = [bun];
54
55 buildPhase = ''
56 runHook preBuild
57 runHook postBuild
58 '';
59
60 dontFixup = true;
61
62 installPhase = ''
63 runHook preInstall
64
65 mkdir -p $out/bin
66
67 ln -s ${node_modules}/node_modules $out
68 cp -R ./* $out
69
70 makeBinaryWrapper ${bun}/bin/bun $out/bin/$pname \
71 --prefix PATH : ${lib.makeBinPath [bun]} \
72 --add-flags "run --prefer-offline --no-install $out/src/index.js"
73
74 '';
75 };
76 dockerImage = with final;
77 final.dockerTools.buildImage {
78 name = pname;
79 tag = "latest";
80
81 copyToRoot = final.buildEnv {
82 name = "image-root";
83 paths = [final.lurker];
84 pathsToLink = ["/bin"];
85 };
86
87 runAsRoot = ''
88 mkdir -p /data
89 '';
90
91 config = {
92 Cmd = ["/bin/${pname}"];
93 WorkingDir = "/data";
94 Volumes = {"/data" = {};};
95 };
96 };
97 };
98
99 devShell = forAllSystems (system: let
100 pkgs = nixpkgsFor."${system}";
101 in
102 pkgs.mkShell {
103 nativeBuildInputs = [
104 pkgs.bun
105 pkgs.biome
106 pkgs.typescript-language-server
107 ];
108 });
109
110 packages = forAllSystems (system: {
111 inherit (nixpkgsFor."${system}") lurker node_modules dockerImage;
112 });
113
114 defaultPackage = forAllSystems (system: nixpkgsFor."${system}".lurker);
115
116 apps = forAllSystems (system: let
117 pkgs = nixpkgsFor.${system};
118 in {
119 default = {
120 type = "app";
121 program = "${pkgs.lurker}/bin/lurker";
122 };
123 });
124
125 formatter = forAllSystems (system: nixpkgsFor."${system}".alejandra);
126
127 nixosModules.default = {
128 config,
129 pkgs,
130 lib,
131 ...
132 }:
133 with lib; {
134 options = {
135 services.lurker = {
136 enable = mkOption {
137 type = types.bool;
138 default = false;
139 description = "Enable lurker";
140 };
141 port = mkOption {
142 type = types.int;
143 default = 3000;
144 description = "Port to run lurker on";
145 };
146 };
147 };
148
149 config = mkIf config.services.lurker.enable {
150 nixpkgs.overlays = [self.overlays.default];
151 systemd.services.lurker = {
152 description = "lurker service";
153 wantedBy = ["multi-user.target"];
154
155 serviceConfig = {
156 ListenStream = "0.0.0.0:${toString config.services.lurker.port}";
157 ExecStart = "${pkgs.lurker}/bin/lurker";
158 Restart = "always";
159 };
160
161 # If the binary needs specific environment variables, set them here
162 environment = {
163 LURKER_PORT = "${toString config.services.lurker.port}";
164 };
165 };
166 };
167 };
168 };
169}