Typhon: Nix-based continuous integration

Hello everyone! I am glad to present to you Typhon, in collaboration with my colleague Lucas Franceschino.

Short version: Typhon is a prototype for Nix-based continuous integration, iterating over the concepts of Hydra and introducing actions to replace plugins. It is fully declarative, comes with a webapp and is entirely written in Rust. We just announced it at FOSDEM, and we are looking for feedback.


When deploying a Hydra instance at work, we got really frustrated. We found Hydra hard to set up and the plugin system tedious. Our main concerns were the fact that plugins are configured at the system level, they are hard to tweak and the deployment capabilities of runCommand are underwhelming. In the end, we dropped Hydra entirely from our CI’s workflow.


Disappointed with our experience with Hydra, and after long discussions, we decided to start writing our own Hydra!

The main idea of Typhon is to externalize the plugin system entirely, to make it as extensible and customizable as possible. Typhon keeps the core concepts of Hydra and introduces actions. Actions are user-defined Nix derivations used to communicate with the forge or do deployment.

More precisely, actions are scripts executed in isolation of the system but with access to internet and to the Nix store. They are triggered by Typhon on different occasions. At the beginning and end of every job, there is an action run that will, for instance, set statuses on your repository (or deploy something, post a message on Slack, anything!). There is also an action used to update the jobsets of a project in the best way suited for your workflow (for example fetching the PR list using the GitHub API, or just the branches, etc.), and one to receive webhooks and trigger CI automatically. Finally, a project declaration can contain encrypted secrets for the actions (like access tokens or ssh keys).

Thanks to the actions, the server is forge-agnostic, it does not know about GitHub, GitLab, or anything else. It is the action’s job to plug Typhon to a specific forge. You can write actions suited for your workflow, and to help you do this, you can use Typhon’s library. It is quite frugal at the moment, but I hope it will convince you of the potential of actions. Another benefit of actions is that you can build them locally and test them on your computer.

In Typhon, project configuration is entirely declarative: a project declaration is a Nix expression that builds your actions, sets some metadata about your project and exposes your encrypted secrets. Typhon supports both flakes and the classical workflow, as long as your expressions evaluate purely.

Finally, Typhon comes with a webapp. It enables some nice features like live logs for your jobs.

Typhon is written in Rust (both the backend and the frontend), source code isavailable at GitHub - typhon-ci/typhon: Nix-based continuous integration. It is licensed under AGPL.

Last word:

For more information, please visit the documentation. It is a short read and after a general introduction it contains instructions to install Typhon and a tutorial to configure a GitHub project. You can also take a look at the Typhon declaration for Typhon itself, which is deployed on the instance https://etna.typhon-ci.org/.

As I said, the action’s library is quite frugal at the moment, there is no pre-configured deployment actions available. Only generic builders and the GitHub’s wrapper. The reason is that we are not yet sure about the best way to design the library. Should actions be configured like NixOS modules? Or is that a bad idea? Why? We are very much looking for your input on how this should be done!

Please keep in mind that Typhon is a prototype: a lot of features are not yet implemented, the interface is not ideal, and expect to find a lot of bugs. But we consider it ready for a beta, so please try it out and send us feedback! I’m available here, on Matrix or by mail (pnm@pnm.tf) if you have trouble setting it up. Also, don’t hesitate to open issues with feature requests or bug reports.


Any plans to support other forges besides GitHub?

1 Like

Definitely! Even better, the action system should make extending Typhon to new forges very easy. For instance, here are the definitions of the GitHub’s actions that communicate with Typhon through JSON: https://github.com/typhon-ci/typhon/tree/main/nix/lib/github

1 Like

Does this support remote builder for different architecture?

How does this scale? The only reason I’m using hydra is it can handle tens of thousands of jobs in a single evaluation.

1 Like
  • services.typhon.hashedPassword: a string containing the digest of the admin password. Use sha256sum to compute this value.

Dear gods. Please, change that to use Argon2 or at least Bcrypt. Also it would be really handy if that could be provided as file instead of fixed string. That would allow injecting that value from Agenix or similar.


Using remote-builders is on our short-term TODO list, but I have no experience with them yet so any advice on the matter is welcome :slight_smile:

Scaling is an open question. We haven’t looked into this, so probably poorly? Performance on large scale projects is more of a long-term goal to us. We want to first focus on the user experience for smaller projects among the self-hosting folks. To be a little bit cheeky about it, we don’t want to compete with Hydra on its strong points right away, let’s start with its weak points!


Thanks for expressing your concern, which seems shared with other people. I am interested in knowing what is the actual risk here? I will make the change ASAP.

I will also take the opportunity to say that at some point we want to do an overhaul of our authentication system (quote - unquote). We want to manage several users with different permissions. But we did not want to reinvent the wheel, so we want to maybe use an external authentication system (OAuth?). Any opinion on the way to go is welcome!

It is unsalted password hashed with general purpose, GPU-optimisable, hash function. This mean that rainbow table is all you need to find collision. The sole purpose of password hashes (like Argon2 and Bcrypt) is to make it expensive to compute without RAM (so it will not be feasible to compute that on GPU) and to force use of proper salt.

OAuth or similar would be good choice there.


Would love to see OIDC (oauth2 in disguise) support!


Thanks for creating this @pnmadelaine, I am very much hoping gitea gets supported at some stage.

It appears the architecture you have created might make this easier to do than other CI systems :slight_smile:

1 Like

We hope to add support for gitea as well as gitlab soon-ish. I’ve actually already started looking into the documentation for Gitea’s webhooks :slight_smile:


That is great news :ok_hand:t2: having a CI that can build machines and servers from my couple of gitea instances would be great.

Other approaches seem to just rely on Guthub and public repos at that.

How does this compare to Hercules CI ?

We have not tested Hercules CI. But Typhon is free software and Hercules CI is not, so for people like Lucas and I who want to deploy their own infrastructure as much as possible Hercules CI is simply not adequate.

Don’t forget to link the actual FOSDEM talk in the first post of the thread: FOSDEM 2024 - Typhon: Nix-based continuous integration


Thanks, I completely forgot to share the link :sweat_smile: sadly, it appears that you can’t edit discourse posts past a certain time :frowning:

They do have a github org and documentation for their components. Which components are closed source? (I was planning on testing them and possibly your CI too).

My understanding is that the server is completely proprietary, the agent connects to it with a token that’s provided by Hercules CI. It appears that Effects are open-source though, so it could be interesting to look at them and see how they compare with Actions. Both approaches look similar, although according to the documentation effects have access to some local state, actions do not (well I guess you can do anything by using the internet, but it’s not really the spirit ^^)