Open sagikazarmark opened 1 year ago
Here is an initial version using the binary distribution for now: https://github.com/sagikazarmark/nix-garden
@sagikazarmark Cool, thank you for working on this!
In our contributing guide we have a [section about how to build the release binaries and docker containers]().
In NixOS you use glibc by default, right?
Basically we need the built pkg vercel nodejs binary, and a "static" directory (that needs to be initialized as a git repository unfortunately right now).
See also the debian Dockerfile: https://github.com/garden-io/garden/blob/main/support/buster.Dockerfile#L47C2-L47C2 The build context root for that Dockerfile dist/linux-amd64 (This directory exists after running yarn dist)
Happy to help if you run into problems.
Unfortunately we have no official ARM binaries yet, which should be straightforward to change nowadays but we are tracking a separate issue for that: #1547
@stefreak thanks for getting back to me.
As far as I understand the value behind building the vercel pkg binaries is to distribute garden as a single executable. I'm not sure the Nix package needs that as Nix is perfectly capable of installing Node as a dependency as well.
The repo I linked above already uses the binary distribution which is a good start IMO, but I'd like to play a bit with skipping the final vercel build and just use ... the artifact that comes before that. A script file? Not sure yet.
In NixOS you use glibc by default, right?
Yep
Basically we need the built pkg vercel nodejs binary, and a "static" directory (that needs to be initialized as a git repository unfortunately right now).
One problem I already have (with the binary distributed version) is this:
Unexpected Git error occurred while running 'git status' from path "/nix/store/hlg35xcp6aihwazrcvy5s8b9b63hm0bh-garden-0.13.10/static". Exit code: 128. Error message: fatal: detected dubious ownership in repository at '/nix/store/hlg35xcp6aih
wazrcvy5s8b9b63hm0bh-garden-0.13.10/static'
To add an exception for this directory, call:
git config --global --add safe.directory /nix/store/hlg35xcp6aihwazrcvy5s8b9b63hm0bh-garden-0.13.10/static
Command "git status" failed with code 128:
fatal: detected dubious ownership in repository at '/nix/store/hlg35xcp6aihwazrcvy5s8b9b63hm0bh-garden-0.13.10/static'
To add an exception for this directory, call:
git config --global --add safe.directory /nix/store/hlg35xcp6aihwazrcvy5s8b9b63hm0bh-garden-0.13.10/static
Nix puts all packages in a so-called "Nix store" (basically /nix in the filesystem) and makes them read-only and owned by root, to make sure no accidental modifications happen.
I'll take a look at the links you've provided and come back if I have any questions. Thanks!
@sagikazarmark then it might be possible that https://github.com/garden-io/garden/pull/4047 has to be finished first, where we get rid of the requirement that the static directory is a git repository.
@stefreak I managed to work around the problem for now: https://github.com/sagikazarmark/nix-garden/blob/main/flake.nix#L93-L98
The binary distribution seems to be working for the moment, so I'll test it in the next couple weeks and then submit it to the official Nix repository.
I'll keep working on the vercel-less version in the meantime.
@sagikazarmark as a user of Nix and Guix this is something I've wanted for a long time (I created an issue in nixpkgs but never got around to filling).
Since I use Guix System on my personal laptop, I created a Guix package for garden
over the weekend. ldd
shows missing libraries on the raw garden
binary:
ldd garden
linux-vdso.so.1 (0x00007ffcbbfe9000)
libdl.so.2 => /gnu/store/ip9mj1pwymxi1yq32zbhwp3n3bycy6yi-glibc-2.35/lib/libdl.so.2 (0x00007fd2f5496000)
libstdc++.so.6 => not found
libm.so.6 => /gnu/store/ip9mj1pwymxi1yq32zbhwp3n3bycy6yi-glibc-2.35/lib/libm.so.6 (0x00007fd2f53b9000)
libgcc_s.so.1 => not found
libpthread.so.0 => /gnu/store/ip9mj1pwymxi1yq32zbhwp3n3bycy6yi-glibc-2.35/lib/libpthread.so.0 (0x00007fd2f53b4000)
libc.so.6 => /gnu/store/ip9mj1pwymxi1yq32zbhwp3n3bycy6yi-glibc-2.35/lib/libc.so.6 (0x00007fd2f51b6000)
/lib64/ld-linux-x86-64.so.2 => /gnu/store/ip9mj1pwymxi1yq32zbhwp3n3bycy6yi-glibc-2.35/lib/ld-linux-x86-64.so.2 (0x00007fd2f549d000)
My Guix package definition is unfinished because patchelf
-ing in these library paths changes the binary size, which Pkg has an issue with because it uses hardcoded offsets. As far as I can tell the solution is to manually bodge the PAYLOAD_POSITION
and PRELUDE_POSITION
as this packager did in 2018.
I've noticed you don't use patchelf
. I'm confused why your flake works for you because as I understand NixOS suffers from the same issue as Guix System in needing to patch the RPATH and dynamic linker of most binaries to work with these distros. How have you avoided it?
In any case, thanks for your efforts to package garden
for Nix! This will open up our tool to be used across a broader range of non-FHS compliant distros and by macOS users that don't want to deal with Homebrew (far and away the worst package manager I've ever used).
@worldofgeese I only used the package on macOS so far, so that might answer why it works.
The garden binary itself is packaged using vercel/pkg which I think we should be able to omit (that could also make packaging easier).
@sagikazarmark I spoke with @TimBeyer to understand our binary build process a little more: yarn build
and yarn dist
call out to https://github.com/garden-io/garden/blob/main/cli/src/build-pkg.ts. Tim tells me it'd be non-trivial to duplicate what build-pkg.ts
does for another packager. However, we did arrive at some promising possibilities!
yarn install
is not an alias but a standard yarn
command and installs all dependencies into the local node_modules
folder. If we pull in yarn as an explicit dependency we can use this in our package definitions to make an FHS-independent package that runs on NixOS and Guix System.garden
to NPM but stopped. If we began publishing to NPM again, we could just install garden
as an NPM package within our build environments.There are performance penalties to using Pkg in the resulting binary so it may be we see performance improvements by pursuing either of these alternatives in our own definitions.
@worldofgeese these are great news! I could see either of these happening.
I believe we should pursue both (given publishing on NPM is something you can/want to do), but for the long term, option 1 is probably a better solution.
There are performance penalties to using Pkg in the resulting binary so it may be we see performance improvements by pursuing either of these alternatives in our own definitions.
I definitely see that penalty on macOS (especially due to the Rosetta requirement).
I definitely see that penalty on macOS (especially due to the Rosetta requirement).
We just published a release with native ARM binaries for macOS which has much improved performance over the version running via Rosetta. There's still a small overhead for running in pkg
but overall it's a much better experience.
I recommend you try it out!
@TimBeyer thanks! I upgraded to the new version: https://github.com/sagikazarmark/nix-garden/commit/8d05717d369ed55a06bc294e51142fd477d23508
It is indeed somewhat better.
Looking at the latest release note I noticed there is a self-update option. @worldofgeese I think it would be nice if we could disable it somehow in the nix packaged version.
@sagikazarmark I'm working on this after work hours so I won't be the fastest person in the world but I made some good progress today! I found a yarn package definition for Guix (make sure it's 1.* because we're not compatible with 2), built it, opened a shell into its definition (guix shell -f yarn.scm
), cloned the garden
repo, ran yarn build && yarn install
(you need to build to get some of the dependencies like open-tracing
) then ran cli/bin/garden
and... it works! Or at least the CLI shows me a list of arguments: so far so good.
Next steps will be to compose these steps into a definition, which I've already started on.
@worldofgeese I also started to work on a definition here: https://github.com/sagikazarmark/nix-garden/commit/b621f9ff5c7f01266da23d865d4a33f42561cf51
Unfortunately, yarn build fails with the following error:
[1/0/3 built, 0.0 MiB DL] building garden (configurePhase): configuringdirenv: ([/nix/store/2fq15zs5fq3ag5ynfxxaa3nw6ys0z6i9-direnv-2.32.3/bin/direnv export zsh]) is taking a while to execute. Use CTRL-C to give up.
error: builder for '/nix/store/fs4p6223viqjdcgkh1cillma9jw61k2y-garden.drv' failed with exit code 1;
last 10 log lines:
> core āāāāāāāāāāāāāāāāāāāāāā $ ./scripts/run-script.ts clean && find . -name ".garden" -type d -prune -exec rm -rf '{}' '+'
> core āāāāāāāāāāāāāāāāāāāāāā SyntaxError: Unexpected token in JSON at position 0
> core āāāāāāāāāāāāāāāāāāāāāā error Command failed with exit code 1.
> core āāāāāāāāāāāāāāāāāāāāāā info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
>
> clean script in package @garden-io/core failed with code 1
> error Command failed with exit code 1.
> info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
> error Command failed with exit code 1.
> info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
For full logs, run 'nix log /nix/store/fs4p6223viqjdcgkh1cillma9jw61k2y-garden.drv'.
Unfortunately, it doesn't tell more about what the problem is.
It could be some automagic, that mkYarnPackage does (I noticed for example that garden utilizes workspaces), but I haven't been able to figure out the problem so far.
I have two suggestions for making progress at this point:
I understand the time constraints, so I think it makes sense to not duplicate efforts.
What do you think?
@sagikazarmark I built a garden
Guix package definition that uses yarn
to build but ran into the wrinkle that Guix build environments are not network-capable.
Looking at your Nix package and based on mkYarnPackage
's Nix definition it looks like it takes a version argument. Could you try and pass any version of yarn
version 1 to it? garden
will only build with v1.
In any case, based on our shared difficulties, I suggest creating an NPM package of garden
, then using Nix and Guix's native Node build methods to source it. I was going to try to yarn publish
to my own NPM namespace now and see if that works and if not, investigate what we'd need to get a functional NPM package. To that end, @stefreak indicated the static directory and the nodejs options that we need to control may be tricky to solve for. Once they are, it should be trivial to package for Nix and Guix.
Happy to work on any common repo with the objective of getting these accepted into their respective homes (Nixpkgs and nonguix)!
@worldofgeese great news!
Since the binary distribution works rather well at the moment, I think it makes sense to wait for an NPM package instead of struggling to come up with a build definition (that may never work).
One thing that doesn't work with the NPM definition is disabling self-update though (which is a bit unfortunate, but not the end of the world).
@sagikazarmark your original approach should work fine, can you maybe dig deeper into why clean
fails with that JSON error?
run-script.ts clean
basically runs yarn clean
in every single package directory. To do that, it reads the definition of the clean
task from the package.json
.
The output contains the log line clean script in package @garden-io/core failed with code 1
which suggests that it tried to read the package.json
In core/
.
Does the core/package.json
contain a weird character at the beginning of the file? Can you share with us the output of hexdump -C core/package.json
?
@stefreak @sagikazarmark I have a PR I'm hoping to get up end of day today that adds an NPM package to simplify this process. You can already try it with npx @worldofgeese/cli
. I will write back here when it's up for review.
I've tested with my own projects and it works great for all commands I've tested. In fact, it is significantly faster in all operations.
EDIT: it's up without any context. I will add more details later tonight or by the morning.
We re-did how we build Garden and implemented a new binary shipping mechanism (garden-sea
)
We now implement some environment variables in this wrapper binary: https://github.com/garden-io/garden/blob/main/garden-sea/src/node.rs#L43C12-L43C12
Namely GARDEN_MAX_SEMI_SPACE_SIZE
, GARDEN_MAX_OLD_SPACE_SIZE
, and GARDEN_SEA_UV_USE_IO_URING
.
We also updated Node.js to 21.1
in the mean time. Should we try again with the npm run dist
approach (https://docs.garden.io/v/edge-release/contributing-to-garden/developing-garden#release-binaries-and-docker-containers) or do we need to go down the NPM package path? With the NPM package we'd have less control over NodeJS versions and these kind of low level NodeJS settings.
If we want to go down the NPM package path, #4477 is resolved now so the NPM PR is unblocked and we can continue working on it.
Feature Request
Background / Motivation
I use Nix as my package manager for macOS and Linux.
What should the user be able to do?
Install garden using Nix.
Why do they want to do this? What problem does it solve?
Nix is particularly useful in creating portable development environments. Since garden is often used for development, integrating it into such environments is crucial.
Suggested Implementation(s)
Create a Nix package.
How important is this feature for you/your team?
šµ Not having this feature makes using Garden painful
Additional information
There is already a closed issue asking for a Nix package: #2785
I decided to open a new issue, because I'd be happy to do the work, but I'd need some assistance because I'm not intimately familiar how Node CLIs are packaged (particularly garden seems to require some additional files for it to run).
What I need to be able to create a Nix package:
I tried following the contributing guide, but it's not obvious what the output of
yarn build
is.Any assistance would be greatly appreciated.
Thanks!