Skip to content

Instantly share code, notes, and snippets.

@brettjrea
Last active May 9, 2024 19:26
Show Gist options
  • Save brettjrea/95d988fb0baf00da9ee9b53e46be0403 to your computer and use it in GitHub Desktop.
Save brettjrea/95d988fb0baf00da9ee9b53e46be0403 to your computer and use it in GitHub Desktop.

First runs with anything nix can take a good while as it finds the cached packages and downloads them or builds from source! Subsequent runs will be faster as they are now loaded into your store and it just looks to add or remove any changes to an existing derivation. Nix uses Hashes to compare files and by default will try to find an existing binaries hash in the store before it rebuilds or downloads it.

Single User Installation

To explicitly select a single-user installation on your system:

$ bash <(curl -L https://nixos.org/nix/install) --no-daemon

In a single-user installation, /nix is owned by the invoking user. The script will invoke sudo to create /nix if it doesn’t already exist. If you don’t have sudo, manually create /nix as rootand run the bash script again.

swap alice for user

$ su root
# mkdir /nix
# chown alice /nix

Restart terminal or use the following to start using it right away.

. /home/userland/.nix-profile/etc/profile.d/nix.sh`

I thought below was for the flakes only, but its also for the nix-command error so I just run it.

Might not be neccesary if you used determinate systems installer need to verify.

mkdir -p ~/.config/nix && echo 'experimental-features = nix-command flakes
' >> ~/.config/nix/nix.conf

Single User uninstall

To remove a single-user installation of Nix, run:

$ rm -rf /nix ~/.nix-channels ~/.nix-defexpr ~/.nix-profile

You might also want to manually remove references to Nix from your ~/.profile.


The Fastest way I found to get a prebuilt binary into the store and executing.

Adds file to store.

nix store prefetch-file https://github.com/wasmCloud/wasmCloud/releases/download/wash-cli-v0.27.0/wash-x86_64-unknown-linux-musl

Fixes permissions.

chmod 755 /nix/store/9an7c6l3fbidz67rd6naca4g2symxq4g-wash-x86_64-unknown-linux-musl

Test that the binary is installed by running full path it's not installed into shell yet or symlinked.

./nix/store/9an7c6l3fbidz67rd6naca4g2symxq4g-wash-x86_64-unknown-linux-musl


Using Flakes to build a project binary.

The following was derived for Wasmcloud from the repo in an attempt to isolate some of the commands into a more scoped flake and get the latest version into my packages. I will try to get some more generalized examples in future but I think this excercise might help you reason how to do this on your own.

The 'nix-command flakes' is aliased already I just haven't tested all commands in different variations yet and am trying to stay true to what I have pulled from the Dockerfile.

Clone Repo:

git clone https://github.com/wasmCloud/wasmCloud.git

Run the original flake.nix this builds the binaries to ./result

nix --accept-flake-config --extra-experimental-features 'nix-command flakes' build -L ".#wasmcloud${TARGET}"

I deleted the created files to test and I needed the --rebuild command to force a rebuild.

nix --accept-flake-config --extra-experimental-features 'nix-command flakes' build -L ".#wasmcloud${TARGET}" --rebuild

A workaround to get another flake to run.

Now I put the following in a different default.nix so that it will run when I run nix build without the experimental flake command.

I am not sure how it worked since the command is aliased but it does I might need to recheck if it was truelly aliased or not for me

I need my default.nix to do these things from the Dockerfile.

install -Dp ./result/bin/wash /out/wash
install -Dp ./result/bin/wasmcloud /out/wasmcloud
--chmod=755 /out/wash /bin/wash
--chmod=755 /out/wasmcloud /bin/wasmcloud

This default.nix sets r/w attributes, puts it in the right folder and most importantly uses autopatchelf to patch the runtime for nix.

This is what it looks like in the file.

cd into .result/

add the following default.nix.

default.nix

{ stdenv, autoPatchelfHook }:

stdenv.mkDerivation rec {
  pname = "wasmcloud-binaries";
  version = "1.0";

  src = ./.; # Assuming the binaries are in the current directory

  nativeBuildInputs = [ autoPatchelfHook ];

  installPhase = ''
    install -D $src/out/wash $out/bin/wash
    install -D $src/out/wasmcloud $out/bin/wasmcloud
  '';

  meta = with stdenv.lib; {
    description = "wasmCloud Binaries";
    homepage = "https://wasmcloud.com";
    license = licenses.mit;
    platforms = platforms.unix;
  };
}

Gather Intel.

You will need to gather the package name for the next nix file to call it.

Lets quickly go check the /nix/store and confirm the packages are there gather any intel.

Run cd /nix/store/ once in the folder search for package find -name *wash*.


Now that the packages are either downloaded or built from source I want to use it in a custom shell.

Now add the shell.nix remember to update package to match your unique packages name and run nix shell this will add packages to your current shell for use.

{ pkgs ? import <nixpkgs> {} }:

pkgs.mkShell {
  buildInputs = [
    pkgs.02hzx0lagp1fwbkwf4f229jfgdp48f9v-wasmcloud-1.0.0/bin/wash
    pkgs.02hzx0lagp1fwbkwf4f229jfgdp48f9v-wasmcloud-1.0.0/bin/wasmcloud
  ];
}

Putting it all together for a full and complete development environment in one flake.

After you have either built or downloaded the binaries and got them installed in the nix/store.

You should have tested via manually invoking a path and getting a successful output by this point and have a clear idea of the binaries path as we are going to place it in the bottom of the file where we add this path to our shell.

We can tie it into a flake.nix that will setup a fuller and more complete development environment.

{
  description = "A flake template for Webassembly, that includes custom wasmCloud binaries in the shell";

  # Flake inputs
  inputs.nixpkgs.url = "https://flakehub.com/f/NixOS/nixpkgs/0.1.*.tar.gz";


  # Flake outputs
  outputs = { self, nixpkgs }:
    let

      # Overlay
      goVersion = 22;
      overlays = [
        (final: prev: rec {
          nodejs = prev.nodejs_latest;
          pnpm = prev.nodePackages.pnpm;
          yarn = (prev.yarn.override { inherit nodejs; });
          go = prev."go_1_${toString goVersion}";
        })
      ];



      # The systems supported for this flake
      supportedSystems = [
        "x86_64-linux" # 64-bit Intel/AMD Linux
        "aarch64-linux" # 64-bit ARM Linux
        "x86_64-darwin" # 64-bit Intel macOS
        "aarch64-darwin" # 64-bit ARM macOS
      ];

      # Helper to provide system-specific attributes
      forEachSupportedSystem = f: nixpkgs.lib.genAttrs supportedSystems (system: f {
         pkgs = import nixpkgs { inherit system; overlays = overlays; };

      });

    in

    {
      devShells = forEachSupportedSystem ({ pkgs }: {
        default = pkgs.mkShell {
          # The Nix packages provided in the environment
          # Add any you need here
          packages = with pkgs; [

            # CI
              cachix
              direnv
              nix-direnv

            # System Utilities

              autoconf
              automake
              bash
              bison
              bzip2
              ccache
              cmake
              curl
              file
              flex
              gettext
              git
              gnupg
              intltool
              lsb-release
              om4
              gnumake
              meson
              mold
              nano
              openssh
              parallel
              gnupatch
              patchelf
              perl
              pkgconf
              libpkgconf
              python311Packages.pip
              ragel
              rsync
              sudo
              proot
              tzdata
              xz
              zip
              zstd
              jq
              openssl
              pkg-config


            # Pulumi Utilities

              # pulumi-watch
              # pulumi-analyzer-* utilities
              # pulumi-language-* utilities
              # pulumi-resource-* utilities
              # pulumi-bin

            # SDKs

              # Python SDK:
              python311

              # Go SDK:
              go_1_22

              # Node.js SDK:
              nodejs
              node2nix
              corepack_20

              # .NET SDK:
              dotnet-sdk_6
              dotnet-sdk_8

              # Java SDK:
              jdk
              maven

              # Rust SDK:
              rustc
              cargo
              rustup

              # Zig SDK:
              zig

              # Emscripten SDK:
              emscripten

              # Kubernetes

              kubectl

              # Miscellaneous Utilities

              jq

              # Python Tools

              # pip

              python311Packages.pip
              pipenv

              # PHP Tools

              php

              # Go Tools
              gotools

              # Go Lint
              golangci-lint

              #tinygo
              tinygo

              # Rust Tools

              cargo-deny
              cargo-edit
              cargo-wasi
              cargo-watch
              rust-analyzer

              # WebAssembly Tools

              # wasm-bindgen
              wasm-pack
              wasm-tools
              wabt
              wazero
              wasmedge
              wasmer
              wasmtime
              
              #Wasmcloud dependencies
              nats-server

          ];

          # Set any environment variables for your dev shell
          env = { };

          # Add any shell logic you want executed any time the environment is activated
          shellHook = ''
            export PATH=$PATH:/nix/store/02hzx0lagp1fwbkwf4f229jfgdp48f9v-wasmcloud-1.0.0/bin/
          '';
        };
      });
    };
}
Android Userland Ubuntu

The following is for Ubuntu on Android userland I have to recheck it on WSL2. These instructions might be simpler and supercede the above. As well the Wasmcloud binary we are installing has a known out of memory issue on low ram devices. If you get the error it means you did it right. The fix might already be patched need to check releases but it would mean I need to rewrite the tutorial with the new binary hash which I don't have time to backtrack just yet.

Dependencies

sudo apt update && sudo apt upgrade && sudo apt autoremove
cat /etc/ssl/certs/ca-certificates.crt
sudo apt install ca-certificates xz-utils git curl build-essential cmake unzip
sudo update-ca-certificates

Rust

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
. "$HOME/.cargo/env"
rustup target add wasm32-wasi

NIX

bash <(curl -L https://nixos.org/nix/install) --no-daemon

Replace userland with your current user.

mkdir -m 0755 /nix && chown userland /nix

If you had to manually create nix folder (likely) rerun bash script then move to the next command to make the Nix command usable.

. /home/userland/.nix-profile/etc/profile.d/nix.sh
mkdir -p ~/.config/nix && echo 'experimental-features = nix-command flakes
' >> ~/.config/nix/nix.conf

External Nats-Server

This might be unneccessary, one seems to be in the cli already. Need to verify.

curl -L https://github.com/nats-io/nats-server/releases/download/v2.10.14/nats-server-v2.10.14-linux-arm64.zip -o nats-server.zip
unzip nats-server.zip -d nats-server
sudo cp nats-server/nats-server-v2.10.14-linux-arm64/nats-server /usr/bin
/usr/bin/nats-server -a 127.0.0.1 &

wasmCloud Binary

nix store prefetch-file https://github.com/wasmCloud/wasmCloud/releases/download/wash-cli-v0.27.0/wash-aarch64-unknown-linux-musl
/nix/store/xk3nrbk3f73afb2g4p28pnfr495hc370-wash-aarch64-unknown-linux-musl
chmod +x /nix/store/xk3nrbk3f73afb2g4p28pnfr495hc370-wash-aarch64-unknown-linux-musl

I am using the full path for now which is good because it shows the unique hash and how versioning and reproducibility work.

/nix/store/xk3nrbk3f73afb2g4p28pnfr495hc370-wash-aarch64-unknown-linux-musl up

Another way to test if binary works outside of the Nix store for sanity checks.

sudo chown 755 /nix/store/xk3nrbk3f73afb2g4p28pnfr495hc370-wash-aarch64-unknown-linux-musl
cp /nix/store/xk3nrbk3f73afb2g4p28pnfr495hc370-wash-aarch64-unknown-linux-musl ~/wash
chmod 755 ~/wash
./wash

Create Rust Project

/nix/store/xk3nrbk3f73afb2g4p28pnfr495hc370-wash-aarch64-unknown-linux-musl new component hello --template-name hello-world-rust
cd hello
/nix/store/xk3nrbk3f73afb2g4p28pnfr495hc370-wash-aarch64-unknown-linux-musl app deploy wadm.yaml
/nix/store/xk3nrbk3f73afb2g4p28pnfr495hc370-wash-aarch64-unknown-linux-musl app list

Test project

curl localhost:8080
{ stdenv, autoPatchelfHook }:
stdenv.mkDerivation rec {
pname = "wasmcloud-binaries";
version = "1.0";
src = ./.; # Assuming the binaries are in the current directory
nativeBuildInputs = [ autoPatchelfHook ];
installPhase = ''
install -D $src/out/wash $out/bin/wash
install -D $src/out/wasmcloud $out/bin/wasmcloud
'';
meta = with stdenv.lib; {
description = "wasmCloud Binaries";
homepage = "https://wasmcloud.com";
license = licenses.mit;
platforms = platforms.unix;
};
}
{
description = "An empty flake template that you can adapt to your own environment";
# Flake inputs
inputs.nixpkgs.url = "https://flakehub.com/f/NixOS/nixpkgs/0.1.*.tar.gz";
# Flake outputs
outputs = { self, nixpkgs }:
let
# The systems supported for this flake
supportedSystems = [
"x86_64-linux" # 64-bit Intel/AMD Linux
"aarch64-linux" # 64-bit ARM Linux
"x86_64-darwin" # 64-bit Intel macOS
"aarch64-darwin" # 64-bit ARM macOS
];
# Helper to provide system-specific attributes
forEachSupportedSystem = f: nixpkgs.lib.genAttrs supportedSystems (system: f {
pkgs = import nixpkgs { inherit system; };
});
in
{
devShells = forEachSupportedSystem ({ pkgs }: {
default = pkgs.mkShell {
# The Nix packages provided in the environment
# Add any you need here
packages = with pkgs; [ ];
# Set any environment variables for your dev shell
env = { };
# Add any shell logic you want executed any time the environment is activated
shellHook = ''
'';
};
});
};
}
/* This Flake Fetch's a prebuilt Wasmcloud binary, auto */
{
description = "wasmcloud";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs";
};
outputs = { self, nixpkgs }:
{
defaultPackage.x86_64-linux =
with import nixpkgs { system = "x86_64-linux"; };
stdenv.mkDerivation rec {
name = "wasmcloud-${version}";
version = "1.0.0";
src = pkgs.fetchurl {
url = "https://github.com/wasmCloud/wasmCloud/releases/download/v1.0.0/wasmcloud-x86_64-unknown-linux-musl";
sha256 = "sha256:0a49pqvlsq5ldq95rmph0zrq0qlfb97f6k9kr8qxf6y11pgxmq30";
};
nativeBuildInputs = [
autoPatchelfHook
];
sourceRoot = ".";
installPhase = ''
install -m755 -D wasmcloud $out/bin/wasmcloud
'';
meta = with lib; {
homepage = "https://wasmcloud.org";
description = "wasmcloud";
platforms = platforms.linux;
};
};
defaultPackage.aarch64-linux =
with import nixpkgs { system = "aarch64-linux"; };
stdenv.mkDerivation rec {
name = "wasmcloud-${version}";
version = "1.0.0";
src = pkgs.fetchurl {
url = "https://github.com/wasmCloud/wasmCloud/releases/download/v1.0.0/wasmcloud-aarch64-linux-android";
sha256 = "sha256:0rm11chn0754w50nl50118h8ik6r59n9njsj25ark7nf26kklcrf";
};
nativeBuildInputs = [
autoPatchelfHook
];
sourceRoot = ".";
installPhase = ''
install -m755 -D wasmcloud $out/bin/wasmcloud
'';
meta = with lib; {
homepage = "https://wasmcloud.org";
description = "wasmcloud";
platforms = platforms.linux;
};
};
};
}
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
buildInputs = [
pkgs.02hzx0lagp1fwbkwf4f229jfgdp48f9v-wasmcloud-1.0.0/bin/wash
pkgs.02hzx0lagp1fwbkwf4f229jfgdp48f9v-wasmcloud-1.0.0/bin/wasmcloud
];
}
{
description = "A flake template for Webassembly, that includes custom wasmCloud binaries in the shell";
# Flake inputs
inputs.nixpkgs.url = "https://flakehub.com/f/NixOS/nixpkgs/0.1.*.tar.gz";
# Flake outputs
outputs = { self, nixpkgs }:
let
# Overlay
goVersion = 22;
overlays = [
(final: prev: rec {
nodejs = prev.nodejs_latest;
pnpm = prev.nodePackages.pnpm;
yarn = (prev.yarn.override { inherit nodejs; });
go = prev."go_1_${toString goVersion}";
})
];
# The systems supported for this flake
supportedSystems = [
"x86_64-linux" # 64-bit Intel/AMD Linux
"aarch64-linux" # 64-bit ARM Linux
"x86_64-darwin" # 64-bit Intel macOS
"aarch64-darwin" # 64-bit ARM macOS
];
# Helper to provide system-specific attributes
forEachSupportedSystem = f: nixpkgs.lib.genAttrs supportedSystems (system: f {
pkgs = import nixpkgs { inherit system; overlays = overlays; };
});
in
{
devShells = forEachSupportedSystem ({ pkgs }: {
default = pkgs.mkShell {
# The Nix packages provided in the environment
# Add any you need here
packages = with pkgs; [
# CI
cachix
direnv
nix-direnv
# System Utilities
autoconf
automake
bash
bison
bzip2
ccache
cmake
curl
file
flex
gettext
git
gnupg
intltool
lsb-release
om4
gnumake
meson
mold
nano
openssh
parallel
gnupatch
patchelf
perl
pkgconf
libpkgconf
python311Packages.pip
ragel
rsync
sudo
proot
tzdata
xz
zip
zstd
jq
openssl
pkg-config
# Pulumi Utilities
# pulumi-watch
# pulumi-analyzer-* utilities
# pulumi-language-* utilities
# pulumi-resource-* utilities
# pulumi-bin
# SDKs
# Python SDK:
python311
# Go SDK:
go_1_22
# Node.js SDK:
nodejs
node2nix
corepack_20
# .NET SDK:
dotnet-sdk_6
dotnet-sdk_8
# Java SDK:
jdk
maven
# Rust SDK:
rustc
cargo
rustup
# Zig SDK:
zig
# Emscripten SDK:
emscripten
# Kubernetes
kubectl
# Miscellaneous Utilities
jq
# Python Tools
# pip
python311Packages.pip
pipenv
# PHP Tools
php
# Go Tools
gotools
# Go Lint
golangci-lint
#tinygo
tinygo
# Rust Tools
cargo-deny
cargo-edit
cargo-wasi
cargo-watch
rust-analyzer
# WebAssembly Tools
# wasm-bindgen
wasm-pack
wasm-tools
wabt
wazero
wasmedge
wasmer
wasmtime
#Wasmcloud dependencies
nats-server
];
# Set any environment variables for your dev shell
env = { };
# Add any shell logic you want executed any time the environment is activated
shellHook = ''
export PATH=$PATH:/nix/store/02hzx0lagp1fwbkwf4f229jfgdp48f9v-wasmcloud-1.0.0/bin/
'';
};
});
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment