Initial package: turborepo-remote-cache 2.8.2
Self-hosted Turborepo remote cache server packaged as a Fedora RPM
with the same base + -service + -container split used by the gitea
package.
- Base: dynamic sysusers turbo-cache user, /etc/turborepo-remote-cache
config dir with config.env token template, /var/cache storage dir
- -service: native Node.js systemd unit, app installed to
%{nodejs_sitelib}/turborepo-remote-cache with pnpm-vendored
production node_modules (built via fetch-sources.sh)
- -container: Podman quadlet pinned to
docker.io/ducktors/turborepo-remote-cache:2.8.2
- Listens on 127.0.0.1:3128; runners reach via host.containers.internal
This commit is contained in:
29
config.env
Normal file
29
config.env
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
# Turborepo Remote Cache server configuration
|
||||||
|
# =============================================
|
||||||
|
#
|
||||||
|
# This file is loaded by both the native systemd service and the
|
||||||
|
# Podman quadlet as an EnvironmentFile. Edit and restart the service:
|
||||||
|
#
|
||||||
|
# systemctl restart turborepo-remote-cache.service
|
||||||
|
#
|
||||||
|
# See https://github.com/ducktors/turborepo-remote-cache for all options.
|
||||||
|
|
||||||
|
# Shared secret that clients (turbo CLI, CI runners) must present.
|
||||||
|
# Generate with: openssl rand -hex 32
|
||||||
|
TURBO_TOKEN=CHANGE_ME
|
||||||
|
|
||||||
|
# Storage provider. Keep "local" for filesystem-backed cache.
|
||||||
|
STORAGE_PROVIDER=local
|
||||||
|
|
||||||
|
# Path inside the service/container where cached artifacts live.
|
||||||
|
# The native service writes here directly; the container mounts
|
||||||
|
# /var/cache/turborepo-remote-cache from the host to this path.
|
||||||
|
STORAGE_PATH=/var/cache/turborepo-remote-cache
|
||||||
|
|
||||||
|
# Listen address and port. Bound to localhost by default — runners
|
||||||
|
# reach the host via host.containers.internal (Podman) on this port.
|
||||||
|
HOST=127.0.0.1
|
||||||
|
PORT=3128
|
||||||
|
|
||||||
|
# Log level: fatal, error, warn, info, debug, trace
|
||||||
|
LOG_LEVEL=info
|
||||||
42
fetch-sources.sh
Executable file
42
fetch-sources.sh
Executable file
@@ -0,0 +1,42 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Fetch upstream source tarball and vendor production node_modules.
|
||||||
|
#
|
||||||
|
# Produces two files next to the spec:
|
||||||
|
# turborepo-remote-cache-<VERSION>.tar.gz (upstream src)
|
||||||
|
# turborepo-remote-cache-<VERSION>-node_modules_prod.tar.gz
|
||||||
|
#
|
||||||
|
# Requires: curl, tar, pnpm, node
|
||||||
|
#
|
||||||
|
# Run this before `rpmbuild` whenever VERSION changes.
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
VERSION="${1:-2.8.2}"
|
||||||
|
PKG="turborepo-remote-cache"
|
||||||
|
UPSTREAM="https://github.com/ducktors/${PKG}"
|
||||||
|
|
||||||
|
SPEC_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
WORK="$(mktemp -d)"
|
||||||
|
trap 'rm -rf "$WORK"' EXIT
|
||||||
|
|
||||||
|
SRC_TARBALL="${PKG}-${VERSION}.tar.gz"
|
||||||
|
DEPS_TARBALL="${PKG}-${VERSION}-node_modules_prod.tar.gz"
|
||||||
|
|
||||||
|
echo ">>> Fetching ${UPSTREAM}/archive/refs/tags/v${VERSION}.tar.gz"
|
||||||
|
curl -fsSL -o "${SPEC_DIR}/${SRC_TARBALL}" \
|
||||||
|
"${UPSTREAM}/archive/refs/tags/v${VERSION}.tar.gz"
|
||||||
|
|
||||||
|
echo ">>> Extracting source to ${WORK}"
|
||||||
|
tar -C "${WORK}" -xzf "${SPEC_DIR}/${SRC_TARBALL}"
|
||||||
|
cd "${WORK}/${PKG}-${VERSION}"
|
||||||
|
|
||||||
|
echo ">>> Installing production dependencies with pnpm"
|
||||||
|
pnpm install --prod --frozen-lockfile --ignore-scripts
|
||||||
|
|
||||||
|
echo ">>> Packing node_modules into ${DEPS_TARBALL}"
|
||||||
|
tar -czf "${SPEC_DIR}/${DEPS_TARBALL}" node_modules
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Done:"
|
||||||
|
echo " ${SPEC_DIR}/${SRC_TARBALL}"
|
||||||
|
echo " ${SPEC_DIR}/${DEPS_TARBALL}"
|
||||||
24
turborepo-remote-cache.container
Normal file
24
turborepo-remote-cache.container
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Turborepo Remote Cache (Podman quadlet)
|
||||||
|
Documentation=https://github.com/ducktors/turborepo-remote-cache
|
||||||
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Container]
|
||||||
|
ContainerName=turborepo-remote-cache
|
||||||
|
Image=docker.io/ducktors/turborepo-remote-cache:2.8.2
|
||||||
|
EnvironmentFile=/etc/turborepo-remote-cache/config.env
|
||||||
|
# Bind to loopback on the host; runners reach via host.containers.internal
|
||||||
|
PublishPort=127.0.0.1:3128:3000
|
||||||
|
Volume=/var/cache/turborepo-remote-cache:/app/cache:Z
|
||||||
|
# Override STORAGE_PATH inside the container to match the bind mount
|
||||||
|
Environment=STORAGE_PATH=/app/cache
|
||||||
|
Environment=PORT=3000
|
||||||
|
Environment=HOST=0.0.0.0
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5s
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target default.target
|
||||||
28
turborepo-remote-cache.service
Normal file
28
turborepo-remote-cache.service
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Turborepo Remote Cache server
|
||||||
|
Documentation=https://github.com/ducktors/turborepo-remote-cache
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=turbo-cache
|
||||||
|
Group=turbo-cache
|
||||||
|
EnvironmentFile=/etc/turborepo-remote-cache/config.env
|
||||||
|
ExecStart=/usr/bin/node --enable-source-maps /usr/lib/node_modules/turborepo-remote-cache/dist/index.js
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5s
|
||||||
|
|
||||||
|
# Hardening
|
||||||
|
NoNewPrivileges=yes
|
||||||
|
ProtectSystem=strict
|
||||||
|
ProtectHome=yes
|
||||||
|
PrivateTmp=yes
|
||||||
|
PrivateDevices=yes
|
||||||
|
ProtectKernelTunables=yes
|
||||||
|
ProtectKernelModules=yes
|
||||||
|
ProtectControlGroups=yes
|
||||||
|
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
|
||||||
|
ReadWritePaths=/var/cache/turborepo-remote-cache
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
142
turborepo-remote-cache.spec
Normal file
142
turborepo-remote-cache.spec
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
%global npm_name turborepo-remote-cache
|
||||||
|
%global __brp_mangle_shebangs_exclude_from ^%{nodejs_sitelib}/%{npm_name}/.*$
|
||||||
|
|
||||||
|
Name: turborepo-remote-cache
|
||||||
|
Version: 2.8.2
|
||||||
|
Release: 1%{?dist}
|
||||||
|
Summary: Self-hosted Turborepo remote cache server
|
||||||
|
License: MIT
|
||||||
|
Group: Development/Tools
|
||||||
|
URL: https://github.com/ducktors/turborepo-remote-cache
|
||||||
|
|
||||||
|
# Fetch both with ./fetch-sources.sh <version> before rpmbuild
|
||||||
|
Source0: %{name}-%{version}.tar.gz
|
||||||
|
Source1: %{name}-%{version}-node_modules_prod.tar.gz
|
||||||
|
|
||||||
|
Source10: %{name}.sysusers
|
||||||
|
Source11: %{name}.service
|
||||||
|
Source12: %{name}.container
|
||||||
|
Source13: config.env
|
||||||
|
|
||||||
|
BuildArch: noarch
|
||||||
|
|
||||||
|
BuildRequires: systemd-rpm-macros
|
||||||
|
BuildRequires: nodejs-devel
|
||||||
|
BuildRequires: nodejs-npm
|
||||||
|
BuildRequires: pnpm
|
||||||
|
|
||||||
|
%description
|
||||||
|
Turborepo Remote Cache is a self-hosted implementation of the Vercel
|
||||||
|
Remote Cache API used by Turborepo and turbo-compatible build tools.
|
||||||
|
It lets CI runners share build artifacts without relying on Vercel's
|
||||||
|
hosted cache.
|
||||||
|
|
||||||
|
This base package ships the sysusers.d drop-in, the configuration
|
||||||
|
directory with a token template, and the cache storage directory.
|
||||||
|
Install either turborepo-remote-cache-service (native Node.js) or
|
||||||
|
turborepo-remote-cache-container (Podman quadlet) to actually run
|
||||||
|
the server.
|
||||||
|
|
||||||
|
%package service
|
||||||
|
Summary: Turborepo Remote Cache as a native Node.js systemd service
|
||||||
|
Requires: %{name} = %{version}-%{release}
|
||||||
|
Requires: nodejs >= 1:20
|
||||||
|
Conflicts: %{name}-container
|
||||||
|
%{?systemd_requires}
|
||||||
|
|
||||||
|
%description service
|
||||||
|
Runs turborepo-remote-cache as a native Node.js process under systemd,
|
||||||
|
using the pnpm-vendored production dependencies shipped with this
|
||||||
|
package. Listens on 127.0.0.1:3128 by default.
|
||||||
|
|
||||||
|
%package container
|
||||||
|
Summary: Turborepo Remote Cache as a Podman quadlet
|
||||||
|
Requires: %{name} = %{version}-%{release}
|
||||||
|
Requires: podman
|
||||||
|
Requires: containers-common
|
||||||
|
Conflicts: %{name}-service
|
||||||
|
|
||||||
|
%description container
|
||||||
|
Runs turborepo-remote-cache as a Podman container via quadlet,
|
||||||
|
pulling docker.io/ducktors/turborepo-remote-cache:%{version}.
|
||||||
|
Listens on 127.0.0.1:3128 by default; cache storage is bind-mounted
|
||||||
|
from /var/cache/turborepo-remote-cache on the host.
|
||||||
|
|
||||||
|
%prep
|
||||||
|
%setup -q -n %{name}-%{version}
|
||||||
|
# Drop the vendored node_modules from Source1 into the source tree
|
||||||
|
tar -xzf %{SOURCE1}
|
||||||
|
|
||||||
|
%build
|
||||||
|
# Compile TypeScript → dist/. node_modules is already vendored.
|
||||||
|
pnpm build
|
||||||
|
|
||||||
|
%install
|
||||||
|
%{__rm} -rf %{buildroot}
|
||||||
|
|
||||||
|
# Base: sysusers, config dir, cache dir
|
||||||
|
install -p -D -m 644 %{SOURCE10} %{buildroot}%{_sysusersdir}/%{name}.conf
|
||||||
|
|
||||||
|
install -d -m 750 %{buildroot}%{_sysconfdir}/%{name}
|
||||||
|
install -m 640 %{SOURCE13} %{buildroot}%{_sysconfdir}/%{name}/config.env
|
||||||
|
|
||||||
|
install -d -m 750 %{buildroot}%{_localstatedir}/cache/%{name}
|
||||||
|
|
||||||
|
# -service: install app tree to %{nodejs_sitelib}/turborepo-remote-cache
|
||||||
|
install -d -m 755 %{buildroot}%{nodejs_sitelib}/%{npm_name}
|
||||||
|
cp -pr dist node_modules package.json \
|
||||||
|
%{buildroot}%{nodejs_sitelib}/%{npm_name}/
|
||||||
|
|
||||||
|
# CLI symlink + shebang fix
|
||||||
|
install -d -m 755 %{buildroot}%{_bindir}
|
||||||
|
ln -s %{nodejs_sitelib}/%{npm_name}/dist/cli.js \
|
||||||
|
%{buildroot}%{_bindir}/%{name}
|
||||||
|
sed -i -e '1s|^#!.*node.*|#!/usr/bin/node|' \
|
||||||
|
%{buildroot}%{nodejs_sitelib}/%{npm_name}/dist/cli.js || :
|
||||||
|
chmod 755 %{buildroot}%{nodejs_sitelib}/%{npm_name}/dist/cli.js
|
||||||
|
|
||||||
|
# -service: systemd unit
|
||||||
|
install -p -D -m 644 %{SOURCE11} %{buildroot}%{_unitdir}/%{name}.service
|
||||||
|
|
||||||
|
# -container: quadlet
|
||||||
|
install -p -D -m 644 %{SOURCE12} \
|
||||||
|
%{buildroot}%{_datadir}/containers/systemd/%{name}.container
|
||||||
|
|
||||||
|
%pre
|
||||||
|
%sysusers_create_package %{name} %{SOURCE10}
|
||||||
|
|
||||||
|
%post service
|
||||||
|
%systemd_post %{name}.service
|
||||||
|
|
||||||
|
%preun service
|
||||||
|
%systemd_preun %{name}.service
|
||||||
|
|
||||||
|
%postun service
|
||||||
|
%systemd_postun_with_restart %{name}.service
|
||||||
|
|
||||||
|
%files
|
||||||
|
%defattr(-,root,root,-)
|
||||||
|
%{_sysusersdir}/%{name}.conf
|
||||||
|
%dir %attr(0750,root,turbo-cache) %{_sysconfdir}/%{name}
|
||||||
|
%config(noreplace) %attr(0640,root,turbo-cache) %{_sysconfdir}/%{name}/config.env
|
||||||
|
%dir %attr(0750,turbo-cache,turbo-cache) %{_localstatedir}/cache/%{name}
|
||||||
|
|
||||||
|
%files service
|
||||||
|
%defattr(-,root,root,-)
|
||||||
|
%{_unitdir}/%{name}.service
|
||||||
|
%dir %{nodejs_sitelib}/%{npm_name}
|
||||||
|
%{nodejs_sitelib}/%{npm_name}/dist
|
||||||
|
%{nodejs_sitelib}/%{npm_name}/node_modules
|
||||||
|
%{nodejs_sitelib}/%{npm_name}/package.json
|
||||||
|
%{_bindir}/%{name}
|
||||||
|
|
||||||
|
%files container
|
||||||
|
%defattr(-,root,root,-)
|
||||||
|
%{_datadir}/containers/systemd/%{name}.container
|
||||||
|
|
||||||
|
%changelog
|
||||||
|
* Wed Apr 08 2026 Zoran Pericic <zpericic@netst.org> - 2.8.2-1
|
||||||
|
- Initial package for ducktors/turborepo-remote-cache 2.8.2
|
||||||
|
- Split into -service (native Node.js) and -container (Podman quadlet)
|
||||||
|
- Dynamic sysusers turbo-cache user
|
||||||
|
- Listens on 127.0.0.1:3128; storage at /var/cache/turborepo-remote-cache
|
||||||
1
turborepo-remote-cache.sysusers
Normal file
1
turborepo-remote-cache.sysusers
Normal file
@@ -0,0 +1 @@
|
|||||||
|
u turbo-cache - "Turborepo Remote Cache" /var/cache/turborepo-remote-cache /sbin/nologin
|
||||||
Reference in New Issue
Block a user