feat: add NixOS service module

This commit is contained in:
2026-07-23 15:08:03 +09:00
parent 6a4f7ca068
commit 234f4354f9
2 changed files with 139 additions and 1 deletions
+32
View File
@@ -64,6 +64,38 @@ Development binds to `127.0.0.1` by default. `dev:tailscale` binds to
only on a trusted network and obtain the Tailscale address with only on a trusted network and obtain the Tailscale address with
`tailscale ip -4`. `tailscale ip -4`.
## NixOS service
The flake provides both a production package and a NixOS module. Import the
module and configure the relay:
```nix
{
inputs.twitter-lite.url =
"git+https://git.yutakobayashi.com/yuta/twitter-lite";
outputs = { nixpkgs, twitter-lite, ... }: {
nixosConfigurations.example = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
twitter-lite.nixosModules.default
{
services.twitter-lite = {
enable = true;
relayBaseUrl = "http://127.0.0.1:6900";
# profileName = "default";
};
}
];
};
};
}
```
The service listens on `127.0.0.1:3000` by default. Set
`services.twitter-lite.host` or `services.twitter-lite.port` to change the
listener. The package can also be built directly with `nix build`.
## Reliability ## Reliability
Bird uses X's internal GraphQL operations through the configured relay. Query Bird uses X's internal GraphQL operations through the configured relay. Query
+107 -1
View File
@@ -3,11 +3,57 @@
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
outputs = { nixpkgs, ... }: outputs = { self, nixpkgs, ... }:
let let
systems = [ "x86_64-linux" "aarch64-linux" ]; systems = [ "x86_64-linux" "aarch64-linux" ];
forAllSystems = nixpkgs.lib.genAttrs systems; forAllSystems = nixpkgs.lib.genAttrs systems;
mkTwitterLite = pkgs:
pkgs.stdenvNoCC.mkDerivation (finalAttrs: {
pname = "twitter-lite";
version = "0.0.0";
src = self;
pnpmDeps = pkgs.fetchPnpmDeps {
inherit (finalAttrs) pname version src;
pnpm = pkgs.pnpm_11;
fetcherVersion = 4;
hash = "sha256-Dk0GkHhvVuls8CkBxYmKV4xYCaZ4vR1UDYCgQmHMgaM=";
};
nativeBuildInputs = with pkgs; [
makeWrapper
nodejs_22
pnpm_11
pnpmConfigHook
];
buildPhase = ''
runHook preBuild
pnpm build
runHook postBuild
'';
installPhase = ''
runHook preInstall
mkdir -p $out/lib/twitter-lite
cp -r .output/. $out/lib/twitter-lite/
makeWrapper ${nixpkgs.lib.getExe pkgs.nodejs_22} $out/bin/twitter-lite \
--add-flags "$out/lib/twitter-lite/server/index.mjs"
runHook postInstall
'';
meta.mainProgram = "twitter-lite";
});
in { in {
packages = forAllSystems (system:
let
pkgs = import nixpkgs { inherit system; };
twitter-lite = mkTwitterLite pkgs;
in {
inherit twitter-lite;
default = twitter-lite;
});
devShells = forAllSystems (system: devShells = forAllSystems (system:
let pkgs = import nixpkgs { inherit system; }; let pkgs = import nixpkgs { inherit system; };
in { in {
@@ -18,5 +64,65 @@
"${pkgs.chromium}/bin/chromium"; "${pkgs.chromium}/bin/chromium";
}; };
}); });
nixosModules.default = { config, lib, pkgs, ... }:
let cfg = config.services.twitter-lite;
in {
options.services.twitter-lite = {
enable = lib.mkEnableOption "Twitter Lite";
package = lib.mkOption {
type = lib.types.package;
default = mkTwitterLite pkgs;
defaultText = lib.literalExpression "twitter-lite.packages.\${pkgs.system}.default";
description = "Twitter Lite package to run.";
};
relayBaseUrl = lib.mkOption {
type = lib.types.nonEmptyStr;
example = "http://127.0.0.1:6900";
description = "Base URL of the Twitter relay.";
};
profileName = lib.mkOption {
type = lib.types.nullOr lib.types.nonEmptyStr;
default = null;
example = "default";
description = "Relay profile to use when the relay has multiple profiles.";
};
host = lib.mkOption {
type = lib.types.nonEmptyStr;
default = "127.0.0.1";
description = "Address on which Twitter Lite listens.";
};
port = lib.mkOption {
type = lib.types.port;
default = 3000;
description = "Port on which Twitter Lite listens.";
};
};
config = lib.mkIf cfg.enable {
systemd.services.twitter-lite = {
description = "Twitter Lite";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
environment = {
HOST = cfg.host;
PORT = toString cfg.port;
TWITTER_RELAY_BASE_URL = cfg.relayBaseUrl;
} // lib.optionalAttrs (cfg.profileName != null) {
BIRD_PROFILE_NAME = cfg.profileName;
};
serviceConfig = {
DynamicUser = true;
ExecStart = lib.getExe cfg.package;
Restart = "on-failure";
};
};
};
};
}; };
} }