From 13279721839923945bd34c637de37fdb79e5c881 Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Thu, 26 Mar 2026 14:43:11 -0700 Subject: [PATCH] Restore embedded frontend with symlink workaround for icons glob mkYarnPackage symlinks node_modules from the Nix store, but webpack's CopyPlugin can't follow symlinks when resolving glob patterns. The @grafana/ui icons directory is dereferenced (cp -rL) before running the webpack build. Also fixes binary output path (root, not cmd/). Co-Authored-By: Claude Opus 4.6 (1M context) --- containers/pyroscope/default.nix | 51 ++++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 6 deletions(-) diff --git a/containers/pyroscope/default.nix b/containers/pyroscope/default.nix index 40565e8..3d14e7e 100644 --- a/containers/pyroscope/default.nix +++ b/containers/pyroscope/default.nix @@ -2,8 +2,6 @@ # Builds v1.19.1 from forge mirror # Uses stdenv + make (not buildGoModule) due to multi-module go.work workspace # with local replace directives (./api, ./lidia) -# Built without embedded frontend — Grafana is the primary UI via the -# grafana-pyroscope-datasource plugin, so the standalone web UI is not needed. # Built with dockerTools.buildLayeredImage for efficient layer caching { pkgs ? import { } }: @@ -16,6 +14,42 @@ let hash = "sha256-UPxGimkzXLFACqmAM1hNQIoNjN6OquVibwVmNvP00+s="; }; + # Build frontend assets via yarn + webpack (upstream uses Docker for this) + # mkYarnPackage symlinks node_modules from the Nix store, but webpack's + # CopyPlugin can't follow symlinks for glob patterns. We dereference the + # @grafana/ui icons directory before running the build. + ui = pkgs.mkYarnPackage { + inherit version src; + pname = "pyroscope-ui"; + + buildPhase = '' + runHook preBuild + export HOME=$TMPDIR + cd deps/grafana-pyroscope + + # Dereference @grafana/ui icons so webpack CopyPlugin glob can find them + icons_src="node_modules/@grafana/ui/dist/public/img/icons" + if [ -L "$icons_src" ] || [ -d "$icons_src" ]; then + icons_tmp=$(mktemp -d) + cp -rL "$icons_src" "$icons_tmp/" + rm -rf "$icons_src" + cp -r "$icons_tmp/icons" "$icons_src" + fi + + yarn --offline build + runHook postBuild + ''; + + installPhase = '' + runHook preInstall + mkdir -p $out + cp -r deps/grafana-pyroscope/public/build/* $out/ + runHook postInstall + ''; + + distPhase = "true"; + }; + # Pre-fetch Go modules for all go.mod files in the workspace (fixed-output derivation) goModules = pkgs.stdenv.mkDerivation { pname = "pyroscope-go-modules"; @@ -68,11 +102,16 @@ let cp -r ${goModules} $GOPATH/pkg/mod chmod -R u+w $GOPATH/pkg/mod - # Build Go binary without embedded frontend (EMBEDASSETS="") - # Grafana queries Pyroscope via API; standalone web UI not needed + # Copy pre-built frontend assets + mkdir -p public/build + cp -r ${ui}/* public/build/ + + # Build Go binary with embedded frontend assets + # Skip the Makefile's frontend/build target (uses Docker) and + # invoke go/bin directly with EMBEDASSETS set # CGO_ENABLED=0 for static binary (matches upstream) CGO_ENABLED=0 \ - EMBEDASSETS="" \ + EMBEDASSETS=embedassets \ IMAGE_TAG=v${version} \ make go/bin @@ -82,7 +121,7 @@ let installPhase = '' runHook preInstall mkdir -p $out/bin - cp cmd/pyroscope/pyroscope $out/bin/pyroscope + cp pyroscope $out/bin/pyroscope runHook postInstall '';