turborepo-remote-cache: init at 2.6.1, nixos/turborepo-remote-cache: init (#405218)

This commit is contained in:
@mjones 2026-03-09 07:07:36 +00:00 committed by GitHub
commit 3766236ef7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 205 additions and 1 deletions

View file

@ -68,6 +68,8 @@
- [udp-over-tcp](https://github.com/mullvad/udp-over-tcp), a tunnel for proxying UDP traffic over a TCP stream. Available as `services.udp-over-tcp`.
- [turborepo-remote-cache](https://ducktors.github.io/turborepo-remote-cache/), an open-source implementation of the [Turborepo custom remote cache server](https://turbo.build/repo/docs/core-concepts/remote-caching#self-hosting). Available as [services.turborepo-remote-cache](options.html#opt-services.turborepo-remote-cache).
- [Komodo Periphery](https://github.com/moghtech/komodo), a multi-server Docker and Git deployment agent by Komodo. Available as [services.komodo-periphery](#opt-services.komodo-periphery.enable).
- [Shoko](https://shokoanime.com), an anime management system. Available as [services.shoko](#opt-services.shoko.enable).

View file

@ -609,6 +609,7 @@
./services/development/lorri.nix
./services/development/nixseparatedebuginfod2.nix
./services/development/rstudio-server/default.nix
./services/development/turborepo-remote-cache.nix
./services/development/vsmartcard-vpcd.nix
./services/development/zammad.nix
./services/display-managers/cosmic-greeter.nix

View file

@ -0,0 +1,131 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.services.turborepo-remote-cache;
inherit (lib)
boolToString
isBool
literalExpression
mapAttrs
mkEnableOption
mkIf
mkOption
mkPackageOption
types
;
in
{
options.services.turborepo-remote-cache = {
enable = mkEnableOption "Turborepo Remote Cache" // {
description = ''
Enables the daemon for `turborepo-remote-cache`,
an open source implementation of the Turborepo custom remote cache server.
'';
};
package = mkPackageOption pkgs "turborepo-remote-cache" { };
environment = mkOption {
type = types.attrsOf (
types.nullOr (
types.oneOf [
types.bool
types.int
types.str
]
)
);
default = { };
description = ''
Environment variables to set.
Turborepo-remote-cache is configured through the use of environment variables.
The available configuration options can be found in the [documentation][envvars].
[envvars]: https://ducktors.github.io/turborepo-remote-cache/environment-variables.html
Note that all environment variables set through this configuration
parameter will be readable by anyone with access to the host
machine. Therefore, sensitive information like {env}`TURBO_TOKEN`
should never be set using this configuration option, but should instead use
[](#opt-services.turborepo-remote-cache.environmentFile).
See the documentation for that option for more information.
Any environment variables specified in the
[](#opt-services.turborepo-remote-cache.environmentFile)
will supersede environment variables specified in this option.
'';
example = literalExpression ''
{
NODE_ENV = "production";
PORT = 8080;
}
'';
};
environmentFile = mkOption {
type = types.nullOr types.path;
default = null;
description = ''
Additional environment file as defined in {manpage}`systemd.exec(5)`.
Secrets like {env}`TURBO_TOKEN` may be passed to the
service without making them readable to everyone with access to
systemctl by using this configuration parameter.
Note that this file needs to be available on the host on which
`turborepo-remote-cache` is running.
See the [documentation][envvars]
and the [](#opt-services.turborepo-remote-cache.environment) configuration parameter
for further options.
[envvars]: https://ducktors.github.io/turborepo-remote-cache/environment-variables.html
'';
example = "/run/secrets/turborepo-remote-cache.env";
};
openFirewall = mkOption {
type = types.bool;
default = false;
description = ''
Open ports in the firewall for turborepo-remote-cache daemon.
'';
};
};
config = mkIf cfg.enable {
systemd.services.turborepo-remote-cache = {
serviceConfig = {
Restart = "always";
EnvironmentFile = cfg.environmentFile;
ExecStart = "${cfg.package}/bin/turborepo-remote-cache";
DynamicUser = true;
ProtectSystem = "strict";
ProtectHome = true;
NoNewPrivileges = true;
PrivateDevices = true;
PrivateTmp = true;
};
environment = mapAttrs (
name: value: if isBool value then boolToString value else toString value
) cfg.environment;
wantedBy = [ "default.target" ];
};
networking.firewall.allowedTCPPorts =
let
# 3000 is the default port as specified in
# https://ducktors.github.io/turborepo-remote-cache/environment-variables.html
port = cfg.environment.PORT or 3000;
in
mkIf cfg.openFirewall [ port ];
};
}

View file

@ -1672,6 +1672,7 @@ in
tuliprox = runTest ./tuliprox.nix;
tuned = runTest ./tuned.nix;
tuptime = runTest ./tuptime.nix;
turborepo-remote-cache = runTest ./turborepo-remote-cache.nix;
turbovnc-headless-server = runTest ./turbovnc-headless-server.nix;
turn-rs = runTest ./turn-rs.nix;
tusd = runTest ./tusd/default.nix;

View file

@ -0,0 +1,65 @@
{ lib, ... }:
let
ports = {
turborepo-remote-cache = 8080;
};
token = "myrandomtoken";
team = "nixos-team";
# require('crypto').randomBytes(20).toString('hex');
artifactid = "82286e93a6f84e18a8fe4770c5a88b24653e7f59";
in
{
name = "turborepo-remote-cache";
nodes.machine = {
services.turborepo-remote-cache = {
enable = true;
environment = {
PORT = ports.turborepo-remote-cache;
TURBO_TEAM = team;
TURBO_TOKEN = token;
};
};
};
testScript = ''
import json
machine.wait_for_unit("turborepo-remote-cache.service")
machine.wait_for_open_port(${toString ports.turborepo-remote-cache})
def read_json(input):
try:
return json.loads(input)
except Exception as e:
print(input)
raise e
out = read_json(machine.succeed("""curl 127.0.0.1:${toString ports.turborepo-remote-cache}/v8/artifacts/status? \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer ${token}"
"""))
if out["status"] != "enabled":
raise Exception(f"status is not enabled in response: {out}")
out = read_json(machine.succeed("""curl -X PUT "127.0.0.1:${toString ports.turborepo-remote-cache}/v8/artifacts/${artifactid}?teamId=${team}" \
-H "Authorization: Bearer ${token}" \
-H "Content-Type: application/octet-stream" \
-d 'myartifact'"""))
if "urls" not in out:
raise Exception(f"'urls' not in response: {out}")
out = machine.succeed("""curl 127.0.0.1:${toString ports.turborepo-remote-cache}/v8/artifacts/${artifactid}?teamId=${team} \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer ${token}"
""")
if out != "myartifact":
raise Exception(f"reponse in not 'myartifact': {out}")
'';
meta.maintainers = [ lib.maintainers.ibizaman ];
}

View file

@ -9,6 +9,7 @@
fetchPnpmDeps,
makeWrapper,
nix-update-script,
nixosTests,
}:
stdenvNoCC.mkDerivation (finalAttrs: {
pname = "turborepo-remote-cache";
@ -73,7 +74,10 @@ stdenvNoCC.mkDerivation (finalAttrs: {
runHook postInstall
'';
passthru.updateScript = nix-update-script { };
passthru = {
tests = { inherit (nixosTests) turborepo-remote-cache; };
updateScript = nix-update-script { };
};
meta = {
homepage = "https://github.com/ducktors/turborepo-remote-cache";