<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"
    xmlns:dc="http://purl.org/dc/elements/1.1/">
    <channel>
        <title>nixbuild.net blog</title>
        <link>https://blog.nixbuild.net</link>
        <description><![CDATA[nixbuild.net blog]]></description>
        <atom:link href="https://blog.nixbuild.net/index.xml" rel="self"
                   type="application/rss+xml" />
        <lastBuildDate>Mon, 01 Sep 2025 00:00:00 UT</lastBuildDate>
        <item>
    <title>OIDC support in nixbuild.net</title>
    <link>https://blog.nixbuild.net/posts/2025-09-01-oidc-support-in-nixbuild-net.html</link>
    <description><![CDATA[<p>nixbuild.net now supports <a href="https://openid.net/developers/how-connect-works/">OpenID
Connect</a> (OIDC)!</p>
<p>This means that you can create <a href="https://docs.nixbuild.net/access-control/#using-auth-tokens">auth
tokens</a> that are
only usable if you also can provide an OIDC JWT signed by a specific identity
provider. In practice, you can now configure your GitHub Actions workflow with
a nixbuild.net auth token that can only be used from within GitHub’s
infrastructure. You can even lock it down to specific GitHub repositories. This
is a great step forward in securing nixbuild.net’s authentication and
authorization.</p>
<p>This new feature is not specific to GitHub, but can be used together with any
OIDC provider. Additionally, it is implemented on top of the existing
<a href="https://blog.nixbuild.net/posts/2023-09-22-biscuits-and-web-links.html">Biscuit</a>
support in nixbuild.net. This further validates the usefulness and flexibility
that nixbuild.net’s Biscuit policies provide.</p>
<p>Read on to find out exactly how it all fits together!</p>
<!--more-->
<h2 id="a-usage-example">A Usage Example</h2>
<p>Let’s illustrate how OIDC works in nixbuild.net by working our way through a
complete usage example. The repository used in this example is available for
inspection at <a href="https://github.com/nixbuild/nixbuild-oidc-auth-example">GitHub</a>.</p>
<p>Our objective is to configure a GitHub Actions workflow that uses nixbuild.net
to perform Nix builds. We want to make use of OIDC to secure the nixbuild.net
authentication and avoid the impact a workflow auth token leak could have.</p>
<p>We have three steps to go through:</p>
<ol type="1">
<li><p>Create a new nixbuild.net auth token with the base permissions needed for our
GitHub workflow.</p></li>
<li><p>Derive a new token from the original one, with a Biscuit policy that takes
the OIDC context into account. This process is called
<a href="https://docs.nixbuild.net/access-control/#token-attenuation">attenuation</a>
and is done offline from nixbuild.net, on your local computer. Arguably,
the nixbuild.net UI could offer a way to attach a Biscuit policy directly
during token creation, but there is no such functionality yet.</p></li>
<li><p>Create a GitHub Actions workflow that requests an OIDC JWT from GitHub and
passes it on to nixbuild.net.</p></li>
</ol>
<h3 id="step-1-create-a-base-token">Step 1: Create a Base Token</h3>
<p>Create a new nixbuild.net auth token using the nixbuild.net admin shell or the
<a href="https://nixbuild.net/settings/auth-tokens">web UI</a>. This token defines the
“upper limit” of what our workflow can do on nixbuild.net. Since you probably
want your workflow to be able to run builds on nixbuild.net, add the permissions
<code>build:read</code>, <code>build:write</code>, <code>store:read</code> and <code>store:write</code>, but leave out
<code>account:read</code> and <code>account:write</code>. You can set the expiration time to whatever
makes sense to you. It is possible to set a shorter expiration time on the
attenuated token (next step) if you like.</p>
<p>The token generated in this step can be kept entirely offline, and you can then
derive new tokens from it whenever you like. Or, you could simply throw away
this base token once you have created an attenuated token. Just remember to not
<em>revoke</em> the base token in nixbuild.net because that will implicitly revoke all
derived tokens too.</p>
<p>If you use the web UI, creating the token should look something like this:</p>
<p><img src="/img/2025-09-01-oidc-support-in-nixbuild-net_create-token.png" width="400" /></p>
<p>The created token is a long string of randomly-looking characters. Store this
string to a file on your computer and treat it as a secret. If anyone gets their
hands on it, they will be able to run builds on nixbuild.net, possibly
incurring costs to your account.</p>
<h3 id="step-2-attenuate-the-base-token">Step 2: Attenuate the Base Token</h3>
<p>Now we want to create a token with more restrictions than the base token. This
restricted token will be used by your GitHub workflow. The process of creating
a new token from an existing one is called “attenuation”, in Biscuit lingo.</p>
<p>To perform attenuation you need the Biscuit CLI tool, <code>biscuit-cli</code>. It is
available in <code>nixpkpgs</code>:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> nix shell nixpkgs#biscuit-cli</span></code></pre></div>
<p>You can use this tool to inspect your base token (stored in the file
<code>base.token</code> in this example):</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> biscuit inspect base.token</span></code></pre></div>
<p>In the printed output you should be able to see the permissions and expiration
time that you selected during token creation.</p>
<p>Now we’ll write a <a href="https://doc.biscuitsec.org/getting-started/authorization-policies.html">Biscuit authorization
policy</a>
that restricts token usage to only work from within GitHub Actions workflows
for the <code>nixbuild/nixbuild-oidc-auth-example</code> repository:</p>
<pre><code>check if
  jwt_claim(&quot;iss&quot;, &quot;https://token.actions.githubusercontent.com&quot;);

check if
  jwt_claim(&quot;sub&quot;, $sub),
  $sub.contains(&quot;repo:nixbuild/nixbuild-oidc-auth-example&quot;);</code></pre>
<p>We add two <code>check</code> statements, which say what must hold true for
authorization to succeed. <code>jwt_claim</code> refers to a <a href="https://doc.biscuitsec.org/reference/datalog.html#facts">Biscuit
fact</a> that is added by
nixbuild.net if it has been provided an OIDC JWT and been able to verify the
signature of the JWT. We’ll talk more about how the JWTs are passed to
nixbuild.net in the next section.</p>
<p>nixbuild.net will not add <em>all</em> JWT claims as Biscuit facts, since it would
make the authorization process computationally more expensive. But it adds the
<code>iss</code> and <code>sub</code> claims, which are used above. In our policy, we first verify
the <code>iss</code> claim. When nixbuild.net receives a JWT with an <code>iss</code> claim, it will
use <a href="https://openid.net/specs/openid-connect-discovery-1_0.html">OIDC
Discovery</a> to find
out which endpoint to ask for public keys to perform JWT verification. This is
what makes the OIDC support in nixbuild.net generic. You could even host your
own identity provider, as long as it supports OIDC Discovery.</p>
<p>So, when our policy checks that the <code>iss</code> claim is
<code>https://token.actions.githubusercontent.com</code>, we can be sure that the provided
JWT was <a href="https://docs.github.com/en/actions/reference/security/oidc">issued by
GitHub</a>.</p>
<p>Furthermore, in GitHub’s <a href="https://docs.github.com/en/actions/reference/security/oidc#configuring-the-subject-in-your-cloud-provider">reference
documentation</a>
we can see that the <code>sub</code> claim will include the owner and name of the repo
that created the OIDC JWT. We use that information to write our second policy
check. GitHub encodes more information in the <code>sub</code> claim that can be useful
for authouring Biscuit policies. Check out their documentation for details!
Also be sure to read through the Biscuit <a href="https://doc.biscuitsec.org/reference/datalog.html">language
documentation</a> to find out
what functions and operators you can use in your policies! There is also a
helpful Bisuit
<a href="https://www.biscuitsec.org/docs/tooling/datalog-playground/">playground</a>
available.</p>
<p>Finally, we save our policy to a file (<code>gha-oidc.biscuit</code> in this example) and
then use the Biscuit CLI to attach the policy to our base token, creating a
new, <em>attenuated</em>, token:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> biscuit attenuate <span class="at">--block-file</span> gha-oidc.biscuit base.token <span class="op">&gt;</span> gha-oidc.token</span></code></pre></div>
<p>If you run <code>biscuit inspect gha-oidc.token</code> you should see that it includes our
new policy.</p>
<p>Lets do a quick sanity check to see that the token actually can’t be used
outside GitHub. We do this by performing a <code>HEAD</code> request against the <code>/builds</code>
endpoint of the nixbuild.net HTTP API, once with the base token and once with
the attenuated token:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> curl <span class="at">-sIH</span> <span class="st">&quot;Authorization: Bearer </span><span class="va">$(</span><span class="fu">cat</span> base.token<span class="va">)</span><span class="st">&quot;</span> https://api.nixbuild.net/builds</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a><span class="ex">HTTP/2</span> 200</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a><span class="ex">server:</span> nginx</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a><span class="ex">date:</span> Thu, 28 Aug 2025 09:31:47 GMT</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a><span class="ex">content-type:</span> application/json<span class="kw">;</span><span class="va">charset</span><span class="op">=</span>utf-8</span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> curl <span class="at">-sIH</span> <span class="st">&quot;Authorization: Bearer </span><span class="va">$(</span><span class="fu">cat</span> gha-oidc.token<span class="va">)</span><span class="st">&quot;</span> https://api.nixbuild.net/builds</span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a><span class="ex">HTTP/2</span> 403</span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a><span class="ex">server:</span> nginx</span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a><span class="ex">date:</span> Thu, 28 Aug 2025 09:32:02 GMT</span></code></pre></div>
<p>Looks good! Now lets see how to use the token in an actual GitHub Actions
workflow.</p>
<h3 id="step-3-create-a-github-workflow">Step 3: Create a GitHub Workflow</h3>
<p>The action
<a href="https://github.com/marketplace/actions/nixbuild-net">nixbuild/nixbuild-action</a>
is the preferred way of configuring nixbuild.net in GitHub Actions workflows,
and since <a href="https://github.com/nixbuild/nixbuild-action/releases/tag/v21">v21</a>
it supports generating an OIDC ID Token and passing it on to nixbuild.net
automatically.</p>
<p>Here is a simple workflow that does this:</p>
<pre><code>name: oidc-test

on: push

jobs:

  oidc-example:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    steps:
      - name: Install Nix
        uses: nixbuild/nix-quick-install-action@v33

      - name: Configure nixbuild.net
        uses: nixbuild/nixbuild-action@v21
        with:
          nixbuild_token: ${{ secrets.nixbuild_token }}
          oidc: true

      - name: Run a simple test build on nixbuild.net
        run: |
          export DRV_SEED=&quot;$RANDOM$RANDOM&quot;
          nix build github:nixbuild/nixbench#write-one-file \
            --impure \
            --eval-store auto \
            --store ssh-ng://eu.nixbuild.net \
            --print-build-logs</code></pre>
<p>The important pieces are the <code>id-token: write</code> permission (allows OIDC ID
Tokens to be fetched from GitHub), the <code>oidc: true</code> setting for
<code>nixbuild/nixbuild-action</code> (enables the mechanism that fetches and passes OIDC
ID Tokens on to nixbuild.net) and the <code>nixbuild_token</code> secret (should be set to
the attenuated Biscuit token).</p>
<p>The above workflow is all it takes to integrate GitHub’s OIDC with
nixbuild.net. If you are using some other OIDC Provider, or if you’re not
using <code>nixbuild-action</code> you should pass in your OIDC ID Token to nixbuild.net
by setting the SSH environment variable (or HTTP header, if you’re using the
HTTP API) named <code>NIXBUILDNET_OIDC_ID_TOKEN</code>. The OIDC ID Token should have
the audience <code>nixbuild.net</code>.</p>]]></description>
    <pubDate>Mon, 01 Sep 2025 00:00:00 UT</pubDate>
    <guid>https://blog.nixbuild.net/posts/2025-09-01-oidc-support-in-nixbuild-net.html</guid>
    <dc:creator>support@nixbuild.net</dc:creator>
</item>
<item>
    <title>A Batch of nixbuild.net Updates</title>
    <link>https://blog.nixbuild.net/posts/2024-10-16-a-batch-of-nixbuild-net-updates.html</link>
    <description><![CDATA[<p>We have not written about nixbuild.net for over a year now, but that doesn’t
mean nothing has happened. Quite the opposite - we’ve been really busy!</p>
<p>This blog post will try to summarize some of what we have been working on
behind the scene the last couple of years. Read on to hear about nixbuild.net
going enterprise, a brand new web UI and lots of new functionality!</p>
<!--more-->
<h2 id="self-hosting-nixbuild.net">Self-Hosting nixbuild.net</h2>
<p>A big thing that has kept us busy the last year is packaging nixbuild.net for
self-hosting inside enterprise setups. We’ve had a number of companies reaching
out to us inquiring about such setups. The reason for wanting to self-host
nixbuild.net are several: internal legal requirements, network bottlenecks,
cost control and the ability to use hardware that is tricky to offer in the
public service.</p>
<p>One of our enterprise customers self-hosts nixbuild.net in production running
10K+ builds daily. A very welcome side-effect of adapting nixbuild.net for
self-hosting is that many scenarios that are seldom or never triggered by users
of our public service are uncovered by enterprise usage. This has made
nixbuild.net even more reliable and capable under high load.</p>
<p>We are in a stage where we are happy to work closely with companies, figuring out
how to best deploy and integrate nixbuild.net into their environments. Our
goal is to eventually be able to offer self-hosted nixbuild.net as an
off-the-shelf product. Actually, if you are on AWS, the deployment
of nixbuild.net is already very simple. We will publish a blog post with
more details on this in the near future, but the short rundown is this:</p>
<ul>
<li>We provide an EC2 AMI that runs NixOS and all necessary nixbuild.net services.</li>
<li>The user deploys this AMI using her preferred method of EC2 provisioning.</li>
<li>The user provides nixbuild.net configuration through <code>cloud-init</code> or by simply
putting configuration files in place on the EC2 instance.</li>
<li>The nixbuild.net configuration includes details on what types of EC2
instances to use for running the builds, and how many builder instances that
your nixbuild.net deployment should be allowed to provision.</li>
</ul>
<p>You can then simply use your nixbuild.net EC2 server as remote Nix builder, and
get all the nixbuild.net niceties of automatic builder provisioning,
scale-to-zero, automatic CPU and memory allocation, strict build isolation etc.</p>
<p>If your company is interested in self-hosting nixbuild.net, please <a href="mailto:sales@nixbuild.net">reach out to
us</a>!</p>
<h2 id="finally-a-web-ui">Finally, a Web UI</h2>
<p>We are proud to say that we now have a brand-new <a href="https://nixbuild.net/sign-in">web
UI</a> available to all nixbuild.net users! This
includes a much simplified sign-up flow, where the
<a href="https://www.hanko.io/">Hanko</a> service is used to provide and secure users’
login details. It is now easier than ever getting started with nixbuild.net!</p>
<p>The web UI is a complement to the tried-and-true <a href="https://docs.nixbuild.net/configuration/#the-nixbuildnet-shell">SSH-based admin
shell</a>. We are
gradually building out the web functionality to cover everything you can do in
the shell today, and more. For the moment you can get by using the web UI to
get started with nixbuild.net, adding SSH keys or creating access tokens. For
configuring settings or setting up billing you will still need to use the
nixbuild.net shell.</p>
<p>Our plan ahead is to keep the SSH-based shell which is very appreciated by many
users and offers an efficient interface for managing your nixbuild.net account.
The web UI will be expanded with full ability to manage your account, as well as
pages to present and visualize builds and Nix store contents in ways that the
terminal shell cannot.</p>
<h2 id="support-for-more-types-of-caches-and-substituters">Support for More Types of Caches and Substituters</h2>
<p>During the last year, nixbuild.net has gained new support for S3 and improved
support for <a href="https://www.cachix.org">Cachix</a>.</p>
<p>nixbuild.net can now use the following sources when substituting (downloading)
cached store paths:</p>
<ul>
<li>Public HTTP caches, like <code>cache.nixos.org</code></li>
<li>Public Cachix caches</li>
<li>Authenticated Cachix caches</li>
<li>S3 buckets (AWS or compatible providers)</li>
</ul>
<p>For more information, see the documentation for the
<a href="https://docs.nixbuild.net/settings/#substituters">substituters</a> setting.
nixbuild.net can use multiple substituters of different types at the same time.
It tries to do as much as possible in parallel, for example, all substituters
are queried concurrently about available <code>narinfo</code> files. The substituter that
answers first is used.</p>
<p>nixbuild.net can also populate binary caches, not only with build outputs but
also their inputs. By activating this functionality, you don’t have to do any
post-build cache uploads from your Nix client machine, it will instead be
performed automatically by nixbuild.net as part of the build. Also in this case,
nixbuild.net will try to parallelize as much as possible. Build inputs will for
example start uploading at the same time the build starts.</p>
<p>nixbuild.net can now upload store paths to the following types of targets:</p>
<ul>
<li>Cachix caches</li>
<li>S3 buckets (AWS or any compatible provider)</li>
</ul>
<p>For more information, see the documentation for the
<a href="https://docs.nixbuild.net/settings/#caches">caches</a> setting.</p>
<h2 id="more-knobs-to-tweak">More Knobs to Tweak</h2>
<p>We have exposed more settings to end users lately. Some of these settings
existed internally already, and some are newly implemented.</p>
<p>These new settings correspond to the identically named Nix settings:</p>
<ul>
<li><a href="https://docs.nixbuild.net/settings/#hashed-mirrors">hashed-mirrors</a></li>
<li><a href="https://docs.nixbuild.net/settings/#impure-env">impure-env</a></li>
<li><a href="https://docs.nixbuild.net/settings/#max-silent-time">max-silent-time</a></li>
<li><a href="https://docs.nixbuild.net/settings/#timeout">timeout</a></li>
</ul>
<p>These new settings lets you control resource allocation:</p>
<ul>
<li><a href="https://docs.nixbuild.net/settings/#default-cpu">default-cpu</a></li>
<li><a href="https://docs.nixbuild.net/settings/#default-mem-per-cpu">default-mem-per-cpu</a></li>
<li><a href="https://docs.nixbuild.net/settings/#max-cpu">max-cpu</a></li>
<li><a href="https://docs.nixbuild.net/settings/#max-mem">max-mem</a></li>
<li><a href="https://docs.nixbuild.net/settings/#min-cpu">min-cpu</a></li>
<li><a href="https://docs.nixbuild.net/settings/#min-mem">min-mem</a></li>
</ul>
<p>For a complete list of settings, check out the
<a href="https://docs.nixbuild.net/settings">documentation</a>.</p>
<h2 id="support-for-custom-nix-store-directories">Support for Custom Nix Store Directories</h2>
<p>nixbuild.net supports using Nix store directories other than the default
<code>/nix/store</code> one. You don’t have do anything special in nixbuild.net to enable
this, it just works. If your Nix client is building something using a custom
Nix store directory, nixbuild.net will automatically setup the build sandbox
with the custom directory and make all build inputs available as usual.</p>
<h2 id="self-managed-signing-keys">Self-Managed Signing Keys</h2>
<p>By default, nixbuild.net creates a unique Nix <a href="https://docs.nixbuild.net/signing-keys/index.html#why-signing-keys">signing
key</a> for
every account. This key is used to sign all build outputs and all paths that
you upload to nixbuild.net. In practice this is not something you have to care
that much about. Nix doesn’t require remote builders to sign builds, and you
don’t have to setup your Nix client with the public keys that corresponds to
your account’s signing key. This is because Nix has roughly the same level of
trust for remote builds as for local builds.</p>
<p>However, inside nixbuild.net, Nix signatures are central, because the set of
store paths available in a session depends on which signatures are trusted in
that session. To control which signatures to trust, you can use the
<a href="/settings/#trusted-public-keys">trusted-public-keys</a> setting. Like all
settings, it can be specified on the SSH key level or even on the environment
of individual SSH sessions.</p>
<p>This flexibility is perhaps not useful to all nixbuild.net users, but it can
be valuable for power users that have embraced Nix signatures as a way to track
build provenance and control store access. For example, you could have your
deployment pipeline verify that only store paths signed by a specific key are
deployed to your production environment.</p>
<p>We have now added support for letting you control the signing keys that should
be used, instead of relying on keys auto-created by nixbuild.net. You can even
setup your configuration so that your secret signing keys are not persistently
stored in nixbuild.net, but only accessible by nixbuild.net during builds or
uploads.</p>
<p>To read more about Nix signing key in general and more details on how
nixbuild.net uses signing keys, check out our newly added
<a href="https://docs.nixbuild.net/signing-keys">documentation</a>. There you’ll also
learn about how to setup
<a href="https://docs.nixbuild.net/access-tokens">access-tokens</a> to lock down sub-users
of your nixbuild.net account to specific trusted public keys.</p>]]></description>
    <pubDate>Wed, 16 Oct 2024 00:00:00 UT</pubDate>
    <guid>https://blog.nixbuild.net/posts/2024-10-16-a-batch-of-nixbuild-net-updates.html</guid>
    <dc:creator>support@nixbuild.net</dc:creator>
</item>
<item>
    <title>Biscuits and Web Links</title>
    <link>https://blog.nixbuild.net/posts/2023-09-22-biscuits-and-web-links.html</link>
    <description><![CDATA[<p>About one year ago, we introduced an <a href="https://docs.nixbuild.net/api/">HTTP API</a>
for <a href="https://nixbuild.net">nixbuild.net</a>. This API can be used to retrieve
information about the builds you’ve run on the service. One place where the API
is used is in the GitHub Action
<a href="https://github.com/nixbuild/nixbuild-action">nixbuild-action</a> to create
detailed build summaries at the end of workflow runs.</p>
<p>When the API was launched, it was using <a href="https://www.biscuitsec.org/">Biscuit</a>
auth tokens to handle authentication and authorization. In the initial
implementation, we didn’t really take much advantage of Biscuit, and basically
used them as plain API keys. This week, however, we’ve finally expanded our
Biscuit usage to properly take advantage of the flexibility offered.</p>
<p>Read on to find out how this allows us to now support advanced access policies,
token-based SSH auth and signed web links that gives easy access to build logs
and fancy build reports.</p>
<!--more-->
<h2 id="signed-web-links">Signed Web Links</h2>
<p>Let’s start out with the feature we’re really happy to launch: signed web
links. To show how it works, I grep for a broken package in nixpkgs and find
one called <code>textpieces</code>. Then I try building it on my laptop which has been
<a href="https://docs.nixbuild.net/getting-started/">setup</a> to use nixbuild.net as a
remote builder (we need <code>NIXPKGS_ALLOW_BROKEN=1</code> and <code>--impure</code> in order to
force Nix to evaluate the broken package):</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> NIXPKGS_ALLOW_BROKEN=1 nix build <span class="at">--impure</span> nixpkgs#textpieces</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="ex">error:</span> build of <span class="st">&#39;/nix/store/s7ns32ymdf9iq44hpa62dkdbwlhvc7nx-textpieces-3.4.1.drv&#39;</span> on <span class="st">&#39;ssh://eu.nixbuild.net&#39;</span> failed: builder for <span class="st">&#39;/nix/store/s7ns32ymdf9iq44hpa62dkdbwlhvc7nx-textpieces-3.4.1.drv&#39;</span> failed with exit code 1</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="ex">error:</span> builder for <span class="st">&#39;/nix/store/s7ns32ymdf9iq44hpa62dkdbwlhvc7nx-textpieces-3.4.1.drv&#39;</span> failed with exit code 1<span class="kw">;</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="fu">last</span> 10 log lines:</span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;</span> upgrade: <span class="ex">Use</span> the <span class="st">&#39;$&#39;</span> extern syntax introduced in blueprint 0.8.0</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;</span> at <span class="ex">../resources/ui/CustomToolPage.blp</span> line 43 column 3:</span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;</span>   43 <span class="kw">|</span>  <span class="ex">.TextPiecesToolSettings</span> tool_settings {</span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;</span>      <span class="kw">|</span>  <span class="ex">^</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;</span> error: <span class="ex">Cannot</span> convert 2.5 to integer</span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;</span> at <span class="ex">../resources/ui/Editor.blp</span> line 45 column 26:</span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;</span>   45 <span class="kw">|</span>          <span class="ex">margin-bottom:</span> 2.5<span class="kw">;</span></span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;</span>      <span class="kw">|</span>                         <span class="ex">^</span></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;</span> ninja: <span class="ex">build</span> stopped: subcommand failed.</span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;</span> <span class="ex">[nixbuild.net]</span> See this link for build details and logs: https://nixbuild.net/builds/1868020<span class="pp">?</span>t=EtcBCm0KBWJ1aWxkCgpidWlsZDpyZWFkGAMiCAoGCAcSAhABIg0KCwgEEgc6BQoDGIEIMiYKJAoCCBsSBggFEgIIBRoWCgQKAggFCggKBiCZzeO0BgoEGgIIADIVChMKAggbEg0IAhIDGIAIEgQQ9IFyEiQIABIgKYLCEYA2IZ9hybF7HQni7n68uipmGCexG7F4x0KMH2oaQOVIWFexkOoOpgNYWNXNv9GY6I5bO5T1n6RBQvU6D25_XTJm41Dmj4_fKPmzc9aZrt4rhxGBZafirifzKecFPgkiIgogIsQ6_jdmw1s5IhuXrrPabnGXJuoGoKrpfIUHz1uUU2k=</span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a>       <span class="ex">For</span> full logs, run <span class="st">&#39;nix log /nix/store/s7ns32ymdf9iq44hpa62dkdbwlhvc7nx-textpieces-3.4.1.drv&#39;</span>.</span></code></pre></div>
<p>At the very end of the build we see the message <code>[nixbuild.net] See this link for build details and logs</code>, pointing us to
<a href="https://nixbuild.net/builds/1868020?t=EtcBCm0KBWJ1aWxkCgpidWlsZDpyZWFkGAMiCAoGCAcSAhABIg0KCwgEEgc6BQoDGIEIMiYKJAoCCBsSBggFEgIIBRoWCgQKAggFCggKBiCZzeO0BgoEGgIIADIVChMKAggbEg0IAhIDGIAIEgQQ9IFyEiQIABIgKYLCEYA2IZ9hybF7HQni7n68uipmGCexG7F4x0KMH2oaQOVIWFexkOoOpgNYWNXNv9GY6I5bO5T1n6RBQvU6D25_XTJm41Dmj4_fKPmzc9aZrt4rhxGBZafirifzKecFPgkiIgogIsQ6_jdmw1s5IhuXrrPabnGXJuoGoKrpfIUHz1uUU2k=">https://nixbuild.net/builds/1868020?t=[…]</a>.</p>
<p>Go ahead and try that link now! What you’ll find is a page with details of the
build we just ran, along with its full build logs. This also works for builds
that don’t fail. Every build you run on nixbuild.net will get this handy
summary link printed in the end of the build. You can share those links as you
please, just like I did here. No accounts or logins on nixbuild.net are needed
to access the links.</p>
<p>You can explicitly create a build link for any build you’ve run using the
<code>builds url</code> command in the nixbuild.net adminstration shell, or by using the
new HTTP API <a href="https://docs.nixbuild.net/api/#get-buildsidurl">endpoint</a>.</p>
<h2 id="biscuit-auth-tokens">Biscuit Auth Tokens</h2>
<p>So how do these build links work? The <code>t=</code> argument in the links is a <a href="https://www.biscuitsec.org/">Biscuit</a> auth token, and we can use the <a href="https://github.com/biscuit-auth/biscuit-cli">biscuit-cli</a> tool to inspect it:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> echo <span class="op">&gt;</span>token <span class="st">&quot;EtcBCm0KBWJ1aWxkCgpidWlsZDpyZWFkGAMiCAoGCAcSAhABIg0KCwgEEgc6BQoDGIEIMiYKJAoCCBsSBggFEgIIBRoWCgQKAggFCggKBiCZzeO0BgoEGgIIADIVChMKAggbEg0IAhIDGIAIEgQQ9IFyEiQIABIgKYLCEYA2IZ9hybF7HQni7n68uipmGCexG7F4x0KMH2oaQOVIWFexkOoOpgNYWNXNv9GY6I5bO5T1n6RBQvU6D25_XTJm41Dmj4_fKPmzc9aZrt4rhxGBZafirifzKecFPgkiIgogIsQ6_jdmw1s5IhuXrrPabnGXJuoGoKrpfIUHz1uUU2k=&quot;</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> biscuit inspect ./token</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a><span class="ex">Authority</span> block:</span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a><span class="ex">==</span> Datalog ==</span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a><span class="ex">owner</span><span class="er">(</span><span class="ex">1</span><span class="kw">);</span></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a><span class="ex">right</span><span class="er">(</span><span class="ex">[</span><span class="st">&quot;build:read&quot;</span><span class="ex">]</span><span class="kw">);</span></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a><span class="ex">check</span> if time<span class="er">(</span><span class="va">$time</span><span class="kw">)</span><span class="ex">,</span> <span class="va">$time</span> <span class="op">&lt;</span> 2024-07-18T09:55:37Z<span class="kw">;</span></span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a><span class="ex">check</span> if resource<span class="er">(</span><span class="st">&quot;build&quot;</span><span class="ex">,</span> 1868020<span class="kw">);</span></span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a><span class="ex">==</span> Revocation id ==</span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true" tabindex="-1"></a><span class="ex">e5485857b190ea0ea6035858d5cdbfd198e88e5b3b94f59fa44142f53a0f6e7f5d3266e350e68f8fdf28f9b373d699aede2b87118165a7e2ae27f329e7053e09</span></span>
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-15"><a href="#cb2-15" aria-hidden="true" tabindex="-1"></a><span class="ex">==========</span></span>
<span id="cb2-16"><a href="#cb2-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-17"><a href="#cb2-17" aria-hidden="true" tabindex="-1"></a><span class="ex">🙈</span> Public key check skipped 🔑</span>
<span id="cb2-18"><a href="#cb2-18" aria-hidden="true" tabindex="-1"></a><span class="ex">🙈</span> Datalog check skipped 🛡️</span></code></pre></div>
<p>What you see above is <a href="https://doc.biscuitsec.org/getting-started/introduction#biscuit-is-a-policy-language">Biscuit Policy
Language</a>.
It states that the owner of the token is <code>1</code>, which is an internal id of my own
account on nixbuild.net. Then it says the token has the <code>build:read</code> right.
That means that you can only use this token for reading information about
builds. You can’t use it to run builds, or fetch store paths or anything like
that. Furthermore, there are two <code>check</code> statements in the token. One of them
sets an expiration time of the token, and the other one restricts the token to
requests concerning a specific resource, namely the build with id <code>1868020</code>.</p>
<p>Now, the really interesting thing about Biscuit tokens is that you can yourself
restrict the tokens further, without involving the nixbuild.net service at all.
This process is called <em>attenuation</em>. We can for example set a new expiration
time on the token like this:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> biscuit attenuate <span class="at">--block</span> <span class="st">&#39;check if time($time), $time &lt; 2023-10-01T00:00:00Z;&#39;</span> ./token</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="ex">EtcBCm0KBWJ1aWxkCgpidWlsZDpyZWFkGAMiCAoGCAcSAhABIg0KCwgEEgc6BQoDGIEIMiYKJAoCCBsSBggFEgIIBRoWCgQKAggFCggKBiCZzeO0BgoEGgIIADIVChMKAggbEg0IAhIDGIAIEgQQ9IFyEiQIABIgKYLCEYA2IZ9hybF7HQni7n68uipmGCexG7F4x0KMH2oaQOVIWFexkOoOpgNYWNXNv9GY6I5bO5T1n6RBQvU6D25_XTJm41Dmj4_fKPmzc9aZrt4rhxGBZafirifzKecFPgkalAEKKhgDMiYKJAoCCBsSBggFEgIIBRoWCgQKAggFCggKBiCA7eKoBgoEGgIIABIkCAASICCqMLKzBGTXvvVsPHikBh0QIN9-BTcnPR0y3IBrSz_ZGkD_REi0xNW8VOi2-MDXPivZUgJdCv4A6cxcK4UuGgb_F9DBuizVuMv1GXkRxawlcMU6irjAUJH8KCLRxN7aUjACIiIKIE2HZlmwEYZZ4v2Rf4qjVmh9ldCUeYYTl3xP13bemrWY</span></span></code></pre></div>
<p>Now, we got a new auth token with our additional restriction added to it. The
interested reader can try to use the new token as <code>t=</code> parameter. This should
work fine as long as the current date is before 2023-10-01.</p>
<p>To learn more about Biscuit tokens and policies I recommend reading through our
new <a href="https://docs.nixbuild.net/access-control/">Access Control</a> documentation,
and of course also the <a href="https://doc.biscuitsec.org/">Biscuit documentation</a>.</p>
<h2 id="using-auth-tokens-for-everything">Using Auth Tokens for Everything</h2>
<p>As part of the launch of the signed web links, we have implemented support for
using auth tokens in all parts of nixbuild.net. You can use them for accessing
the <a href="https://docs.nixbuild.net/api/">HTTP API</a> or when <a href="https://docs.nixbuild.net/access-control/#using-the-nix-client-with-an-auth-token">using the Nix
client</a>
to run builds or interact with your Nix store in nixbuild.net.</p>
<p>You can create tokens using the <a href="https://docs.nixbuild.net/access-control/#using-auth-tokens">tokens
create</a> command in
the administration shell of nixbuild.net. When doing this, you select what
<a href="https://docs.nixbuild.net/access-control/#permissions">permissions</a> you want
to embed in the token, and set an expiration time. With the permission system
it is possible to create tokens that can only be used for specific operations
in nixbuild.net.</p>
<p>When you have created a token, you can create new, more restricted tokens from
it, using the
<a href="https://docs.nixbuild.net/access-control/#token-attenuation">attenuation</a>
process demonstrated above.</p>
<p>You can still use SSH keys for auth, if you like. In fact, the newly introduced
permissions are also possible to assign to specific SSH keys, using the
<a href="https://docs.nixbuild.net/settings/#default-permissions">default-permissions</a>
setting. This way, you can gain some more granularity in your authorization
setup, without going all in on Biscuit tokens.</p>
<h2 id="the-future">The Future</h2>
<p>For now, the access policies you are able to define in your auth tokens are
somewhat limited since the policy context is still something we are expanding.
The context is represented as a set of
<a href="https://docs.nixbuild.net/access-control/#biscuit-facts">facts</a> that are made
available by nixbuild.net during the authorization phase. We are working on
adding more facts, and also implementing more example policies that you can
gain inspiration from. As always, if you have any feedback, questions or
issues, just ping us on <a href="mailto:support@nixbuild.net">support@nixbuild.net</a>.</p>]]></description>
    <pubDate>Fri, 22 Sep 2023 00:00:00 UT</pubDate>
    <guid>https://blog.nixbuild.net/posts/2023-09-22-biscuits-and-web-links.html</guid>
    <dc:creator>support@nixbuild.net</dc:creator>
</item>
<item>
    <title>ARM Builds for All</title>
    <link>https://blog.nixbuild.net/posts/2022-08-18-arm-builds-for-all.html</link>
    <description><![CDATA[<p>Less than a year ago, we
<a href="https://blog.nixbuild.net/posts/2021-09-20-nixbuild-net-now-supports-arm-builds.html">announced</a>
support for ARM (<code>aarch64-linux</code>) builds on
<a href="https://nixbuild.net">nixbuild.net</a>, for users that wanted to evaluate the
feature in an Early Access phase. Today, we are thrilled to announce that all
nixbuild.net users now can run <code>aarch64-linux</code> builds!</p>
<p>For now, ARM builds are priced in the exact same way as x86-64 builds. This
might change in the future.</p>
<p>If you’re already a nixbuild.net user, head over to the
<a href="https://docs.nixbuild.net/arm-builds/">documentation</a> to learn about how to
configure Nix to run <code>aarch64-linux</code> builds on nixbuild.net. If you’re not a
user, <a href="https://nixbuild.net/#register">register</a> today and <a href="https://docs.nixbuild.net/getting-started/">get
started</a>! Every new account gets
free build hours that can be spent on both ARM and x86-64 builds.</p>
<!--more-->]]></description>
    <pubDate>Thu, 18 Aug 2022 00:00:00 UT</pubDate>
    <guid>https://blog.nixbuild.net/posts/2022-08-18-arm-builds-for-all.html</guid>
    <dc:creator>support@nixbuild.net</dc:creator>
</item>
<item>
    <title>Lightning-fast CI with nixbuild.net</title>
    <link>https://blog.nixbuild.net/posts/2022-03-16-lightning-fast-ci-with-nixbuild-net.html</link>
    <description><![CDATA[<p>Today we are announcing support for <strong>remote store builds</strong> in
<a href="https://nixbuild.net">nixbuild.net</a>. This is an alternative way of remote
building in Nix, which can improve build performance greatly for certain types
of environments. The biggest performance impact can be had in CI setups,
especially in hosted CI services like <a href="https://github.com/features/actions">GitHub
Actions</a>.</p>
<p>By switching over our own CI setup (running on GitHub Actions) to this build
mode we reduced the best-case build time of our slowest CI job from 20 minutes
down to just 20 seconds, an amazing 60x speedup!</p>
<p>No extra setup is needed, everything is already built into Nix and the
feature is available to all nixbuild.net users right now.</p>
<p>Read on to find out how to try this out on your own CI builds!</p>
<!--more-->
<h2 id="remote-builders-vs-stores">Remote Builders vs Stores</h2>
<p>Usually, when Nix <a href="https://nixos.org/manual/nix/stable/advanced-topics/distributed-builds.html">distributes
builds</a>,
it sends them to one or more <em>remote builder</em>. These remote builders are just
normal Nix machines, accessed over SSH by the Nix client. Since nixbuild.net
tries hard to act just like a normal Nix machine from the outside, you can use
nixbuild.net as a drop-in replacement for a remote builder. This is how
nixbuild.net has worked from the very launch.</p>
<p>Here is a brief iteration of what happens when Nix uses a remote builder to
perform a build:</p>
<ol type="1">
<li><p>Nix checks if the build result already is available in the local
store or can be fetched from any configured substituter (binary cache).</p></li>
<li><p>If Nix needs to run the build, it will first make sure that all
dependencies (inputs), and their transitive closures, are in place in the
local Nix store. This might mean it has to build the inputs, if there are
no existing builds to be found.</p></li>
<li><p>Once all inputs are locally available, Nix will select a remote builder
machine that can perform the build, and then check if the builder has all
build inputs in place in its store. If there are any missing closures, they
will either be downloaded from a substituter directly to the remote
builder, or uploaded from the local store to the builder.</p></li>
<li><p>Now, Nix asks the remote builder to perform the build. Once it is done Nix
will download the build result from the builder to its local store.</p></li>
</ol>
<p>We have just added a chapter in the nixbuild.net
<a href="https://docs.nixbuild.net/remote-builds">documentation</a> that describes this
process in greater detail.</p>
<p>If you use a service such as <a href="https://github.com/features/actions">GitHub
Actions</a>, each run will start out with a
completely empty environment. This is pretty bad when using Nix, because it
means all build inputs have to be fetched on each run. Even for changes that
only trigger quick builds, the total size of the build inputs might be
considerable. Not only does it take time to fetch the closures from binary caches,
it also takes time for Nix to unpack the closure archives (compressed
<code>nar</code>-files) to the local file system.</p>
<p>If you have configured a binary cache together with your CI, where all new build
results are stored, you might sometimes be lucky and commit code
that doesn’t trigger any new builds at all. In this case, no build inputs needs to
be fetched. However, the build <em>output</em> and its transitive closure will still
be fetched from your binary cache to your CI. This might seem unavoidable and even
desireable, but in fact you are often not interested in the build output itself
when it comes to CI builds. What you really want to see is if your builds and
tests pass. If you are using a remote builder like nixbuild.net, actually
fetching the build output to the ephemeral CI runner is just a waste of time.</p>
<p>For some builds, the time spent on transporting Nix closures can add up to a
considerable amount. In our own CI for nixbuild.net, we had one particularly
slow build. It builds our development shell, including NixOS containers for a
complete development deployment of nixbuild.net itself. It contains
<em>all</em> software that the nixbuild.net service directly or indirectly uses. The
total closure size is just shy of 10 GB. Running this build in GitHub Actions
(<a href="https://github.com/marketplace/actions/nixbuild-net">hooked</a> up to
nixbuild.net, of course) took about 20 minutes, even when minimal actual
building was required.</p>
<p>Today, the same build takes just 20 seconds!</p>
<p>Nix has a lesser-known way of distributing builds, using <em>remote stores</em>. It is
conceptually the same thing as SSHing to a remote Nix machine and running your
build on it instead of on your local machine. But Nix makes the process a bit
more convenient, allowing the Nix evaluation to happen locally (where you have
your sources). To use it with nixbuild.net, all you have to do is to run this:</p>
<pre><code>nix build \
  --eval-store auto \
  --store ssh-ng://eu.nixbuild.net \
  ...</code></pre>
<p>Now, the build process will look roughly like this instead:</p>
<ol type="1">
<li><p>Nix evaluates your build as usual. During this phase, derivation files
(<code>.drv</code>-files) will be written to your local store, and any sources that
are needed for evaluation will be fetched.</p></li>
<li><p>Nix will copy over all <code>.drv</code>-files for the build and its inputs to the
remote Nix machine (<code>eu.nixbuild.net</code> in this case). Any sources used
during evaluation will also be copied over (if they don’t already exist on
remote machine).</p></li>
<li><p>Now, Nix will tell the remote machine to build the top-level <code>.drv</code> file
of the build you requested. During the build, logs will be sent over to
your local console so it looks just like an ordinary build, but everything
is running remotely.</p></li>
<li><p>When the build is done, the build results will be available on the remote
machine, but Nix will not fetch them. If you need to, you can fetch them
explicitly, with <code>nix copy</code>.</p></li>
</ol>
<p>As you can see, all copying of Nix closures is gone, improving performance
tremendously for many types of builds. We have created a public <a href="https://github.com/nixbuild/ci-demo">demonstration
repository</a> where you can see more
comparisons between remote store building and traditional building, and
practical examples of GitHub Actions. We plan on keeping the repository updated
and adding more sample projects.</p>
<p>It is not only CI runners that benefit from using nixbuild.net as a remote
store. If you use Nix on underpowered (in terms of network, storage or CPU)
machines, you might want to offload as much work as possible from them. Using
a remote store for building guarantees that the local machine will only be used
for Nix evaluation.</p>
<p>Nix itself has had support for remote store building for some time, but the
support for <code>--eval-store</code> (which makes the whole thing practically useful for
actual builds) was recently added. We were able to add support for remote store
building to nixbuild.net by implementing more pieces of the <code>nix-daemon</code>
protocol (than we had already implemented). With this new feature nixbuild.net
fits into even more Nix use cases, and as we add support for even more pieces of
the <code>nix-daemon</code> protocol we hope to find many more.</p>
<p>If you want to try this new feature out, you need to use Nix 2.4 or newer.</p>
<p>Lastly, we should add that the remote store building feature on nixbuild.net
should be considered beta for the time being. There is some polishing needed in
the UX (the output you see when running Nix in your shell), some known
<a href="https://docs.nixbuild.net/remote-builds/#limitations-of-remote-store-builds-in-nixbuildnet">limitations</a>,
and we are also working on further performance improvements. If you try it out,
your feedback is very much welcome, either through
<a href="mailto:support@nixbuild.net">support@nixbuild.net</a> or our <a href="https://github.com/nixbuild/feedback/issues">issue
tracker</a>.</p>]]></description>
    <pubDate>Wed, 16 Mar 2022 00:00:00 UT</pubDate>
    <guid>https://blog.nixbuild.net/posts/2022-03-16-lightning-fast-ci-with-nixbuild-net.html</guid>
    <dc:creator>support@nixbuild.net</dc:creator>
</item>
<item>
    <title>KVM builds supported on nixbuild.net</title>
    <link>https://blog.nixbuild.net/posts/2021-10-01-kvm-builds-supported-on-nixbuild-net.html</link>
    <description><![CDATA[<p>Less than two weeks ago, we
<a href="https://blog.nixbuild.net/posts/2021-09-20-nixbuild-net-now-supports-arm-builds.html">announced</a>
support for ARM builds on <a href="https://nixbuild.net">nixbuild.net</a>. Today we are
excited to announce another early access feature — support for builds
that use <a href="https://en.wikipedia.org/wiki/Kernel-based_Virtual_Machine">KVM</a>!</p>
<p>KVM support is something that almost no public CI/CD provider offers, so we are
very happy to be able to make this available to our users.</p>
<p>For NixOS users and developers, this is especially valuable since it makes it
possible to run <a href="https://nix.dev/tutorials/integration-testing-using-virtual-machines">integration
tests</a>
based on the powerful <a href="https://nixos.org/manual/nixos/stable/index.html#sec-nixos-tests">testing
framework</a>
found in nixpkgs/NixOS.</p>
<p>KVM builds are currently in an Early Access phase. If you want to try it out,
contact us at <a href="mailto:support@nixbuild.net">support@nixbuild.net</a>. Anyone is
free to request access, but there might be waiting time depending on interest.
During Early Access, KVM builds are priced and handled exactly as standard
builds. The final pricing and price model for builds that require KVM has not
been settled yet.</p>
<p>So far KVM builds are only supported on <code>x86_64-linux</code>, not on ARM.</p>
<!--more-->
<h2 id="setup">Setup</h2>
<p>Once you’ve gained access to running KVM builds, configuring your Nix client is
simple. You just need to mark your <code>eu.nixbuild.net</code> remote builder with the
<code>kvm</code> system feature. And if you want to run NixOS integration tests you’ll
need the <code>nixos-test</code> feature too. For more detailed configuration descriptions
see the <a href="https://docs.nixbuild.net/getting-started/#kvm-builds">documentation</a>.</p>
<h2 id="kvm-builds-in-github-actions">KVM builds in GitHub Actions</h2>
<p>The <a href="https://github.com/marketplace/actions/nixbuild-net">nixbuild.net GitHub
Action</a> has been
<a href="https://github.com/nixbuild/nixbuild-action/releases/tag/v7">updated</a> to
support KVM builds too. If you’ve been granted access to KVM builds, all you
have to do is to make sure you use the latest release of nixbuild-action. No
extra configuration is needed to run KVM builds, or NixOS integration tests, in
GitHub Actions.</p>]]></description>
    <pubDate>Fri, 01 Oct 2021 00:00:00 UT</pubDate>
    <guid>https://blog.nixbuild.net/posts/2021-10-01-kvm-builds-supported-on-nixbuild-net.html</guid>
    <dc:creator>support@nixbuild.net</dc:creator>
</item>
<item>
    <title>nixbuild.net now supports ARM builds!</title>
    <link>https://blog.nixbuild.net/posts/2021-09-20-nixbuild-net-now-supports-arm-builds.html</link>
    <description><![CDATA[<p>As of today, there is support for running <code>aarch64-linux</code> builds in
nixbuild.net. This is a feature that has been requested by many of our users,
and we are very happy to be able to provide this as part of our service.</p>
<p>For the moment, ARM builds are in an Early Access phase. If you want to try it
out, just drop us a line at
<a href="mailto:support@nixbuild.net">support@nixbuild.net</a>. Anyone is free to request
access, but there might be waiting time depending on interest. During Early
Access, ARM builds are priced and handled exactly as the standard
<code>x86_64-linux</code> builds. The final pricing and price model for ARM builds has not
been settled yet.</p>
<!--more-->
<h2 id="setup">Setup</h2>
<p>Once you’ve gained access to running ARM builds, configuring your Nix client is
just as straightforward as for <code>x86_64-linux</code> builds. Just swap the <code>system</code> of
your remote builder to <code>aarch64-linux</code>. You can use nixbuild.net for both
x86_64 and ARM builds at the same time. For more detailed configuration
descriptions see the
<a href="https://docs.nixbuild.net/getting-started/#aarch64-linux-builds">documentation</a>.</p>
<h2 id="zero-config-aarch64-linux-builds-in-github-actions">Zero-config aarch64-linux builds in GitHub Actions</h2>
<p>Together with the new support for ARM builds in nixbuild.net, there’s also a
new release of the <a href="https://github.com/marketplace/actions/nixbuild-net">nixbuild.net GitHub
Action</a>. The release
(<a href="https://github.com/nixbuild/nixbuild-action/releases/tag/v6">v6</a>) enables
support for <code>aarch64-linux</code> for your GitHub builds. If you’ve been granted
access to <code>aarch64-linux</code> builds, all you have to do is to add <code>--system aarch64-linux</code> or similar to your nix invocations inside your GitHub actions.</p>
<p>It is of course also simple to run <code>aarch64-linux</code> builds from GitLab, Hydra or
any other CI setup using Nix. Just add nixbuild.net as an <code>aarch64-linux</code>
remote builder as described in the
<a href="https://docs.nixbuild.net/getting-started/#aarch64-linux-builds">documentation</a>.</p>]]></description>
    <pubDate>Mon, 20 Sep 2021 00:00:00 UT</pubDate>
    <guid>https://blog.nixbuild.net/posts/2021-09-20-nixbuild-net-now-supports-arm-builds.html</guid>
    <dc:creator>support@nixbuild.net</dc:creator>
</item>
<item>
    <title>Data Science with Nix: Parameter Sweeps</title>
    <link>https://blog.nixbuild.net/posts/2021-04-26-data-science-with-nix-parameter-sweeps.html</link>
    <description><![CDATA[<p><strong>Parameter sweeping</strong> is a technique often utilized in scientific computing and
<a href="https://en.wikipedia.org/wiki/Supercomputer">HPC</a> settings. In the mainstream
software industry the concept is called a <strong>build matrix</strong>.</p>
<p>The idea is that you have a task you want to perform with varying input
parameters. If the task takes multiple parameters, and you’d like to try it out
with multiple values for each parameter, it is easy to end up with a
<a href="https://en.wikipedia.org/wiki/Combinatorial_explosion">combinatorial
explosion</a>.</p>
<p>This blog post gives a practical demonstration showing how
<a href="https://nixos.org/">Nix</a> is a perfect companion for managing parameter
sweeps and build matrices, and how <a href="https://nixbuild.net">nixbuild.net</a> can be
used to supercharge your workflow.</p>
<p>My hope is that this text can interest readers that don’t know anything about
Nix as well as experienced Nix users.</p>
<!--more-->
<h2 id="use-cases">Use Cases</h2>
<p>In scientific computing, it is common to run simulations of physical processes.
The list of things simulated is endless: weather forecasting, molecular
dynamics, celestial movements, FEM analysis, particle physics etc. A simulation
is usually implemented directly as a computer program or as a description for a
higher level simulation framework. A simulation generally has a set of input
parameters that can be defined. These parameters can describe initial states,
environmental aspects or tweak the behavior of the simulation algorithm itself.
Scientists are interested in comparing simulation results for a range of
different parameter values, and the process of doing so is referred to as a
<em>parameter sweep</em>.</p>
<p>Parameter sweeping is often built into simulation frameworks. For simulations
implemented directly as specialized programs, scientists will simply run the
program over and over again with different parameters, collecting and comparing
the results. When <a href="https://en.wikipedia.org/wiki/Supercomputer">supercomputers</a>
are used for running the simulations, the job scheduler usually has some support
for launching multiple simulation instances with varying parameters.</p>
<p>In the software industry, the term <em>build matrix</em> is used to mean
basically the same thing as parameter sweeping. Regularly, build matrices are
used to build different variants of the same deliverable. In the simplest case,
a programmer builds and packages a program for set of different targets
(Windows, MacOS, Android etc). But more complex build matrices with (much)
higher dimensionality is of course also used.</p>
<p>Benchmarking is another area where build matrices are utilized, and
combinatorial explosions are common. The demo below will show how a compression
benchmark can be implemented with Nix and nixbuild.net.</p>
<h2 id="embarassing-parallelism">Embarassing Parallelism</h2>
<p>Parameter sweeping can be classified as an <a href="https://en.wikipedia.org/wiki/Embarrassingly_parallel">embarrassingly
parallel</a> problem. As
long as we have enough CPUs, all simulations or builds can be executed in
parallel, since there is (usually) no dependencies between them. This is a
perfect workload for nixbuild.net, which is built to be very scalable.</p>
<p>At the same time, it is also easy to get into troubles managing all possible
combinations of parameter values. Adding new parameters or parameter values
can increase the number of runs exponentially, and the work of managing the
runs and their results becomes overwhelming. The next section will show how
Nix can help out with this.</p>
<h2 id="how-nix-helps">How Nix Helps</h2>
<p>One of the aspects of Nix that I find most empowering is that it helps you with
the boring and stress-inducing task of <em>managing files</em>. Let me see if I can
explain.</p>
<p>Assume you have a program called <code>simulation</code> that takes a parameter file as its
only argument. The parameter file contains simulation parameters in a simple
INI-format like this:</p>
<pre><code>param1=3
param2=92
param3=0</code></pre>
<p>The program outputs a simulation result on its standard output, in CSV format.</p>
<p>Now we want to run the simulation for some different combinations of input
parameters. We could manually author the needed parameter files, or we can
write a simple shell script for it:</p>
<pre><code>round=1

for param1 in 3 4 5; do
  for param2 in 10 33 50 92; do
    for param3 in 0 1; do
      echo &quot;param1=$param1&quot; &gt;&gt; &quot;round$round.ini&quot;
      echo &quot;param2=$param2&quot; &gt;&gt; &quot;round$round.ini&quot;
      echo &quot;param3=$param3&quot; &gt;&gt; &quot;round$round.ini&quot;
      round=$((round+1))
    done
  done
done</code></pre>
<p>We now got 24 different parameter files with all possible combinations of the
values we are interested in:</p>
<pre><code>$ ls -v
round1.ini  round6.ini   round11.ini  round16.ini  round21.ini
round2.ini  round7.ini   round12.ini  round17.ini  round22.ini
round3.ini  round8.ini   round13.ini  round18.ini  round23.ini
round4.ini  round9.ini   round14.ini  round19.ini  round24.ini
round5.ini  round10.ini  round15.ini  round20.ini

$ cat round20.ini
param1=5
param2=33
param3=1</code></pre>
<p>To run the simulations, we simply loop through all parameter files:</p>
<pre><code>for round in round*.ini; do
  simulation $round &gt;&gt; results.csv
done</code></pre>
<p>So far, so good. At this point, we might want to tweak our parameter generation
a bit. Maybe there are more parameter values we want to explore, different
sweeps to do. So we change our parameter generator script and re-run a few
times. We then realise we want to make changes to our simulation program
itself. So we do that, and recompile it. Now we want to re-run all the
different parameter sweeps we’ve done. Luckily, we saved all different versions
of our parameter generation script, so we can just run the updated simulator
with the previous simulator.</p>
<p>At the end of our productive simulation session we have the following mess
(with all intermediate parameter files removed):</p>
<pre><code>gen-params.sh         results-1.csv   results-12.csv  simulation-3
gen-params-1.sh       results-2.csv   results-13.csv  simulation-O2-1
gen-params-2.sh       results-3.csv   results-14.csv  simulation-O2-2
gen-params-3.sh       results-4.csv   results-15.csv  simulation-O3
gen-params-3v2.sh     results-5.csv   results-16.csv  simulation-debug
gen-params-4.sh       results-6.csv   results-17.csv  simulation-debug2
gen-params-test.sh    results-7.csv   simulation      simulation-wrong
gen-params-test-2.sh  results-8.csv   simulation-1
results.csv           results-10.csv  simulation-2</code></pre>
<p>Admittedly, this is how things usually end up for me when I’m doing any kind
of “exploratory” work. I’m sure you all are much more organized. To my rescue
comes Nix. It allows me to stop caring entirely about <em>generated files</em>,
and only care about <em>how stuff is generated</em>. Additionally, it gives me tools
to abstract, parameterize and reuse generators.</p>
<p>Let’s make an attempt at recreating our workflow above with Nix:</p>
<pre><code>{ pkgs ? import &lt;nixpkgs&gt; {} }:

let

  inherit (pkgs) lib callPackage runCommand writeText;

  # Compiles the &#39;simulation&#39; program, and allows us to provide
  # build-time arguments
  simulation = callPackage ./simulation.nix;

  # Executes the given simulation program with the given parameters
  runSimulation = buildArgs: parameters:
    runCommand &quot;result.csv&quot; {
      buildInputs = [ (simulation buildArgs) ];
      parametersFile = writeText &quot;params.ini&quot; (
        lib.generators.toKeyValue {} parameters
      );
    } &#39;&#39;
      simulation $parametersFile &gt; $out
    &#39;&#39;;

  # Merges multiple CSV files into a single one
  mergeResults = results: runCommand &quot;results.csv&quot; {
    inherit results;
  } &#39;&#39;
    cat $results &gt; $out
  &#39;&#39;;

in {

  sim_O3_std_sweep = mergeResults (
    lib.forEach (lib.cartesianProductOfSets {
      param1 = [3 4 5];
      param2 = [10 33 50 92];
      param3 = [0 1];
    }) (
      runSimulation {
        optimizationLevel = 3;
      }
    )
  );

  sim_O2_small_sweep = mergeResults (
    lib.forEach (lib.cartesianProductOfSets {
      param1 = [1 3];
      param2 = [20 60 92];
      param3 = [0 1];
    }) (
      runSimulation {
        optimizationLevel = 2;
      }
    )
  );

}</code></pre>
<p>The key function above is perhaps <code>cartesianProductOfSets</code>, from the library
functions in nixpkgs. It will create all possible combinations of input
parameters, if we list the possible value for each parameter. Our build function
is then mapped over all these combinations using <code>forEach</code>.</p>
<p>We can build one of our parameter sweeps like this:</p>
<pre><code>nix-build -A sim_O3_std_sweep</code></pre>
<p>When all 24 simulation runs are done, Nix will create a single <code>result</code> symlink
in the current directory, pointing to a <code>results.csv</code> file containing all
simulation results. We can add new sweeps to our Nix file and re-run the build
at any time. We never have to care about any generated files, since everything
needed to re-generate results exists in the Nix file. The Nix file itself can
be version-controlled like any source file.</p>
<p>In addition to the demonstrated ability to parameterize builds, Nix provides us
with two more things, for free.</p>
<p><strong>No unnecessary re-builds</strong></p>
<p>In the example above, the <code>sim_O3_std_sweep</code> and <code>sim_O2_small_sweep</code> builds
have some overlapping parameter sets. If you build both, Nix will only
run the overlapping simulations once, and use the same <code>result.csv</code> files to
create the two different <code>results.csv</code> files. This happens without any extra
effort from the user. The same is true if you make changes that only affect
part of your build. Nix also has support for external caches which makes it
easy to share and reuse build results between computers (or you can simply use
nixbuild.net to get build sharing without any extra configuration).</p>
<p><strong>Automatic parallelization</strong></p>
<p>When Nix evaluates an expression, it constructs a <em>build graph</em> that tracks all
dependencies between builds. In the example above, the <code>results.csv</code> file
depends on the list of <code>result.csv</code> files, which in turn depend on specific
builds of <code>simulation</code>. All of these dependencies are <em>implicit</em>; you don’t
have to do anything other than simply refer to the things you need to perform
your build.</p>
<p>The build graph allows Nix to execute the actual builds with maximum
parallelization. However, running as many builds as possible in parallel is
often not optimal, if your compute resources (usually: your local computer) are
limited. Nix has a simplistic build scheduler, which is just a
user-configurable limit of the maximum number of concurrent builds. This works
in many cases, but quickly gets non-optimal when you have lots of builds that
could run in parallel, or when the builds themselves have varying compute
requirements.</p>
<p>This is where <a href="https://nixbuild.net">nixbuild.net</a> can step in. It is able to
run an “infinite” number of concurrent Nix builds for you, while keeping all
builds perfectly isolated from each other (security- and resource-wise). It
also <a href="https://blog.nixbuild.net/posts/2020-06-25-automatic-resource-optimization.html">selects compute resources
intelligently</a>
for each individual build.</p>
<p>From the perspective of scientific computing, you can say that Nix provides a
generic framework for parallel workloads, and nixbuild.net acts somewhat as a
supercomputer, minus the effort of writing submission scripts and explicitly
managing compute results.</p>
<h2 id="demo-compression-benchmark">Demo: Compression Benchmark</h2>
<p>I’m now going to show you an example that is similar to the example in the
previous section, but instead of an imaginary simulation we will run an actual
benchmark this time. The benchmark will compare the compression ratio of a
number of different lossless compression implementations. Since this article
is about parameter sweeping, we will vary the following parameters during the
benchmark:</p>
<ul>
<li><p>Compression implementation: <code>brotli</code>, <code>bzip2</code>, <code>gzip</code>, <code>lz4</code>, <code>xz</code> and <code>zstd</code>.</p></li>
<li><p>Two different versions of each compression implementation. We’ll use the
versions packaged in nixpkgs 16.03 and 20.09, respectively.</p></li>
<li><p>Compression level: 1-9.</p></li>
<li><p>Corpus type: text, binaries and jpeg files.</p></li>
<li><p>Corpus size: small, medium and large.</p></li>
</ul>
<p>We’ll try out the Cartesian product of the above parameters, resulting in 972
different builds. There is no particular thought behind the parameter
selection, they are just picked to demonstrate the abilities of Nix and
nixbuild.net. If you were to design a proper benchmark you’d likely come up
with different parameters, but the concept would be the same.</p>
<p>Here is the complete Nix expression implementing the benchmark outlined above.
The expression is parameterized over package sets from different releases of
nixpkgs. There are different ways of actually importing those package sets, but
that is out of the scope of this example.</p>
<pre><code>{ pkgs, pkgs_2009, pkgs_1603 }:

let

  inherit (pkgs)
    stdenv fetchurl lib writers runCommand unzip gnutar
    referencesByPopularity uclibc hello zig;

  compressionCommand = pkgs: program: level: {

    brotli = writers.writeBash &quot;brotli-compress&quot; &#39;&#39;
      if [ -x ${pkgs.brotli}/bin/brotli ]; then
        ${pkgs.brotli}/bin/brotli --stdout -${toString level}
      else
        ${pkgs.brotli}/bin/bro --quality ${toString level}
      fi
    &#39;&#39;;

    bzip2 = &quot;${pkgs.bzip2}/bin/bzip2 --stdout -${toString level}&quot;;

    gzip = &quot;${pkgs.gzip}/bin/gzip --stdout -${toString level}&quot;;

    lz4 = &quot;${pkgs.lz4}/bin/lz4 --stdout -${toString level}&quot;;

    xz = &quot;${pkgs.xz}/bin/xz --stdout -${toString level}&quot;;

    zstd = &quot;${pkgs.zstd}/bin/zstd --stdout -${toString level}&quot;;

  }.${program};

  corpus = rec {
    txt.small = calgary-text.small;
    txt.medium = calgary-text;
    txt.large = runCommand &quot;enwik8&quot; {
      buildInputs = [ unzip ];
      src = fetchurl {
        url = &quot;http://mattmahoney.net/dc/enwik8.zip&quot;;
        sha256 = &quot;1g1l4n9x8crxghapq956j7i4z89qkycm5ml0hcld3ghfk3cr8yal&quot;;
      };
    } &#39;&#39;
      unzip &quot;$src&quot;
      mv enwik8 &quot;$out&quot;
    &#39;&#39;;

    pkg.small = closure-tar &quot;uclibc-closure.tar&quot; uclibc;
    pkg.medium = closure-tar &quot;hello-closure.tar&quot; hello;
    pkg.large = closure-tar &quot;zig-closure.tar&quot; zig;

    jpg.small = fetchurl {
      url = &quot;https://people.sc.fsu.edu/~jburkardt/data/jpg/charlie.jpg&quot;;
      sha256 = &quot;0cmd8wwm0vaqxsbvb3lxk2f7w2lliz8p361s6pg4nw0vzya6lzrg&quot;;
    };
    jpg.medium = fetchurl {
      url = &quot;https://cdn.hasselblad.com/samples/x1d-II-50c/x1d-II-sample-02.jpg&quot;;
      sha256 = &quot;15pz84f5d34jmp0ljz61wx3inx8442sgf9n8adbgb8m4v88vifk2&quot;;
    };
    jpg.large = fetchurl {
      url = &quot;https://cdn.hasselblad.com/samples/Cam_1_Borna_AOS-H5.jpg&quot;;
      sha256 = &quot;0rdcxlxcxanlgfnlxs9ffd3s36a05g8g3ca9khkfsgbyd5spk343&quot;;
    };

    calgary-text = stdenv.mkDerivation {
      name = &quot;calgary-corpus-text&quot;;
      src = fetchurl {
        url = &quot;http://corpus.canterbury.ac.nz/resources/calgary.tar.gz&quot;;
        sha256 = &quot;1dwk417ql549l0sa4jzqab67ffmyli4nmgaq7i9ywp4wq6yyw2g1&quot;;
      };
      sourceRoot = &quot;.&quot;;
      outputs = [ &quot;out&quot; &quot;small&quot; ];
      installPhase = &#39;&#39;
        cat bib book2 news paper* prog* &gt; &quot;$out&quot;
        cat paper1 &gt; &quot;$small&quot;
      &#39;&#39;;
    };

    closure-tar = name: pkg: runCommand name {
      buildInputs = [ gnutar ];
      closure = referencesByPopularity pkg;
    } &#39;&#39;
      tar -c --files-from=&quot;$closure&quot; &gt; &quot;$out&quot;
    &#39;&#39;;
  };

  benchmark = { release, program, level, corpusType, corpusSize }:
    runCommand (lib.concatStringsSep &quot;-&quot; [
      &quot;zbench&quot; program &quot;l${toString level}&quot; corpusType corpusSize release.rel
    ]) rec {
      corpusFile = corpus.${corpusType}.${corpusSize};
      run = compressionCommand release.pkgs program level;
      version = lib.getVersion release.pkgs.${program};
      tags = lib.concatStringsSep &quot;,&quot; [
        program version (toString level) corpusType corpusSize
      ];
    } &#39;&#39;
      orig_size=&quot;$(stat -c %s &quot;$corpusFile&quot;)&quot;
      result_size=&quot;$($run &lt; &quot;$corpusFile&quot; | wc -c)&quot;
      percent=&quot;$((100*result_size / orig_size))&quot;
      echo &gt;&quot;$out&quot; &quot;$tags,$orig_size,$result_size,$percent&quot;
    &#39;&#39;;

in runCommand &quot;compression-benchmarks&quot; {
  results = map benchmark (lib.cartesianProductOfSets {
    program = [
      &quot;brotli&quot;
      &quot;bzip2&quot;
      &quot;gzip&quot;
      &quot;lz4&quot;
      &quot;xz&quot;
      &quot;zstd&quot;
    ];
    release = [
      { pkgs = pkgs_1603; rel = &quot;1603&quot;; }
      { pkgs = pkgs_2009; rel = &quot;2009&quot;; }
    ];
    level = lib.range 1 9;
    corpusType = [ &quot;txt&quot; &quot;pkg&quot; &quot;jpg&quot; ];
    corpusSize = [ &quot;small&quot; &quot;medium&quot; &quot;large&quot; ];
  });
} &#39;&#39;
  echo program,version,level,corpus,class,orig_size,result_size,ratio &gt; $out
  cat $results &gt;&gt; $out
&#39;&#39;</code></pre>
<p>Above, <code>compressionCommand</code> defines the command used for each compression
program to compress <code>stdin</code> to <code>stdout</code> with a given level.</p>
<p>The <code>corpus</code> attribute set defines <code>txt</code>, <code>pkg</code> and <code>jpg</code> datasets. For text
and jpeg we simply fetch suitable sets, and for the binary (<code>pkg</code>) sets we use
Nix itself to create a tar file out of the transistive closure of some
different packages. The corpus sizes varies between around 50 kB and 300 MB.</p>
<p><code>benchmark</code> runs a single compression command for one combination of input
parameters.</p>
<p>Finally, we again use the <code>cartesianProductOfSets</code> function to create builds of
all possible combinations of parameters, and then simply concatenate all
individual results into a big CSV file.</p>
<p>Building the complete benchmark takes about 25 minutes on my somewhat old
8-core workstation, with Nix configured to run at most 8 builds concurrently.
If I use <a href="https://nixbuild.net">nixbuild.net</a> instead, time is cut down to <strong>10
minutes</strong> due to the parallelization gains possible when running 972 independent
Nix builds.</p>
<p>In the end we get a CSV-file with values for each parameter combination. The
first ten lines of the file looks like this:</p>
<pre><code>program,version,level,corpus,class,orig_size,result_size,ratio
brotli,0.3.0,1,txt,small,53161,19634,36
brotli,1.0.9,1,txt,small,53161,21162,39
bzip2,1.0.6,1,txt,small,53161,16558,31
bzip2,1.0.6.0.1,1,txt,small,53161,16558,31
gzip,1.6,1,txt,small,53161,21605,40
gzip,1.10,1,txt,small,53161,21605,40
lz4,131,1,txt,small,53161,27936,52
lz4,1.9.2,1,txt,small,53161,28952,54
xz,5.2.2,1,txt,small,53161,18416,34</code></pre>
<p>To quickly get some sort of visualization of the benchmark data, I dumped the
CSV contents into <a href="https://rawgraphs.io/">rawgraphs.io</a> and produced the
following graph:</p>
<p><img src="/img/2021-04-26-data-science-with-nix-parameter-sweeps_benchmark-graph.svg" /></p>
<p>From this visualization, we can draw a few conclusions:</p>
<ul>
<li><p>There’s little point in compressing (already compressed) JPG data.</p></li>
<li><p><code>xz</code> is the clear winner when it comes to producing small archives of binary
data.</p></li>
<li><p><code>bzip2</code> produces almost the same compression ratio for all level settings.
It even looks like level 9 can produce slightly <em>worse</em> compression than
level 8.</p></li>
<li><p><code>lz4</code> makes a very big jump in compression ratio between level 2 and 3.</p></li>
</ul>
<p>To further refine our workflow, we could also produce data visualizations
directly in our Nix expression, by creating builds that would feed the CSV
data into some visualization software.</p>
<p>Remember, this blog post is not about benchmarking compression, but about how
you can use Nix and <a href="https://nixbuild.net">nixbuild.net</a> for such workflows.
Hopefully you’ve gained some insights into how Nix can be used in scientific
computing and data science workflows. Let’s wrap up with a summary of why I
find Nix useful in these situations:</p>
<ul>
<li><p>The Nix programming language and standard library provide tools for managing
combinatorial problems, and allows us to quickly come up with high level
abstractions giving us sensible knobs to turn when exploring parameter
sweeps and build matrices.</p></li>
<li><p>We don’t have to think about parallelization, Nix takes care of it for us.</p></li>
<li><p>Nix makes it very easy to build specific variants of packages. This is helpful
if you want make comparisons between different software versions or patches.
<a href="https://github.com/NixOS/nixpkgs">nixpkgs</a> is a huge repository of
pre-packaged software available to anyone.</p></li>
<li><p><a href="https://nixbuild.net">nixbuild.net</a> gives you extreme scalability with no
adaptation or configuration needed. In the example above we saw build times
cut to less than half by sending our Nix builds to nixbuild.net.</p></li>
<li><p>Reproducibility and build reuse is first-rate in Nix.</p></li>
</ul>
<p>Thank you for reading this rather lengthy blog post! If have any comments or
questions about the content or about nixbuild.net in general, don’t hesitate
to <a href="mailto:rickard@nixbuild.net">contact</a> me.</p>]]></description>
    <pubDate>Mon, 26 Apr 2021 00:00:00 UT</pubDate>
    <guid>https://blog.nixbuild.net/posts/2021-04-26-data-science-with-nix-parameter-sweeps.html</guid>
    <dc:creator>support@nixbuild.net</dc:creator>
</item>
<item>
    <title>Finding Non-determinism with nixbuild.net</title>
    <link>https://blog.nixbuild.net/posts/2021-01-13-finding-non-determinism-with-nixbuild-net.html</link>
    <description><![CDATA[<p>During the last decade, many initiatives focussing on making builds
reproducible have gained momentum.
<a href="https://reproducible-builds.org/">reproducible-builds.org</a> is a great resource
for anyone interested in how the work progresses in multiple software
communities. <a href="https://r13y.com/">r13y.com</a> tracks the current reproducibility
metrics in <a href="https://nixos.org/">NixOS</a>.</p>
<p>Nix is particularly suited for working on reproducibility, since it by design
isolates builds and comes with
<a href="https://nixos.org/manual/nix/stable/#chap-diff-hook">tools</a> for finding
non-determinism. The Nix community also works on related projects, like
<a href="https://www.tweag.io/blog/2020-12-16-trustix-announcement/">Trustix</a> and the
<a href="https://www.tweag.io/blog/2020-09-10-nix-cas/">content-addressed store</a>.</p>
<p>This blog post summarises how <a href="https://nixbuild.net/">nixbuild.net</a> can be
useful for finding non-deterministic builds, and announces a new feature
related to reproducibility!</p>
<!--more-->
<h2 id="repeated-builds">Repeated Builds</h2>
<p>The way to find non-reproducible builds is to run the same build multiple times
and check for any difference in results, when compared bit-for-bit. Since Nix
guarantees that all inputs will be identical between the runs, just finding
differing output results is enough to conclude that a build is
non-deterministic. Of course, we can never <em>prove</em> that a build is
<em>deterministic</em> this way, but if we run the build many times, we gain a certain
confidence in it.</p>
<p>To run a Nix build multiple times, simply add the
<a href="https://nixos.org/manual/nix/stable/#conf-repeat">–repeat</a> option to your
build command. It will run your build the number of extra times you specify.</p>
<p>Suppose we have the following Nix expression in <code>deterministic.nix</code>:</p>
<pre><code>let
  inherit (import &lt;nixpkgs&gt; {}) runCommand;
in {
  stable = runCommand &quot;stable&quot; {} &#39;&#39;
    touch $out
  &#39;&#39;;

  unstable = runCommand &quot;unstable&quot; {} &#39;&#39;
    echo $RANDOM &gt; $out
  &#39;&#39;;
}</code></pre>
<p>We can run repeated builds like this (note that the <code>--builders ""</code> option is
there to force a local build, to not use nixbuild.net):</p>
<pre><code>$ nix-build deterministic.nix --builders &quot;&quot; -A stable --repeat 1
these derivations will be built:
  /nix/store/0fj164aqyhsciy7x97s1baswygxn8lzf-stable.drv
building &#39;/nix/store/0fj164aqyhsciy7x97s1baswygxn8lzf-stable.drv&#39; (round 1/2)...
building &#39;/nix/store/0fj164aqyhsciy7x97s1baswygxn8lzf-stable.drv&#39; (round 2/2)...
/nix/store/6502c5490rap0c8dhvfwm5rhi22i9clz-stable

$ nix-build deterministic.nix --builders &quot;&quot; -A unstable --repeat 1
these derivations will be built:
  /nix/store/psmn1s3bb97989w5a5b1gmjmprqcmf0k-unstable.drv
building &#39;/nix/store/psmn1s3bb97989w5a5b1gmjmprqcmf0k-unstable.drv&#39; (round 1/2)...
building &#39;/nix/store/psmn1s3bb97989w5a5b1gmjmprqcmf0k-unstable.drv&#39; (round 2/2)...
output &#39;/nix/store/g7a5sf7iwdxs7q12ksrzlvjvz69yfq3l-unstable&#39; of &#39;/nix/store/psmn1s3bb97989w5a5b1gmjmprqcmf0k-unstable.drv&#39; differs from previous round
error: build of &#39;/nix/store/psmn1s3bb97989w5a5b1gmjmprqcmf0k-unstable.drv&#39; failed</code></pre>
<p>Running repeated builds on nixbuild.net works exactly the same way:</p>
<pre><code>$ nix-build deterministic.nix -A stable --repeat 1
these derivations will be built:
  /nix/store/wnd5y30jp3xwpw1bhs4bmqsg5q60vc8i-stable.drv
building &#39;/nix/store/wnd5y30jp3xwpw1bhs4bmqsg5q60vc8i-stable.drv&#39; (round 1/2) on &#39;ssh://eu.nixbuild.net&#39;...
copying 1 paths...
copying path &#39;/nix/store/z3wlpwgz66ningdbggakqpvl0jp8bp36-stable&#39; from &#39;ssh://eu.nixbuild.net&#39;...
/nix/store/z3wlpwgz66ningdbggakqpvl0jp8bp36-stable

$ nix-build deterministic.nix -A unstable --repeat 1
these derivations will be built:
  /nix/store/6im1drv4pklqn8ziywbn44vq8am977vm-unstable.drv
building &#39;/nix/store/6im1drv4pklqn8ziywbn44vq8am977vm-unstable.drv&#39; (round 1/2) on &#39;ssh://eu.nixbuild.net&#39;...
[nixbuild.net] output &#39;/nix/store/srch6l8pyl7z93c7gp1xzf6mq6rwqbaq-unstable&#39; of &#39;/nix/store/6im1drv4pklqn8ziywbn44vq8am977vm-unstable.drv&#39; differs from previous round
error: build of &#39;/nix/store/6im1drv4pklqn8ziywbn44vq8am977vm-unstable.drv&#39; on &#39;ssh://eu.nixbuild.net&#39; failed: build was non-deterministic
builder for &#39;/nix/store/6im1drv4pklqn8ziywbn44vq8am977vm-unstable.drv&#39; failed with exit code 1
error: build of &#39;/nix/store/6im1drv4pklqn8ziywbn44vq8am977vm-unstable.drv&#39; failed</code></pre>
<p>As you can see, the log output differs slightly between the local and the
remote builds. This is because when Nix submits a remote build, it will not do
the determinism check itself, instead it will leave it up to the builder
(nixbuild.net in our case). This is actually a good thing, because it allows
nixbuild.net to perform some optimizations for repeated builds. The following
sections will enumerate those optimizations.</p>
<h2 id="finding-non-determinism-in-past-builds">Finding Non-determinism in Past Builds</h2>
<p>If you locally try to rebuild a something that has failed due to
non-determinism, Nix will build it again at least two times (due to <code>--repeat</code>)
and fail it due to non-determinism again, since it keeps no record of the
previous build failure (other than the build log).</p>
<p>However, nixbuild.net keeps a record of every build performed, also for
repeated builds. So when you try to build the same derivation again,
nixbuild.net is smart enough to look at its past build and figure out that the
derivation is non-deterministic without having to rebuild it. We can
demonstrate this by re-running the last build from the example above:</p>
<pre><code>$ nix-build deterministic.nix -A unstable --repeat 1
these derivations will be built:
  /nix/store/6im1drv4pklqn8ziywbn44vq8am977vm-unstable.drv
building &#39;/nix/store/6im1drv4pklqn8ziywbn44vq8am977vm-unstable.drv&#39; (round 1/2) on &#39;ssh://eu.nixbuild.net&#39;...
[nixbuild.net] output &#39;/nix/store/srch6l8pyl7z93c7gp1xzf6mq6rwqbaq-unstable&#39; of &#39;/nix/store/6im1drv4pklqn8ziywbn44vq8am977vm-unstable.drv&#39; differs from previous round
error: build of &#39;/nix/store/6im1drv4pklqn8ziywbn44vq8am977vm-unstable.drv&#39; on &#39;ssh://eu.nixbuild.net&#39; failed: a previous build of the derivation was non-deterministic
builder for &#39;/nix/store/6im1drv4pklqn8ziywbn44vq8am977vm-unstable.drv&#39; failed with exit code 1
error: build of &#39;/nix/store/6im1drv4pklqn8ziywbn44vq8am977vm-unstable.drv&#39; failed</code></pre>
<p>As you can see, the exact same derivation fails again, but now the build status
message says: <code>a previous build of the derivation was non-deterministic</code>. This
means nixbuild.net didn’t have to run the build, it just checked its past
outputs for the derivation and noticed they differed.</p>
<p>When nixbuild.net looks at past builds it considers all outputs that have been
signed by a key that the account trusts. That means that it can even compare
outputs that have been fetched by substitution.</p>
<h2 id="scaling-out-repeated-builds">Scaling Out Repeated Builds</h2>
<p>When you use <code>--repeat</code>, nixbuild.net will create multiple copies of the build
and schedule all of them like any other build would have been scheduled. This
means that every repeated build will run in parallel, saving time for the user.
As soon as nixbuild.net has found proof of non-determinism, any repeated build
still running will be cancelled.</p>
<h2 id="provoking-non-determinism-through-filesystem-randomness">Provoking Non-determinism through Filesystem Randomness</h2>
<p>As promised in the beginning of this blog post, we have new a feature to
announce! nixbuild.net is now able to inject randomness into the filesystem that
the builds see when they run. This can be used to provoke builds to uncover
non-deterministic behavior.</p>
<p>The idea is not new, it is in fact the exact same concept as have been
implemented in the
<a href="https://salsa.debian.org/reproducible-builds/disorderfs">disorderfs</a> project
by <a href="https://reproducible-builds.org/">reproducible-builds.org</a>. However, we’re
happy to make it easily accessible to nixbuild.net users. The feature is
disabled by default, but can be enabled through a new <a href="https://docs.nixbuild.net/settings/#inject-fs-randomness">user
setting</a>.</p>
<p>For the moment, the implementation will return directory entries in a random
order when enabled. In the future we might inject more metadata randomness.</p>
<p>To demonstrate this feature, let’s use this build:</p>
<pre><code>let
  inherit (import &lt;nixpkgs&gt; {}) runCommand;
in rec {
  files = runCommand &quot;files&quot; {} &#39;&#39;
    mkdir $out
    touch $out/{1..10}
  &#39;&#39;;

  list = runCommand &quot;list&quot; {} &#39;&#39;
    ls -f ${files} &gt; $out
  &#39;&#39;;
}</code></pre>
<p>The <code>files</code> build just creates ten empty files as its output, and the <code>list</code>
build lists those file with <code>ls</code>. The <code>-f</code> option of <code>ls</code> disables sorting
entirely, so the file names will be printed in the order the filesystem returns
them. This means that the build output will depend on how the underlying
filesystem is implemented, which could be considered a non-deterministic
behavior.</p>
<p>First, we build it locally with <code>--repeat</code>:</p>
<pre><code>$ nix-build non-deterministic-fs.nix --builders &quot;&quot; -A list --repeat 1
these derivations will be built:
  /nix/store/153s3ir379cy27wpndd94qlfhz0wj71v-list.drv
building &#39;/nix/store/153s3ir379cy27wpndd94qlfhz0wj71v-list.drv&#39; (round 1/2)...
building &#39;/nix/store/153s3ir379cy27wpndd94qlfhz0wj71v-list.drv&#39; (round 2/2)...
/nix/store/h1591y02qff8vls5v41khgjz2zpdr2mg-list</code></pre>
<p>As you can see, the build succeeded. Then we delete the result from our Nix
store so we can run the build again:</p>
<pre><code>rm result
nix-store --delete /nix/store/h1591y02qff8vls5v41khgjz2zpdr2mg-list</code></pre>
<p>We enable the <code>inject-fs-randomness</code> feature through the <a href="https://docs.nixbuild.net/nixbuild-shell/">nixbuild.net
shell</a>:</p>
<pre><code>nixbuild.net&gt; set inject-fs-randomness true</code></pre>
<p>Then we run the build (with <code>--repeat</code>) on nixbuild.net:</p>
<pre><code>$ nix-build non-deterministic-fs.nix -A list --repeat 1
these derivations will be built:
  /nix/store/153s3ir379cy27wpndd94qlfhz0wj71v-list.drv
building &#39;/nix/store/153s3ir379cy27wpndd94qlfhz0wj71v-list.drv&#39; (round 1/2) on &#39;ssh://eu.nixbuild.net&#39;...
copying 1 paths...
copying path &#39;/nix/store/vl13q40hqp4q8x6xjvx0by06s1v9g3jy-files&#39; to &#39;ssh://eu.nixbuild.net&#39;...
[nixbuild.net] output &#39;/nix/store/h1591y02qff8vls5v41khgjz2zpdr2mg-list&#39; of &#39;/nix/store/153s3ir379cy27wpndd94qlfhz0wj71v-list.drv&#39; differs from previous round
error: build of &#39;/nix/store/153s3ir379cy27wpndd94qlfhz0wj71v-list.drv&#39; on &#39;ssh://eu.nixbuild.net&#39; failed: build was non-deterministic
builder for &#39;/nix/store/153s3ir379cy27wpndd94qlfhz0wj71v-list.drv&#39; failed with exit code 1
error: build of &#39;/nix/store/153s3ir379cy27wpndd94qlfhz0wj71v-list.drv&#39; failed</code></pre>
<p>Now, nixbuild.net found the non-determinism! We can double check that the
directory entries are in a random order by running without <code>--repeat</code>:</p>
<pre><code>$ nix-build non-deterministic-fs.nix -A list
these derivations will be built:
  /nix/store/153s3ir379cy27wpndd94qlfhz0wj71v-list.drv
building &#39;/nix/store/153s3ir379cy27wpndd94qlfhz0wj71v-list.drv&#39; on &#39;ssh://eu.nixbuild.net&#39;...
copying 1 paths...
copying path &#39;/nix/store/h1591y02qff8vls5v41khgjz2zpdr2mg-list&#39; from &#39;ssh://eu.nixbuild.net&#39;...
/nix/store/h1591y02qff8vls5v41khgjz2zpdr2mg-list

$ cat /nix/store/h1591y02qff8vls5v41khgjz2zpdr2mg-list
6
1
2
5
10
7
8
..
9
4
3
.</code></pre>
<h2 id="future-work">Future Work</h2>
<p>There are lots of possibilities to improve the utility of nixbuild.net when it
comes to reproducible builds. Your feedback and ideas are very welcome to
<a href="mailto:support@nixbuild.net">support@nixbuild.net</a>.</p>
<p>Here are some of the things that could be done:</p>
<ul>
<li><p>Make it possible to trigger repeated builds for any previous build, without
submitting a new build with Nix. For example, there could be a command in
the nixbuild.net shell allowing a user to trigger a repeated build and
report back any non-determinism issues.</p></li>
<li><p>Implement functionality similar to <a href="https://diffoscope.org/">diffoscope</a> to
be able to find out exactly what differs between builds. This could be
available as a shell command or through an API.</p></li>
<li><p>Make it possible to download specific build outputs. The way Nix downloads
outputs (and stores them locally) doesn’t allow for having multiple variants
of the same output, but nixbuild.net could provide this functionality
through the shell or an API.</p></li>
<li><p>Inject more randomness inside the sandbox. Since we have complete control
over the sandbox environment we can introduce more differences between
repeated builds to provoke non-determinism. For example, we can schedule
builds on different hardware or use different kernels between repeated
builds.</p></li>
<li><p>Add support for listing known non-deterministic derivations.</p></li>
</ul>]]></description>
    <pubDate>Wed, 13 Jan 2021 00:00:00 UT</pubDate>
    <guid>https://blog.nixbuild.net/posts/2021-01-13-finding-non-determinism-with-nixbuild-net.html</guid>
    <dc:creator>support@nixbuild.net</dc:creator>
</item>
<item>
    <title>The First Year</title>
    <link>https://blog.nixbuild.net/posts/2020-12-29-the-first-year.html</link>
    <description><![CDATA[<p><a href="https://discourse.nixos.org/t/announcing-nixbuild-net-nix-build-as-a-service">One year
ago</a>
nixbuild.net was announced to the Nix community for the very first time. The
service then ran as a closed beta for 7 months until it was made <a href="https://blog.nixbuild.net/posts/2020-08-28-nixbuild-net-is-generally-available.html">generally
available</a>
on the 28th of August 2020.</p>
<p>This blog post will try to summarize how nixbuild.net has evolved since GA four
months ago, and give a glimpse of the future for the service.</p>
<!--more-->
<h2 id="stability-and-performance">Stability and Performance</h2>
<p>Thousands of Nix builds have been built by nixbuild.net so far, and every build
helps in making the service more reliable by uncovering possible edge cases in
the build environment.</p>
<p>These are some of the stability-related improvements and fixes that have been
deployed since GA:</p>
<ul>
<li><p>Better detection and handling of builds that time out or hang.</p></li>
<li><p>Improved retry logic should our backend storage not deliver Nix closures as
expected.</p></li>
<li><p>Fixes to the virtual file system inside the KVM sandbox.</p></li>
<li><p>Better handling of builds that have binary data in their log output.</p></li>
<li><p>Changes to the virtual sandbox environment so it looks even more like a
“standard” Linux environment.</p></li>
<li><p>Application of the <a href="https://nixos.org/manual/nix/stable/#conf-sandbox">Nix sandbox</a>
inside our KVM sandbox. This basically guarantees that the Nix environment
provided through nixbuild.net is identical to the Nix environment for local
builds.</p></li>
<li><p>Support for following HTTP redirects from binary caches.</p></li>
</ul>
<h2 id="even-better-build-reuse">Even Better Build Reuse</h2>
<p>One of the fundamental ideas in nixbuild.net is to try as hard as possible to
<em>not</em> build your builds, if an existing build result can be reused instead. We
can trivially reuse an account’s own builds since they are implicitly trusted
by the user, but also untrusted builds can be reused under certain
circumstances. This has been described in detail in an <a href="https://blog.nixbuild.net/posts/2020-08-13-build-reuse-in-nixbuild-net.html">earlier blog
post</a></p>
<p>Since GA we’ve introduced a number of new ways build results can be reused.</p>
<h3 id="reuse-of-build-failures">Reuse of Build Failures</h3>
<p>Build failures are now also reused. This means that if someone tries to build a
build that is identical (in the sense that the derivation and its transitive
input closure is bit-by-bit identical) to a previously failed build,
nixbuild.net will immediately serve back the failed result instead of
re-running the build. You will even get the build log replayed.</p>
<p>Build failures can be reused since we are confident that our sandbox is pure,
meaning that it will behave exactly the same as long as the build is exactly
the same. Only non-transient failures will be reused. So if the builder
misbehaves in some way that is out of control for Nix, that failure will not be
reused. This can happen if the builder machine breaks down or something similar.
In such cases we will automatically re-run the build anyway.</p>
<p>When we fix bugs or make major changes in our sandbox it can happen that we
alter the behavior in terms of which builds succeed or fail. For example, we
could find a build that fail just because we have missed implementing some
specific detail in the sandbox. Once that is fixed, we don’t want to reuse such
failures. To avoid that, all existing build failures will be “invalidated” on
each major update of the sandbox.</p>
<p>If a user really wants to re-run a failed build on nixbuild.net, failure reuse
can be turned off using the new <em>user settings</em> (see below).</p>
<h3 id="reuse-of-build-timeouts">Reuse of Build Timeouts</h3>
<p>In a similar vein to reused build failures, we can also reuse build timeouts.
This is not enabled by default, since users can select different timeout
limits. A user can activate reuse of build timeouts through the user settings.</p>
<p>The reuse of timed out builds works like this: Each time a new build is
submitted, we check if we have any previous build results of the exact same
build. If no successful results or plain failures are found, we look for builds
that have timed out. We then check if any of the existing timed out builds ran
for longer than the user-specified timeout for the new build. If we can
find such a result, it will be served back to the user instead of re-running
the build.</p>
<p>This feature can be very useful if you want to avoid re-running builds that
timeout over and over again (which can be a very time-consuming excercise). For
example, say that you have your build timeout set to two hours, and some input
needed for a build takes longer than that to build. The first time that input
is needed you have to wait two hours to detect that the build will fail. If
you then try building something else that happens to depend on the very same
input you will save two hours by directly being served the build failure from
nixbuild.net!</p>
<h3 id="wait-for-running-builds">Wait for Running Builds</h3>
<p>When a new build is submitted, nixbuild.net will now check if there is
any identical build currently running (after checking for previous build
results or failures). If there is, the new build will simply hold until the
running build has finished. After that, the result of the running build will
likely be served back as the result of the new build (as long as the running
build wasn’t terminated in a transient way, in which case the new build will
have to run from scratch). The identical running builds are checked and reused
across accounts.</p>
<p>Before this change, nixbuild.net would simply start another build in parallel
even if the builds were identical.</p>
<h2 id="new-features">New Features</h2>
<h3 id="user-settings">User Settings</h3>
<p>A completely new feature has been launched since GA: <strong><a href="https://docs.nixbuild.net/settings/">User
Settings</a></strong>. This allows end users to
tweak the behavior of nixbuild.net. For example, the build reuse described
above can be controlled by user settings. Other settings includes <a href="https://docs.nixbuild.net/settings/#max-cpu-hours-per-month">controlling
the maximum used build time per
month</a>, and the
possibility to <a href="https://docs.nixbuild.net/settings/#allow-override">lock down</a>
specific SSH keys which is useful in CI setups.</p>
<p>The user settings can be set in various way; through the <a href="https://docs.nixbuild.net/nixbuild-shell/index.html#configure-settings">nixbuild.net
shell</a>,
the <a href="https://docs.nixbuild.net/settings/#ssh-environment">SSH client
environment</a> and even
through the <a href="https://docs.nixbuild.net/settings/#nix-derivation">Nix
derivations</a> themselves.</p>
<p>Even if many users probably never need to change any settings, it can be
helpful to read through the
<a href="https://docs.nixbuild.net/settings/">documentation</a> to get a feeling for what
is possible. If you need to differentiate permissions in any way (different
settings for account administrators, developers, CI etc) you should definitely
look into the various user settings.</p>
<h3 id="github-ci-action">GitHub CI Action</h3>
<p>A <a href="https://github.com/marketplace/actions/nixbuild-net">GitHub Action</a> has been
published. This action makes it very easy to use nixbuild.net as a remote Nix
builder in your GitHub Actions workflows. Instead of running you Nix builds on
the two vCPUs provided by GitHub you can now enjoy scale-out Nix builds on
nixbuild.net with minimal setup required.</p>
<p>The nixbuild.net GitHub Action is developed by the nixbuild.net team and there
are plans on adding more functionality that nixbuild.net can offer users, like
automatically generated cost and performance reports for your Nix builds.</p>
<h3 id="shell-improvements">Shell Improvements</h3>
<p>Various minor improvements have been made to the <a href="https://docs.nixbuild.net/nixbuild-shell/">nixbuild.net
shell</a>. It is for example now much
easier to get an overview on how large your next invoice will be, through the
<a href="https://docs.nixbuild.net/nixbuild-shell/#check-your-account-usage">usage</a>
command.</p>
<h2 id="the-future">The Future</h2>
<p>After one year of real world usage, we are very happy with the progress of
nixbuild.net. It has been well received in the Nix community, proved both
reliable and scalable, and it has delivered on our initial vision of a simple
service that can integrate into any setup using Nix.</p>
<p>We feel that we can go anywhere from here, but we also realize that we must be
guided by our users’ needs. We have compiled a small and informal roadmap
below. The items on this list are things that we, based on the feedback we’ve
received throughout the year, think are natural next steps for nixbuild.net.</p>
<p>The roadmap has no dates and no prioritization, and should be seen as merely a
hint about which direction the development is heading. Any question or comment
concerning this list (or what’s missing from the list) is very welcome to
<a href="mailto:support@nixbuild.net">support@nixbuild.net</a>.</p>
<h3 id="support-aarch64-linux-builds">Support aarch64-linux Builds</h3>
<p>Work is already underway to add support for <code>aarch64-linux</code> builds to
nixbuild.net, and so far it is looking good. With the current surge in
performant ARM hardware (Apple M1, Ampere Altra etc), we think having <code>aarch64</code>
support in nixbuild.net is an obvious feature. It is also something that has
been requested by our users.</p>
<p>We don’t know yet how the pricing of <code>aarch64</code> builds will look, or what
scalability promises we can make. If you are interested in evaluating <code>aarch64</code>
builds on nixbuild.net in an early access setting, just send us an email to
<a href="mailto:support@nixbuild.net">support@nixbuild.net</a>.</p>
<h3 id="provide-an-api-over-ssh-and-http">Provide an API over SSH and HTTP</h3>
<p>Currently the <a href="https://docs.nixbuild.net/nixbuild-shell/">nixbuild.net shell</a>
is the administrative tool we offer end users. We will keep developing the
shell and make it more intuitive for interactive use. But will also add an
alternative, more scriptable variant of the shell.</p>
<p>This alternative version will provide roughly the same functionality as the
original shell, only more adapted to scripting instead of interactive use. The reason for
providing such an SSH-based API is to make it easy to integrate nixbuild.net
more tightly into CI and similar scenarios.</p>
<p>There is in fact already a tiny version of this API deployed. You can run the
following command to try it out:</p>
<pre><code>$ ssh eu.nixbuild.net api show public-signing-key
{&quot;keyName&quot;:&quot;nixbuild.net/bob-1&quot;,&quot;publicKey&quot;:&quot;PmUhzAc4Ug6sf1uG8aobbqMdalxW41SHWH7FE0ie1BY=&quot;}</code></pre>
<p>The above API command is in use by the
<a href="https://github.com/nixbuild/nixbuild-action">nixbuild-action</a> for GitHub. So
far, this is the only API command implemented, and it should be seen as a very
first proof of concept. Nothing has been decided on how the API should look and
work in the future.</p>
<p>The API will also be offered over HTTP in addition to SSH.</p>
<h3 id="upload-builds-to-binary-caches">Upload builds to binary caches</h3>
<p>Adding custom binary caches that nixbuild.net can fetch dependencies from is
supported today, although such requests are still handled manually through
support.</p>
<p>We also want to support uploading to custom binary caches. That way users could
gain performance by not having to first download build results from nixbuild.net
and then upload them somewhere else. This could be very useful for CI setups
that can spend a considerable amount of their time just uploading closures.</p>
<h3 id="provide-an-http-based-binary-cache">Provide an HTTP-based binary cache</h3>
<p>Using nixbuild.net as a binary cache is handy since you don’t have to wait
for any uploads after a build has finished. Instead, the closures will be
immediately available in the binary cache, backed by nixbuild.net.</p>
<p>It is actually possible to use nixbuild.net as a binary cache today, by
configuring an SSH-based cache (<code>ssh://eu.nixbuild.net</code>). This works out of the
box right now. You can even use <code>nix-copy-closure</code> to upload paths to
nixbuild.net. We just don’t yet give any guarantees on how long store paths
are kept.</p>
<p>However, there are benfits to providing an HTTP-based cache. It would most
probably have better performance (serving nar files over HTTP instead of using
the <code>nix-store</code> protocol over SSH), but more importantly it would let us use a
CDN for serving cache contents. This could help mitigate the fact that
nixbuild.net is only deployed in Europe so far.</p>
<h3 id="support-builds-that-use-kvm">Support builds that use KVM</h3>
<p>The primary motivation for this is to be able to run NixOS tests (with good
performance) on nixbuild.net.</p>
<h2 id="thank-you">Thank You!</h2>
<p>Finally we’d like to thank all our users. We look forward to an exciting new
year with lots of Nix builds!</p>]]></description>
    <pubDate>Tue, 29 Dec 2020 00:00:00 UT</pubDate>
    <guid>https://blog.nixbuild.net/posts/2020-12-29-the-first-year.html</guid>
    <dc:creator>support@nixbuild.net</dc:creator>
</item>

    </channel>
</rss>
