Botanix is the Remote Building & CI System for Nix.
  • Rust 96.1%
  • Nix 3.9%
Find a file
WilliButz c3d218310f tests/garage: move provisioning to service to reuse in nixos-shell
The service should work across reboots, the very simplistic config for
the buckets/keys/permissions should be easy enough to extend for local
development.

Example:
```
$ nix run .#garage
<starts vm and opens root-shell>
[nixos login: root (automatic login)
[root@nixos:~]# garage status
==== HEALTHY NODES ====
ID                Hostname  Address         Tags  Zone    Capacity  DataAvail       Version
fb73d8ca538099d0  nixos     10.0.2.15:3901  []    garage  2.0 GB    1.9 GB (92.8%)  cargo:2.2.0
```

second terminal, inside botanix devshell (for env vars):
```
$ aws s3 cp README.md s3://botanix/test
upload: ./README.md to s3://botanix/test

$ aws s3 ls s3://botanix/test
2026-04-16 17:32:11       3484 test
```

State of the vm is in the gitignored nixos.qcow2 in the repo root.

look at me, I'm the OpenTofu now
2026-04-18 20:14:10 +00:00
nix nix/packages/default: cleanSource -> cleanSourceWith 2026-04-13 23:47:56 +02:00
packaging Remove obsolete grpc_port 2026-03-08 19:03:26 +00:00
proto ADD: botanix-cli with db connexion + protocol 2025-12-27 03:44:18 +00:00
src tests/basic: fix test 2026-04-14 15:00:13 +02:00
tests tests/garage: move provisioning to service to reuse in nixos-shell 2026-04-18 20:14:10 +00:00
.env.example tool(systemd): instructions for developing 2026-04-13 13:59:14 +01:00
.envrc tests/garage: test use of presigned urls before using them in codebase 2026-04-18 20:14:10 +00:00
.gitignore tests/basic: rename from nixos-vm-test and fix group for daemon-access 2026-04-14 13:53:31 +02:00
AUTHORS.md ADD: initial commit : main + cli parser + env config + errors 2025-10-17 01:02:04 +02:00
build.rs checks: add output checks.<system>.fmt-botanix for rustfmt 2026-04-13 17:28:41 +02:00
Cargo.lock tonix: add native-tls-roots so that HTTPS uses system trusted CAs 2026-03-08 19:03:01 +00:00
Cargo.toml tonix: add native-tls-roots so that HTTPS uses system trusted CAs 2026-03-08 19:03:01 +00:00
flake.lock flake: init garage flake app output 2026-04-13 22:43:34 +02:00
flake.nix tests/garage: move provisioning to service to reuse in nixos-shell 2026-04-18 20:14:10 +00:00
LICENSE.md ADD: LICENSE.md 2025-11-14 23:24:15 +00:00
Procfile tool(systemd): instructions for developing 2026-04-13 13:59:14 +01:00
README.md tool(systemd): instructions for developing 2026-04-13 13:59:14 +01:00
sources.nix pre-commit: init 2026-04-13 13:42:32 +02:00

Botanix

A distributed CI/CD system for Nix projects with webhook integration for Git forges.

Overview

Botanix is coordinator-worker system that builds Nix derivations in response to Git webhooks.

Quick Start

Prerequisites

  • Rust (latest stable)
  • Nix with flakes enabled

Create a test repository

Create a public test repository on a public forgejo instance. Since we use forge webhooks, Botanix still needs to clone something.

To have something to build for a quick-start, add a flake.nix like

{
  description = "A very basic flake";

  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
  };

  outputs = { self, nixpkgs }: let pkgs = nixpkgs.legacyPackages.x86_64-linux; in {
    hydraJobs = {
      hello = pkgs.hello.overrideAttrs (_: {
        postPatch = ''
          # noop
        '';
      });
    };
  };
}

Prepare environment

cp .env.example .env

Fill the values like this:

  • leave WORKER_TOKEN empty (will be filled later)
  • set FORGEJO_API to https://your-forgejo.tld/api/v1/
  • create a token in Forgejo in "Settings > Applications", give it read/write access to public repos.

Start the coordinator (Server)

cargo run -- --mode server --port 8080

Start a Worker

First you need a WORKER_TOKEN. You can obtain one by registering with coordinator:

curl -s -X POST /worker/register \
    -H 'Content-Type: application/json' \
    -d '{"systems":[SYSTEM_OF_YOUR_WORKER]}'

Set WORKER_TOKEN to the token from this request.

Now you can start both components with hivemind.

Configure a Webhook

Add a webhook to your Git repository, for now available PROVIDER are { forgejo }

  • URL: http://your-server:8080/webhooks/PROVIDER
  • SECRET: Same as WEBHOOK_SECRET
  • EVENTS: Push events, Pull Request events.

Send a webhook for your test repo

nix run .#forgejo-webhook '{
    "repository":{"name":"your-test-repo","youruser/your-test-repo","clone_url":"https://forgejo.tld/youruser/your-test-repo","ssh_url":"..."},
    "owner":"youruser",
    "ref":"main",
    "after":"'"$(git -C /path/to/your/testrepo log --format="%H" -n 1)"'"
}'

Configuration

Server

  • Required:

    • WEBHOOK_SECRET: HMAC secret for validating webhooks
    • NIX_SYSTEMS: Comma separated systems this server supports (default: x86_64-linux).
  • Optional:

    • FORGEJO_API: Forgejo API base URL for status updates.
    • FORGEJO_TOKEN: Personal Access Token for Forgejo API.
    • PORT: Coordinator http Port, (default: 8080)

Worker

  • Required:

    • COORDINATOR_URL: Coordinator server base URL
    • WORKER_TOKEN: Authentication token.
    • NIX_SYSTEMS: Comma separated systems this worker supports (default: x86_64-linux).
  • Optional:

    • CACHE_URL: Nix binary cache URL for substitutions.
    • CACHE_NETRC_PATH: Path to .netrc file for authenticated cache access.
    • CHECKOUT_DIR: Directory to store git checkouts (default: follows systemd hierarchy).

Checkout Directory configuration

The worker stores cloned git repositories in a checkout directory. By default, this directory is determined in the following order:

Priority order:

  1. CHECKOUT_DIR environment variable (if set by the user).
  2. $RUNTIME_DIRECTORY/botanix/checkouts (if RUNTIME_DIRECTORY is set, typically by systemd).
  3. $TMPDIR/botanix/checkouts (if TMPDIR is set).
  4. /tmp/botanix/checkouts (default fallback).