From 6432c4a5a7b395e21c6da0e254f4ac90f3b9d67f Mon Sep 17 00:00:00 2001 From: Eli Ribble Date: Thu, 10 Jul 2025 21:22:29 +0000 Subject: [PATCH] Add things I've learned from building a custom image Still isn't working quite right, but it's a lot of stuff I'd rather not lose. --- README.md | 34 ++++++++++++++++++++++++++++- digitalocean/create-droplet.sh | 12 ++++++++++ digitalocean/custom-image.nix | 40 +++++++++++++++++++++++----------- digitalocean/infect-nixos.yaml | 3 +++ 4 files changed, 75 insertions(+), 14 deletions(-) create mode 100644 digitalocean/create-droplet.sh create mode 100644 digitalocean/infect-nixos.yaml diff --git a/README.md b/README.md index ae58932..75fd0c8 100644 --- a/README.md +++ b/README.md @@ -9,5 +9,37 @@ Hat tip to [the negation](https://thenegation.com/posts/nixos-do-colmena/) for s Build a custom image for Digital Ocean: ``` -nix-build digitalocean/custom-image.nix +> nix-build digitalocean/custom-image.nix +... +/nix/store/rm84j1a5bskhg2z8gz633m4apjyg848c-digital-ocean-image +> ls -lh result/ +nixos-image-digital-ocean-25.05pre-git-x86_64-linux.qcow2.gz nix-support/ ``` + +In order to "upload" the image to Digital Ocean you'll need to make the image available via URL. We can use Gleipnir static storage as an example: + +``` +rsync result/nixos-image-digital-ocean-25.05pre-git-x86_64-linux.qcow2.gz static.gleipnir.technology:/tmp +``` + +Make sure the image is accessible via a public URL. +Then upload either through the web interface, or using [doctl](https://docs.digitalocean.com/reference/doctl/) + +``` +> doctl compute image create "Gleipnir NixOS 25.05" -v --image-description "NixOS 25.05 with ssh keys for eliribble baked in" --image-distribution nixos-25.05 --image-url "https://static.gleipnir.technology/nixos-image-digital-ocean-25.05pre-git-x86_64-linux.qcow2.gz" --region sfo3 --tag-names nixos +ID Name Type Distribution Slug Public Min Disk Created +192948683 Gleipnir NixOS 25.05 custom Unknown OS false 0 2025-07-10T20:22:43Z1G +``` + +Then start a droplet using that image: + +``` +> doctl compute droplet create "test2.nidus.cloud" --enable-ipv6 --image 192948683 --project-id ce2159e8-02f5-4169-8943-f34ccf812d23 --region sfo3 --size s-1vcpu-1gb --ssh-keys 48777034 --tag-name nixos --wait +Error: POST https://api.digitalocean.com/v2/droplets: 422 (request "116c778d-8e72-4099-a7c6-c3ad37557c4c") image is not compatible with ipv6 +``` + +Oh. [Well that sucks](https://docs.digitalocean.com/products/custom-images/details/limits/). Digital Ocean can't do IPv6 on custom images. + +## With cloud-init +Cloud init data: +curl http://169.254.169.254/metadata/v1.json diff --git a/digitalocean/create-droplet.sh b/digitalocean/create-droplet.sh new file mode 100644 index 0000000..be9fccb --- /dev/null +++ b/digitalocean/create-droplet.sh @@ -0,0 +1,12 @@ +doctl compute droplet create \ + "test.nidus.cloud" \ + --enable-ipv6 \ + --image debian-12-x64 \ + --project-id ce2159e8-02f5-4169-8943-f34ccf812d23 \ + --region sfo3 \ + --size s-1vcpu-1gb \ + --ssh-keys 48777034,46710608 \ + --tag-name nixos \ + --user-data-file digitalocean/infect-nixos.yaml \ + --wait + diff --git a/digitalocean/custom-image.nix b/digitalocean/custom-image.nix index a335093..315d583 100644 --- a/digitalocean/custom-image.nix +++ b/digitalocean/custom-image.nix @@ -1,18 +1,32 @@ let - ## Pin the latest NixOS stable (nixos-25.05) release: - nixpkgs = builtins.fetchTarball { - url = "https://github.com/NixOS/nixpkgs/archive/refs/tags/25.05.tar.gz"; - sha256 = "sha256:0q96nxw7jg9l9zlpa3wkma5xzmgkdnnajapwhgb2fk2ll224rgs1"; - }; + ## Pin the latest NixOS stable (nixos-25.05) release: + nixpkgs = builtins.fetchTarball { + url = "https://github.com/NixOS/nixpkgs/archive/refs/tags/25.05.tar.gz"; + sha256 = "sha256:1915r28xc4znrh2vf4rrjnxldw2imysz819gzhk9qlrkqanmfsxd"; + }; - ## Import nixpkgs: - pkgs = import nixpkgs { }; + ## Import nixpkgs: + pkgs = import nixpkgs { }; - ## Prepare the NixOS configuration: - config = { - imports = [ - "${nixpkgs}/nixos/modules/virtualisation/digital-ocean-image.nix" - ]; - }; + ## Prepare the NixOS configuration: + config = { + imports = [ + "${nixpkgs}/nixos/modules/virtualisation/digital-ocean-image.nix" + ]; + system.stateVersion = "25.05"; + users.users.eliribble = { + extraGroups = [ "sudo" "wheel" ]; + initialHashedPassword = "$y$j9T$XYOMZR8RZEiTnpaF8lsxv1$H7YbWDpzbnYXTLN0ZMhvtKOlSMy64P7C/RdLBaeaNf/"; + isNormalUser = true; + openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBvhtF6nRWlA6PVs71Eek7p0p2PxTd3P6ZEGFV2t75MB eliribble@nixos" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHL1SpT3KR8XeXtH19muncYVrKxWzWdWtJYNTwoJGTm3 eliribble@Elis-Mac-mini.local" + ]; + }; + users.users.root.openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBvhtF6nRWlA6PVs71Eek7p0p2PxTd3P6ZEGFV2t75MB eliribble@nixos" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHL1SpT3KR8XeXtH19muncYVrKxWzWdWtJYNTwoJGTm3 eliribble@Elis-Mac-mini.local" + ]; + }; in (pkgs.nixos config).digitalOceanImage diff --git a/digitalocean/infect-nixos.yaml b/digitalocean/infect-nixos.yaml new file mode 100644 index 0000000..ef0a599 --- /dev/null +++ b/digitalocean/infect-nixos.yaml @@ -0,0 +1,3 @@ +#cloud-config +runcmd: +– curl https://raw.githubusercontent.com/sheran/nixos-infect/master/nixos-infect | PROVIDER=digitalocean NIX_CHANNEL=nixos-23.05 bash 2>&1 | tee /tmp/infect.log