-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: starting to write the nixos hetzner snapshot
- Loading branch information
Showing
3 changed files
with
214 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
--- | ||
date: 2025-01-12 | ||
draft: true | ||
--- | ||
|
||
# Packer: How to Build NixOS 24 Snapshot on Hetzner Cloud | ||
|
||
Packer is a powerful tool to create immutable images, with support for various | ||
cloud providers. | ||
|
||
In this blog post, I share how I built a NixOS 24 snapshot using Packer on | ||
Hetzner Cloud. | ||
|
||
If you're a fan of NixOS or want to learn more about Packer, this post is for | ||
you. | ||
|
||
<!-- more --> | ||
|
||
## Introduction | ||
|
||
I have been on the sidelines waiting for an opportunity to dip my toes into the | ||
NixOS ecosystem. | ||
|
||
I have been hearing a lot of good things about it and I wanted to see what the | ||
fuss was all about. | ||
|
||
Additionally, I have been using Hetzner Cloud for a while now, both personally | ||
and professionally in production setups. | ||
|
||
I thought it would be a good idea to combine the two and see what I can come up | ||
with. | ||
|
||
## Prerequisites | ||
|
||
- Packer v1.11 installed on your local machine[^packer] | ||
- Hetzner Cloud account with an API token | ||
- Use my referral code to get €20 in credits :grimacing:: | ||
<https://hetzner.cloud/?ref=ai5E5vaX1J71> | ||
|
||
## Getting Started | ||
|
||
There are various ways of installing NixOS, and I found it somehow confusing | ||
that the docs are scattered all over the internet, not making it easy for | ||
beginners to get started. | ||
|
||
High barrier to entry is perhaps one of the reasons why NixOS is not as | ||
wide-spread as other Linux distributions! | ||
|
||
## Packer Configuration | ||
|
||
If you know, you know, and if you don't, I'll explain the file as much as | ||
possible in a bit. | ||
|
||
```hcl title="nixos-hetzner.pkr.hcl" | ||
-8<- "docs/blog/posts/2025/002-packer-hetzner/packer/nixos-hetzner.pkr.hcl" | ||
``` | ||
|
||
[^packer]: https://developer.hashicorp.com/packer/install |
156 changes: 156 additions & 0 deletions
156
docs/blog/posts/2025/002-packer-hetzner/packer/nixos-hetzner.pkr.hcl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
packer { | ||
required_plugins { | ||
hcloud = { | ||
version = "< 2.0.0" | ||
source = "github.com/hetznercloud/hcloud" | ||
} | ||
} | ||
} | ||
|
||
variable "hcloud_token" { | ||
type = string | ||
sensitive = true | ||
default = env("HCLOUD_TOKEN") | ||
} | ||
|
||
variable "ssh_public_key" { | ||
type = string | ||
default = "" | ||
} | ||
|
||
locals { | ||
timestamp = regex_replace(timestamp(), "[- TZ:]", "") | ||
ssh_public_key = var.ssh_public_key != "" ? var.ssh_public_key : file(pathexpand("~/.ssh/hetzner-nixos.pub")) | ||
|
||
nixos_version = "24.11" | ||
nixpkgs_version = "branch-off-24.11" | ||
} | ||
|
||
source "hcloud" "nixos" { | ||
image = "debian-12" | ||
rescue = "linux64" | ||
location = "nbg1" | ||
server_type = "cax31" | ||
snapshot_name = "nixos-${local.timestamp}" | ||
snapshot_labels = { | ||
os = "nixos" | ||
timestamp = local.timestamp | ||
} | ||
ssh_username = "root" | ||
token = "${var.hcloud_token}" | ||
} | ||
|
||
build { | ||
sources = ["source.hcloud.nixos"] | ||
|
||
provisioner "file" { | ||
content = <<-EOF | ||
#!/bin/bash | ||
set -eux | ||
export DEBIAN_FRONTEND=noninteractive | ||
apt update | ||
apt install -y squashfs-tools | ||
# ref: https://gist.github.com/chris-martin/4ead9b0acbd2e3ce084576ee06961000 | ||
wget https://channels.nixos.org/nixos-${local.nixos_version}/latest-nixos-minimal-$(uname -m)-linux.iso -O nixos.iso | ||
mkdir nixos | ||
mount -o loop nixos.iso nixos | ||
mkdir /nix | ||
unsquashfs -d /nix/store nixos/nix-store.squashfs | ||
NIXOS_INSTALL=$(find /nix/store -path '*-nixos-install/bin/nixos-install') | ||
NIX_INSTANTIATE=$(find /nix/store -path '*-nix-*/bin/nix-instantiate') | ||
NIXOS_GENERATE_CONFIG=$(find /nix/store -path '*-nixos-generate-config/bin/nixos-generate-config') | ||
export PATH="$(dirname $NIXOS_INSTALL):$(dirname $NIX_INSTANTIATE):$(dirname $NIXOS_GENERATE_CONFIG):$PATH" | ||
groupadd --system nixbld | ||
useradd --system --home-dir /var/empty --shell $(which nologin) -g nixbld -G nixbld nixbld0 | ||
wget https://github.com/NixOS/nixpkgs/archive/refs/tags/${local.nixpkgs_version}.zip -O nixpkgs.zip | ||
unzip nixpkgs.zip | ||
mv nixpkgs-* nixpkgs | ||
export NIX_PATH=nixpkgs=$HOME/nixpkgs | ||
parted -s /dev/sda -- mklabel gpt | ||
parted -s /dev/sda -- mkpart root xfs 512MB -2GB | ||
parted -s /dev/sda -- mkpart swap linux-swap -2GB 100% | ||
parted -s /dev/sda -- mkpart ESP fat32 1MB 512MB | ||
parted -s /dev/sda -- set 3 esp on | ||
mkfs.ext4 -L nixos /dev/sda1 | ||
mkswap -L swap /dev/sda2 | ||
mkfs.fat -F 32 -n boot /dev/sda3 | ||
mount /dev/disk/by-label/nixos /mnt | ||
mkdir -p /mnt/boot | ||
mount -o umask=077 /dev/disk/by-label/boot /mnt/boot | ||
swapon /dev/sda2 | ||
mkdir /mnt/nix | ||
unsquashfs -d /mnt/nix/store nixos/nix-store.squashfs | ||
nixos-generate-config --root /mnt | ||
cat > /mnt/etc/nixos/configuration.nix <<EOL | ||
{ config, pkgs, ... }: | ||
{ | ||
imports = [ ./hardware-configuration.nix ]; | ||
boot.loader.systemd-boot.enable = true; | ||
boot.loader.efi.canTouchEfiVariables = true; | ||
environment.systemPackages = with pkgs; [ | ||
vim | ||
git | ||
wget | ||
curl | ||
tmux | ||
openssh | ||
pkgs.util-linux | ||
]; | ||
networking.hostName = "nixos"; | ||
networking.networkmanager.enable = true; | ||
services.openssh.enable = true; | ||
services.openssh.settings.PermitRootLogin = "prohibit-password"; | ||
users.users.root.openssh.authorizedKeys.keys = [ | ||
"${var.ssh_public_key}" | ||
]; | ||
system.stateVersion = "${local.nixos_version}"; | ||
} | ||
EOL | ||
nixos-install --no-root-passwd --root /mnt | ||
rm -rf /mnt/root/.nix-profile | ||
rm -rf /mnt/root/.nix-defexpr | ||
rm -rf /mnt/root/.nix-channels | ||
rm -rf /tmp/* | ||
nix-collect-garbage -d | ||
rm -rf /var/log/* | ||
EOF | ||
destination = "/tmp/install.sh" | ||
direction = "upload" | ||
} | ||
|
||
provisioner "shell" { | ||
inline = [ | ||
"chmod +x /tmp/install.sh", | ||
"/tmp/install.sh", | ||
] | ||
} | ||
|
||
provisioner "shell" { | ||
inline = [ | ||
"rm -f /tmp/install.sh", | ||
"sync", | ||
] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters