2019-01-17 17:18:00 +03:00
# nixos-generators - one config, multiple formats
The nixos-generators project allows to take the same NixOS configuration, and
generate outputs for different target formats.
2019-02-01 01:06:29 +03:00
Just put your stuff into the configuration.nix and then call one of the image builders.
2018-04-28 13:01:45 +03:00
2023-07-23 19:57:01 +03:00
For example:
2018-04-28 13:01:45 +03:00
```
2019-08-19 17:07:08 +03:00
nixos-generate -f iso
2018-04-28 13:01:45 +03:00
```
2022-11-22 17:51:18 +03:00
2018-05-17 23:46:25 +03:00
or
2019-01-17 17:18:00 +03:00
2018-05-17 23:46:25 +03:00
```
2019-08-19 17:07:08 +03:00
nixos-generate -f iso -c /etc/nixos/configuration.nix
2018-05-17 23:46:25 +03:00
```
2018-04-28 13:01:45 +03:00
2019-01-17 17:18:00 +03:00
it echoes the path to a iso image, which you then can flash onto an usb-stick
or mount & boot in a virtual machine.
2018-04-28 13:01:45 +03:00
2019-01-22 01:47:08 +03:00
# Installation
2021-11-06 09:17:19 +03:00
nixos-generators is part of [nixpkgs ](https://search.nixos.org/packages?channel=unstable&show=nixos-generators&from=0&size=50&sort=relevance&type=packages&query=nixos-generator ) and can be installed from there.
nixos-generators can be also installed from source into the user profile like this:
2019-01-22 01:47:08 +03:00
```console
2019-08-19 17:07:08 +03:00
nix-env -f https://github.com/nix-community/nixos-generators/archive/master.tar.gz -i
2019-01-22 01:47:08 +03:00
```
2021-11-23 04:17:21 +03:00
or for flakes users like this:
```console
nix profile install github:nix-community/nixos-generators
```
2021-11-06 09:17:19 +03:00
or run from the nix flake without installing:
```
nix run github:nix-community/nixos-generators -- --help
```
2019-01-17 17:18:00 +03:00
## Supported formats
2018-04-28 13:01:45 +03:00
2019-01-17 17:18:00 +03:00
format | description
--- | ---
2020-08-18 12:02:48 +03:00
amazon | Amazon EC2 image
2020-05-21 02:37:09 +03:00
azure | Microsoft azure image (Generation 1 / VHD)
2020-10-20 12:15:18 +03:00
cloudstack | qcow2 image for cloudstack
2019-12-01 20:25:19 +03:00
do | Digital Ocean image
2022-04-19 20:09:35 +03:00
docker | Docker image (uses systemd to run, probably only works in podman)
2020-05-21 02:37:09 +03:00
gce | Google Compute image
hyperv | Hyper-V Image (Generation 2 / VHDX)
2019-01-19 00:17:38 +03:00
install-iso | Installer ISO
2019-12-01 22:10:37 +03:00
install-iso-hyperv | Installer ISO with enabled hyper-v support
2019-01-19 00:17:38 +03:00
iso | ISO
2019-01-20 23:32:05 +03:00
kexec | kexec tarball (extract to / and run /kexec_nixos)
kexec-bundle | same as before, but it's just an executable
2021-12-21 03:15:03 +03:00
kubevirt | KubeVirt image
2022-08-16 15:52:07 +03:00
linode | Linode image
2019-02-07 19:59:08 +03:00
lxc | create a tarball which is importable as an lxc container, use together with lxc-metadata
2022-07-14 00:40:15 +03:00
lxc-metadata | the necessary metadata for the lxc image to start, usage: `lxc image import $(nixos-generate -f lxc-metadata) $(nixos-generate -f lxc)`
2019-01-20 23:32:05 +03:00
openstack | qcow2 image for openstack
2021-11-02 17:46:13 +03:00
proxmox | [VMA ](https://pve.proxmox.com/wiki/VMA ) file for proxmox
2022-02-15 21:35:01 +03:00
proxmox-lxc | LXC template for proxmox
2020-05-10 16:33:05 +03:00
qcow | qcow2 image
2023-01-05 07:46:00 +03:00
qcow-efi | qcow2 image with efi support
2022-12-18 11:33:41 +03:00
raw | raw image with bios/mbr. for physical hardware, see the 'raw and raw-efi' section
raw-efi | raw image with efi support. for physical hardware, see the 'raw and raw-efi' section
2020-10-20 12:15:18 +03:00
sd-aarch64 | Like sd-aarch64-installer, but does not use default installer image config.
sd-aarch64-installer | create an installer sd card for aarch64. For cross compiling use `--system aarch64-linux` and read the cross-compile section.
2019-12-20 01:41:25 +03:00
vagrant-virtualbox | VirtualBox image for [Vagrant ](https://www.vagrantup.com/ )
2019-01-20 23:32:05 +03:00
virtualbox | virtualbox VM
2019-01-17 17:18:00 +03:00
vm | only used as a qemu-kvm runner
2020-07-30 13:56:09 +03:00
vm-bootloader | same as vm, but uses a real bootloader instead of netbooting
vm-nogui | same as vm, but without a GUI
2020-05-21 04:07:15 +03:00
vmware | VMWare image (VMDK)
2018-05-11 13:01:00 +03:00
2019-01-17 17:18:00 +03:00
## Usage
2018-05-11 13:01:00 +03:00
2019-08-19 17:07:08 +03:00
Run `nixos-generate --help` for detailed usage information.
2019-01-17 19:38:32 +03:00
2019-12-02 13:27:25 +03:00
## select a specific nixpkgs channel
2023-07-23 19:57:01 +03:00
Adds ability to select a specific channel version.
2019-12-02 13:27:25 +03:00
2023-07-23 19:57:01 +03:00
Example:
2019-12-02 13:27:25 +03:00
```
nix-shell --command './nixos-generate -f iso -I nixpkgs=channel:nixos-19.09'
```
2019-12-01 20:25:19 +03:00
## Using a particular nixpkgs
To use features found in a different nixpkgs (for instance the Digital Ocean
image was recently merged in nixpkgs):
```
NIX_PATH=nixpkgs=../nixpkgs nixos-generate -f do
```
2024-02-10 23:09:12 +03:00
## Setting the disk image size
To specify the size of the generated disk image, use the `--disk-size` argument,
specifying the size in megabytes. This is currently supported by the following
formats. If this argument is unspecified it defaults to automatic sizing based
on the generated NixOS build.
- hyperv
- proxmox
- qcow
- raw-efi
- raw
- vm
- vm-nogui
- vmware
Example (20GB disk):
2024-03-27 15:07:55 +03:00
```bash
2024-02-10 23:09:12 +03:00
nixos-generate -c < your_config.nix > -f < format > --disk-size 20480
```
2024-03-27 15:07:55 +03:00
To set the disk size in `flake.nix` , set `diskSize` in the `specialArgs` argument of the `nixosGenerate` function.
```nix
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11";
nixos-generators = {
url = "github:nix-community/nixos-generators";
inputs.nixpkgs.follows = "nixpkgs";
};
xc = {
url = "github:joerdav/xc";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = { nixpkgs, nixos-generators, xc, ... }:
let
pkgsForSystem = system: import nixpkgs {
inherit system;
overlays = [
(final: prev: { xc = xc.packages.${system}.xc; })
];
};
allVMs = [ "x86_64-linux" "aarch64-linux" ];
forAllVMs = f: nixpkgs.lib.genAttrs allVMs (system: f {
inherit system;
pkgs = pkgsForSystem system;
});
in
{
packages = forAllVMs ({ system, pkgs }: {
vm = nixos-generators.nixosGenerate {
system = system;
specialArgs = {
pkgs = pkgs;
diskSize = 20 * 1024;
};
modules = [
# Pin nixpkgs to the flake input, so that the packages installed
# come from the flake inputs.nixpkgs.url.
({ ... }: { nix.registry.nixpkgs.flake = nixpkgs; })
# Apply the rest of the config.
./configuration.nix
];
format = "raw";
};
});
};
}
```
2019-03-22 17:35:50 +03:00
## Cross Compiling
2022-05-23 19:44:07 +03:00
To cross compile nixos images for other architectures you have to configure
`boot.binfmt.emulatedSystems` or `boot.binfmt.registrations` on your host system.
In your system `configuration.nix` :
2022-11-22 17:51:18 +03:00
2022-05-23 19:44:07 +03:00
```nix
{
# Enable binfmt emulation of aarch64-linux.
boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
}
```
Alternatively, if you want to target other architectures:
2022-11-22 17:51:18 +03:00
2022-05-23 19:44:07 +03:00
```nix
# Define qemu-arm-static source.
let qemu-arm-static = pkgs.stdenv.mkDerivation {
name = "qemu-arm-static";
src = builtins.fetchurl {
url = "https://github.com/multiarch/qemu-user-static/releases/download/v6.1.0-8/qemu-arm-static";
sha256 = "06344d77d4f08b3e1b26ff440cb115179c63ca8047afb978602d7922a51231e3";
};
dontUnpack = true;
installPhase = "install -D -m 0755 $src $out/bin/qemu-arm-static";
};
in {
# Enable binfmt emulation of extra binary formats (armv7l-linux, for exmaple).
boot.binfmt.registrations.arm = {
interpreter = "${qemu-arm-static}/bin/qemu-arm-static";
magicOrExtension = ''\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00'';
mask = ''\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\x00\xff\xfe\xff\xff\xff'';
};
# Define additional settings for nix.
nix.extraOptions = ''
extra-platforms = armv7l-linux
'';
nix.sandboxPaths = [ "/run/binfmt/arm=${qemu-arm-static}/bin/qemu-arm-static" ];
}
```
2019-03-22 17:35:50 +03:00
2022-05-23 19:44:07 +03:00
For more details on configuring `binfmt` , have a look at:
[binfmt options ](https://search.nixos.org/options?channel=unstable&query=boot.binfmt ),
[binfmt.nix ](https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/system/boot/binfmt.nix ),
[this comment ](https://github.com/NixOS/nixpkgs/issues/109661#issuecomment-762629438 ) and
2019-03-22 17:35:50 +03:00
[clevers qemu-user ](https://github.com/cleverca22/nixos-configs/blob/master/qemu.nix ).
2022-05-23 19:44:07 +03:00
Once you've run `nixos-rebuild` with these options,
2019-03-22 17:35:50 +03:00
you can use the `--system` option to create images for other architectures.
2023-07-03 13:52:57 +03:00
## Using as a nixos-module
`nixos-generators` can be included as a `NixOS module` into your existing `configuration.nix` making all available formats available through `config.formats` and configurable through `config.formatConfigs` . New formats can be defined by adding a new entry like `config.formatConfigs.my-new-format = {config, ...}: {}` .
An example `flake.nix` demonstrating this approach is below.
2023-07-23 19:57:01 +03:00
Images can be built from that flake by running:
2023-07-03 13:52:57 +03:00
2023-07-04 11:50:48 +03:00
- `nix build .#nixosConfigurations.my-machine.config.formats.vmware` or
- `nix build .#nixosConfigurations.my-machine.config.formats.my-custom-format` or
- `nix build .#nixosConfigurations.my-machine.config.formats.<any-other-format>`
2023-07-03 13:52:57 +03:00
```nix
{
inputs = {
nixpkgs.url = "nixpkgs/nixos-unstable";
nixos-generators = {
url = "github:nix-community/nixos-generators";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = { self, nixpkgs, nixos-generators, ... }: {
# A single nixos config outputting multiple formats.
# Alternatively put this in a configuration.nix.
2024-07-13 07:31:16 +03:00
nixosModules.myFormats = { config, ... }: {
2023-07-03 13:52:57 +03:00
imports = [
nixos-generators.nixosModules.all-formats
];
nixpkgs.hostPlatform = "x86_64-linux";
# customize an existing format
2023-08-26 11:12:51 +03:00
formatConfigs.vmware = { config, ... }: {
2023-07-03 13:52:57 +03:00
services.openssh.enable = true;
};
# define a new format
2023-08-26 11:12:51 +03:00
formatConfigs.my-custom-format = { config, modulesPath, ... }: {
imports = [ "${toString modulesPath}/installer/cd-dvd/installation-cd-base.nix" ];
2023-07-03 13:52:57 +03:00
formatAttr = "isoImage";
2023-07-22 17:20:50 +03:00
fileExtension = ".iso";
2023-07-03 13:52:57 +03:00
networking.wireless.networks = {
# ...
};
};
2024-07-13 07:31:16 +03:00
};
2023-07-03 13:52:57 +03:00
2024-07-13 07:31:16 +03:00
# a machine consuming the module
nixosConfigurations.my-machine = nixpkgs.lib.nixosSystem {
modules = [ self.nixosModules.myFormats ];
2023-07-03 13:52:57 +03:00
};
};
}
```
2021-11-20 10:35:59 +03:00
## Using in a Flake
`nixos-generators` can be included as a `Flake` input and provides
2024-03-22 12:58:12 +03:00
a `nixosGenerate` function for building images as `Flake` outputs. This
2021-11-20 10:35:59 +03:00
approach pins all dependencies and allows for conveniently defining multiple
2022-11-22 17:51:18 +03:00
output types based on one config.
2021-11-20 10:35:59 +03:00
An example `flake.nix` demonstrating this approach is below. `vmware` or
`virtualbox` images can be built from the same `configuration.nix` by running
`nix build .#vmware` or `nix build .#virtualbox`
2023-01-30 00:05:19 +03:00
Custom formats can be defined by building a format module (see the
[formats ](./formats ) directory for examples) and passing it to `nixosGenerate`
via an the `customFormats` argument. `customFormats` should be in the form of
an attribute sets of the form `<format name> = <format module>` and can define
2023-02-05 02:40:56 +03:00
multiple custom formats. `nixosGenerate` will then match against these custom formats as well as the built in ones.
2023-01-30 00:05:19 +03:00
2021-11-22 09:52:01 +03:00
```nix
2021-11-20 10:35:59 +03:00
{
inputs = {
nixpkgs.url = "nixpkgs/nixos-unstable";
nixos-generators = {
url = "github:nix-community/nixos-generators";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = { self, nixpkgs, nixos-generators, ... }: {
packages.x86_64-linux = {
vmware = nixos-generators.nixosGenerate {
2022-08-13 05:15:38 +03:00
system = "x86_64-linux";
2021-11-20 10:35:59 +03:00
modules = [
# you can include your own nixos configuration here, i.e.
# ./configuration.nix
];
format = "vmware";
2023-01-30 00:05:19 +03:00
2023-04-04 12:21:42 +03:00
# optional arguments:
# explicit nixpkgs and lib:
# pkgs = nixpkgs.legacyPackages.x86_64-linux;
# lib = nixpkgs.legacyPackages.x86_64-linux.lib;
2023-07-23 19:57:01 +03:00
# additional arguments to pass to modules:
2023-04-04 12:21:42 +03:00
# specialArgs = { myExtraArg = "foobar"; };
2023-01-30 00:05:19 +03:00
# you can also define your own custom formats
# customFormats = { "myFormat" = < myFormatModule > ; ... };
# format = "myFormat";
2021-11-20 10:35:59 +03:00
};
vbox = nixos-generators.nixosGenerate {
2022-08-13 05:15:38 +03:00
system = "x86_64-linux";
2021-11-20 10:35:59 +03:00
format = "virtualbox";
};
};
};
}
```
2022-12-18 11:33:41 +03:00
## Format-specific notes
### `raw` and `raw-efi`
`raw` and `raw-efi` images can be used on physical hardware, but benefit from some tweaks.
* These images are configured to log to the serial console, and not to your display. One workaround for this is to add `boot.kernelParams = [ "console=tty0" ];` to your configuration, which will override the image's default `console=ttyS0` .
* By default, grub will timeout after 1 second. To extend this, set `boot.loader.timeout = 5;` (or longer)
* If boot fails for some reason, you will not get a recovery shell unless the root user is enabled, which you can do by setting a password for them (`users.users.root.password = "something";`, possibly `users.mutableUsers = true;` so you can interactively change the passwords after boot)
* After booting, if you intend to use `nixos-switch` , consider using `nixos-generate-config` .
2019-01-17 19:38:32 +03:00
### License
2019-08-19 17:07:08 +03:00
2019-08-19 21:16:16 +03:00
This project is licensed under the [MIT License ](LICENSE ).
2022-04-13 14:03:10 +03:00
# FAQ
#### No space left on device
2023-07-23 19:57:01 +03:00
This means either /tmp, /run/user/$UID or your TMPFS runs full. Sometimes setting TMPDIR to some other location can help, sometimes /tmp needs to be on a bigger partition (not a tmpfs).