This commit is contained in:
Bryan Ramos 2026-04-15 20:58:07 -04:00
commit 864c69fe61
147 changed files with 11233 additions and 0 deletions

View file

@ -0,0 +1,136 @@
{ pkgs, lib, config, ... }:
with lib;
let
cfg = config.modules.system.sandpack;
domain = "ramos.codes";
privateAccessRules = concatMapStringsSep "\n" (cidr: "allow ${cidr};") config.modules.system.nginx.privateAllowCidrs + "\ndeny all;";
staticBrowserServer = pkgs.stdenvNoCC.mkDerivation (finalAttrs: let
pnpm = pkgs.pnpm_10;
in {
pname = "static-browser-server";
version = "1.0.6";
src = pkgs.fetchFromGitHub {
owner = "LibreChat-AI";
repo = "static-browser-server";
rev = "30de7ae4ebf5433acc0fb640649fb77426a79e04";
hash = "sha256-OVAGnoh7KRmTPY2bXE0kvCMiPx3tXAooDa8n8ujugYM=";
};
patches = [ ./pnpm-lock.patch ];
pnpmDeps = pkgs.fetchPnpmDeps {
inherit (finalAttrs) pname version src patches;
pnpm = pnpm;
fetcherVersion = 3;
hash = "sha256-+Gz8tQy4rkoi365To9GI6sShPTjuKEmZxtV5mEB2UYk=";
};
nativeBuildInputs = [
pkgs.makeWrapper
pkgs.nodejs
pkgs.pnpmConfigHook
pnpm
];
buildPhase = ''
runHook preBuild
pnpm build
runHook postBuild
'';
installPhase = ''
runHook preInstall
mkdir -p $out/libexec/static-browser-server $out/bin
cp -r out $out/libexec/
pnpm exec esbuild \
./servers/demo-server.ts \
--bundle \
--platform=node \
--format=cjs \
--outfile=$out/libexec/static-browser-server/demo-server.js
makeWrapper ${pkgs.nodejs}/bin/node $out/bin/static-browser-server \
--add-flags $out/libexec/static-browser-server/demo-server.js
runHook postInstall
'';
});
in
{
options.modules.system.sandpack = {
enable = mkEnableOption "Sandpack services";
};
config = mkIf cfg.enable {
virtualisation.oci-containers = {
backend = "podman";
containers.sandpack-bundler = {
image = "ghcr.io/librechat-ai/codesandbox-client/bundler:latest";
ports = [ "127.0.0.1:4333:80" ];
};
};
systemd.services.sandpack-preview = {
description = "Sandpack static preview server";
after = [ "network-online.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
ExecStart = "${staticBrowserServer}/bin/static-browser-server";
WorkingDirectory = "${staticBrowserServer}/libexec/static-browser-server";
Restart = "always";
RestartSec = 5;
DynamicUser = true;
Environment = [
"HOST=127.0.0.1"
"PORT=4324"
];
};
};
services.nginx.virtualHosts."bundler.${domain}" = {
useACMEHost = domain;
forceSSL = true;
locations."/" = {
proxyPass = "http://127.0.0.1:4333";
extraConfig = ''
${privateAccessRules}
add_header Access-Control-Allow-Origin "*" always;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;
add_header Access-Control-Max-Age "3600" always;
if ($request_method = OPTIONS) {
return 204;
}
'';
};
};
services.nginx.virtualHosts."preview.${domain}" = {
useACMEHost = domain;
forceSSL = true;
serverAliases = [ "~^.+-preview\\.ramos\\.codes$" ];
locations."/" = {
proxyPass = "http://127.0.0.1:4324";
extraConfig = ''
${privateAccessRules}
add_header Access-Control-Allow-Origin "*" always;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;
add_header Access-Control-Max-Age "3600" always;
if ($request_method = OPTIONS) {
return 204;
}
'';
};
};
};
}