Documentation
Deployments
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 Hosting
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 Deployments
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.
Secrets
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 agenix
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 builds
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 servers
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 domain
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.