{"id":16887549,"url":"https://github.com/alicebob/niksnut","last_synced_at":"2025-04-11T12:40:49.986Z","repository":{"id":243347367,"uuid":"807977498","full_name":"alicebob/niksnut","owner":"alicebob","description":"nix build server","archived":false,"fork":false,"pushed_at":"2024-09-18T09:36:02.000Z","size":831,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-10T19:29:58.522Z","etag":null,"topics":["deployment","deployment-automation","manual-deployment","nix","nixos","oldschool"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alicebob.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-05-30T06:29:26.000Z","updated_at":"2024-09-18T09:36:06.000Z","dependencies_parsed_at":"2024-07-14T09:44:08.953Z","dependency_job_id":"66370284-194c-4154-9bff-9c5167a451c2","html_url":"https://github.com/alicebob/niksnut","commit_stats":null,"previous_names":["alicebob/niksnut"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alicebob%2Fniksnut","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alicebob%2Fniksnut/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alicebob%2Fniksnut/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alicebob%2Fniksnut/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alicebob","download_url":"https://codeload.github.com/alicebob/niksnut/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248402525,"owners_count":21097330,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["deployment","deployment-automation","manual-deployment","nix","nixos","oldschool"],"created_at":"2024-10-13T16:44:53.024Z","updated_at":"2025-04-11T12:40:49.336Z","avatar_url":"https://github.com/alicebob.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"Team builder is the simplest possible, Nix based, build server.\n\nYou configure a list with projects, where each project is a git repo with a nix build, and a post build hook to do something with the build result.\n\n\nMain use case (for me) is on demand build+push+kubectl docker containers on stag and prod environments.\n\n\n### Main reasons this exists:\n\n - security: we block access to kubectl from everywhere except our build server. There are also no automated incoming actions to the team builder, so it's easy to lock it down.\n - vanilla nix: this runs on a \"proper\" server, not on containers. You get all the advantages from Nix with a persistent store. No need to mess around with the nix store (e.g. attic or cachix). It also keeps the use of cache.nixos.org to a minimum, which is just polite. And it makes build pretty fast.\n\nThis is not a CI system, I use github actions to do CI, but for production deploys I need more control about what and when.\n\n\n### Example flow\n\nThe core of a build is:\n - click in the UI which project and which branch you want\n - we do a checkout of the branch\n - it runs the configured nix attribute. This is essentially `nix-build -A [what you configured]`.\n - if the main build is done this run the configured shell script, which is essentially `nix-shell -P [what you configured] [your shell]`. This can do scp or kubectl or whatever else you need.\n\n\n### Nix\n\nThis uses only basic Nix commands, and currently doesn't support flakes (I don't use them).  There's no support for Lix, but that would be a good improvement.\n\n\n### UI\n\nThe GUI works 100% without Javascript. Some things are slightly nicer with it, but it's not required. Also: no animations and it's as full screen as possible.\n\nThe CLI executable can also run builds, but it's not really intended as main thing (but you could use cron to schedule builds this way).\n\n\nExample of the main page, which has on the left the list of projects you configured, and on the right the builds:\u003cbr /\u003e\n\u003cimg src=\"./docs/niksnut_index.png\" width=\"400\" /\u003e\u003cbr /\u003e\n\nStarting a new build goes by picking the branch you want:\u003cbr /\u003e\n\u003cimg src=\"./docs/niksnut_newbuild.png\" width=\"400\" /\u003e\u003cbr /\u003e\n\nA build has some basic meta data, and the stdout logs (which streams if you have JS enabled):\u003cbr /\u003e\n\u003cimg src=\"./docs/niksnut_build.png\" width=\"400\" /\u003e\u003cbr /\u003e\n\n\n\n### Config file\n\nThe config file lists your projects. It's nix so you can use variables and expressions and imports, as long as in the end you get this structure:\n\n```\n{\n  projects = [\n    {\n      id = \"hello\";\n      name = \"Hello!\";\n      category = \"just for the UI\"; \n      git = \"ssh://git@github.com/alicebob/gohello;\n      attribute = \"gohello\";\n      packages = [\n        \"which\"\n        \"openssh\"\n      ];\n      post = ''\n        echo which ssh: $(which ssh)\n        echo ssh version: $(ssh -V)\n        echo result: $(./result/bin/gohello)\n      '';\n    }\n  ]\n}\n```\n\nSee ./config.nix as an example.\n\nYou can run `./niksnut --config=./yourconfig.nix check` to check it. Or you can run `nix-instantiate --strict --json --read-write-mode --eval ./config.nix` and see what that gives.\n\nNo yaml!\n\n\n### Security\n\nThe build itself runs in Nix, so that uses the nix sandbox. The post-build script runs as the user you run the daemon as, but can only do what you configure here. This doesn't use containers, and has no other limitations. Limiting access to the http UI is on you. The main use case of this tool is for internal builds, it's not intended as a public build tool.\n\nThere are no incoming links, besides the UI. There's no explicit integration with any git website such as github.\n\n\n### Secrets and keys\n\nIf you need ssh keys or kubectl access set up it's expected that the account under which team builder runs has the required access. In practise that means I add the ssh key to access github via nixos.\n\n\n### Installation\n\nYou need a machine with nix installed, and then you need to set up a (system) account to run this. For nixos you need to add these packages: [pkgs.bash pkgs.git pkgs.nix pkgs.openssh]. Happy to give an example nixos config.\n\nWeb UI runs with: `niksnut --config=./config.nix --buildsdir=./builds/ httpd --listen=localhost:3141`\n\nYou'll want to setup a webserver with access control in front of this. I use nginx with letsencrypt and basic auth.\n\nYou can run builds outside with `./niksnut run yourproject main` if you want to test without UI.\n\n\n### Maintenance\n\nBuilds older than 4 * 24 hours get deleted automatically. If you want to delete builds manually you can delete the directory from `./builds/runs/...`. There is no database, so that's all you need to do.\n\nThis never runs nix-collect-garbage.\n\n\n### Links\n\nWe run this on a Hetzner cloud machine, works well (no referral, just a happy customer): https://www.hetzner.com/cloud/ . The smallest Google Cloud machines are really too weak to run anything useful.\n\nSee https://github.com/alicebob/gonix if you build Go programs and want to speed that up.\n\n`crane` (`gcrane` if you run on Google cloud) is a nice util to push docker images you made with `pkgs.dockerTools.buildImage { ... }` to an image repository. Do use `compressor = \"none\";` to avoid unzipping with crane.\n\n\n### Development\n\nNormally all templates and static files are bundled in the binary, but they will be loaded from disk is you run: `./niksnut -root=. httpd`. You can also add `-offline` if your wifi is bad (but nix sometimes still wants to download things).\n\nThe unit tests do what you expect, and there are some \"integration\" tests which tests with a real git. See `make int`.\n\nThis project is called both \"Team builder\" and \"niksnut\".\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falicebob%2Fniksnut","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falicebob%2Fniksnut","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falicebob%2Fniksnut/lists"}