Documentation

menu
Nix FlakesGarnyaml configWhat Garnix CI doesDeploymentsUsing Private InputsCachingGitHub Actions IntegrationBadges

Deploymentsshare

This feature is currently in a private beta phase, so if you're interested, please join the waitlist.

garnix can deploy your NixOS configurations automatically, keeping them always up to date with the latest commits in your git repo. This can be used for two things:

  • Deploying machines from branches for public consumption, e.g. for production or staging environments.
  • Deploying ephemeral environments from pull-requests, to try them out during development.

Branch Hostingshare

garnix can host NixOS configurations from the latest commit of a specified branch. To enable this feature, simply add a servers section to your garnix.yaml (create a garnix.yaml if you don't yet have one). For example, if you want your deployment to track the branch prod, and the NixOS configuration is called myMachine in flake.nix, you would write:

servers:
  - configuration: myMachine
    deployment:
      type: on-branch
      branch: prod

Additionally, your nixos configuration must have the following items:

  fileSystems."/" = {
    device = "/dev/sda1";
    fsType = "ext4";
  };
  boot.loader.grub.device = "/dev/sda";

If you don't need any secrets in your deployment, that's all there is to it! You can access your machines via URLs that follow this scheme:

<hostname>.<branch>.<myrepo>.<myorg/myuser>.garnix.me

Where hostname is the name of the nixosConfiguration. Whenever there is a new commit, garnix will spin up a new VPS with the new configuration, wait until it's ready, then reroute the traffic to the new machine atomically, and delete the old one.

Note that currently only port 80 is available via the garnix.me URL. If you need other ports – to e.g. SSH into the machine – use the IP address, which you get after each deploy.

Pull-Request Deploymentsshare

The above will redeploy on every commit to the specified branch. That's usually what you want for "production" hosting. But sometimes we want to preview what a pull-request would look like as part of review/QA. We can do that with:

servers:
  - configuration: myMachine
    deployment:
      type: on-pull-request

This will cause the server to be deployed whenever a pull-request is opened, updated whenever the PR gets new commits, and shut down when the pull-request is closed.

Secretsshare

garnix also supports secrets. How this works is that garnix deploys a secret key to your servers. That way, you can use something like agenix or sops-nix to encrypt your secrets for that secret key and deploy them as needed.

Currently garnix generates a single key for each repo, and deploys them to all servers in the path /var/garnix/keys/repo-key. It's root-readable only. To get the public key, you can use curl:

curl https://garnix.io/api/keys/<myorg/myuser>/<myrepo>/repo-key.public

Note that any root exploit can thus gain access to all secrets. For this and other reasons (i.e., hosting and secrets are still alpha), we recommend not yet using highly sensitive secrets.

Secrets with agenixshare

Here's an example of encrypting with agenix. Things should work relatively similarly for sops-nix.

First, we create a secrets.nix file, containing only one secret. It states that all our servers, and we ourselves, should have access to the secret:

let repoKey = <gotten from curl command above>;
    myKey = <gotten from ~/.ssh/id_ed25519.pub or the like>;
in
{
  "sampleSecret.age".publicKeys = [ repoKey myKey ];
}

Then, assuming we have agenix installed, we run:

agenix -e sampleSecret.age

And write the secret in the editor that opens up.

Next we add the agenix repo to our flake inputs:

  inputs.agenix.url = "github:ryantm/agenix";

And the agenix module (agenix.nixosModules.default) to the nixos configuration we want to deploy. Then we add the following:

  age.secrets.sampleSecret = {
    file = ./sampleSecret.age;
  };
  age.identityPaths = [
    "/var/garnix/keys/repo-key"
  ];

See the agenix reference for more options, such as path, modes and ownership. When you deploy, /run/agenix/sampleSecret should contain the secret you encrypted.

Debugging failed buildsshare

One advantage of garnix's approach to deployments is that failed deployments can be debugged at leisure, because they cause no downtime.

If NixOS activation fails, garnix will keep the failed server around until the next deployment. This allows you to ssh in and understand better what happened.

Multiple serversshare

If you need multiple servers talking to one another, get in touch. This already works, but we haven't yet open-sourced the function you need to use to obtain server urls.

Custom domainshare

If you want to use a custom domain, add a CNAME record in your DNS provider to point to the correct deployment. For example:

www.mydomain.com      CNAME       myServer.branch.repo.org.garnix.me

Some providers allow CNAMEs in apex domains (via CNAME flattening), others do not. garnix will work with the former.

Note that currently HTTPS in custom domains is not yet supported.