Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/hraban/nixos-images

Using GH Actions to build NixOS images
https://github.com/hraban/nixos-images

digitalocean nix nixos nixpkgs

Last synced: 4 months ago
JSON representation

Using GH Actions to build NixOS images

Awesome Lists containing this project

README

        

#+title: NixOS images built using Github Actions

Every Sunday the latest DigitalOcean image is built and uploaded as a release. You can download it here:

https://github.com/hraban/nixos-images/releases/download/latest/nixos-digitalocean-x86_64-linux.qcow.gz

* Motivation

This allows me to create tiny DigitalOcean droplets with an up-to-date NixOS system.

Features:

1. No uploading an image from my computer to DigitalOcean (I would need to use a Linux virtual machine, and I have slow upload speed, so it’s a lot of work and it takes too long)
2. Support for small 512MiB RAM droplets (eval’ing nixpkgs takes too much memory on a tiny droplet; without swap enabled you’ll never be able to actually switch to new config)
3. Easy way to keep the boot images up to date (I don’t want to wait 50 minutes while it processes 3 months of updates on boot)

DigitalOcean can download images from a remote URL as long as that URL meets some requirements. Thankfully, GitHub release assets work well for this.

* Example

You can upload a new image to DigitalOcean like this:

#+begin_src shell
url='https://github.com/hraban/nixos-images/releases/download/latest/nixos-digitalocean-x86_64-linux.qcow.gz'
# Pick from $ doctl compute region list
region=nyc1
read -s DIGITALOCEAN_ACCESS_TOKEN
export DIGITALOCEAN_ACCESS_TOKEN
doctl compute image create nixos-nixpkgs-unstable \
--image-url "$url" \
--tag-names nixos \
--region $region
#+end_src

DigitalOcean will download the image directly from GitHub and print its ID. After a few minutes you can use it to create a new droplet.

Minimal example NixOS config:

#+begin_src nix
# When passed as userdata, this config will be activated on boot by a
# digitalocean nixos droplet.

# This next comment line makes the default digitalocean nix image userdata
# handler update the channels:

### https://nixos.org/channels/nixos-unstable nixos

# Remove it if you don’t want that.

# Source: https://github.com/NixOS/nixpkgs/blob/a3ed7406349a9335cb4c2a71369b697cecd9d351/nixos/modules/virtualisation/digital-ocean-init.nix#L59-L91

# N.B.: that trick only works if this is passed as userdata to a fresh DO
# droplet. If used from within a flake on a remote builder it’s obviously not
# necessary in the first place because you’re using the host’s lock file.

{ pkgs, ... }: {
imports = [
# If you’re unsure about this line: keep it.
(builtins.fetchurl "https://raw.githubusercontent.com/hraban/nixos-images/master/digitalocean-config.nix")
];
environment.systemPackages = [ pkgs.hello ];
}
#+end_src

Save that in =do-userdata.nix=, now you can create a fresh droplet:

#+begin_src shell
# your image id
img=12345
# pick a size from: $ doctl compute size list
size=s-1vcpu-512mb-10gb
# Your pre-registered SSH key. $ doctl compute ssh-key list
ssh=54321
doctl compute droplet create mymachine \
--size $size \
--image $img \
--ssh-keys $ssh \
--tag-name nix \
--wait \
--region $region \
--user-data-file ./do-userdata.nix
#+end_src

Wait for your machine to boot and load the fresh config, and you can:

#+begin_example
$ doctl compute ssh mymachine

[root@mymachine:~]# hello
Hello, world!
#+end_example

If the machine has booted but doesn’t seem to have applied your custom config, it’s either still working or it failed to apply it. You can check the logs using =systemctl=.