From add0fa3e3723f3a9b9b62a6970612c7fde22a0b9 Mon Sep 17 00:00:00 2001 From: Xe Iaso Date: Sun, 1 May 2022 09:12:27 -0400 Subject: [PATCH] Nix flakes 4 wsl (#464) * nix flakes 4: WSL Signed-off-by: Xe Iaso * edits Signed-off-by: Xe Iaso * more edits Signed-off-by: Xe Iaso --- blog/nix-flakes-1-2022-02-21.markdown | 3 + blog/nix-flakes-4-wsl-2022-05-01.markdown | 341 ++++++++++++++++++++++ 2 files changed, 344 insertions(+) create mode 100644 blog/nix-flakes-4-wsl-2022-05-01.markdown diff --git a/blog/nix-flakes-1-2022-02-21.markdown b/blog/nix-flakes-1-2022-02-21.markdown index 7b20dc1..e28ec80 100644 --- a/blog/nix-flakes-1-2022-02-21.markdown +++ b/blog/nix-flakes-1-2022-02-21.markdown @@ -75,6 +75,9 @@ nix = { Then rebuild your system and you can continue along with the article. +EDIT: You can use WSL for this. See +[here](/blog/nix-flakes-4-wsl-2022-05-01) for more information. + If you are not on NixOS, you will need to either edit `~/.config/nix/nix.conf` or `/etc/nix/nix.conf` and add the following line to it: diff --git a/blog/nix-flakes-4-wsl-2022-05-01.markdown b/blog/nix-flakes-4-wsl-2022-05-01.markdown new file mode 100644 index 0000000..1608e61 --- /dev/null +++ b/blog/nix-flakes-4-wsl-2022-05-01.markdown @@ -0,0 +1,341 @@ +--- +title: "Nix Flakes on WSL" +date: 2022-05-01 +series: nix-flakes +tags: + - nixos + - wsl +vod: + youtube: https://youtu.be/VzQ_NwFJObc + twitch: https://www.twitch.tv/videos/1464781566 +--- + +About five years ago, Microsoft released the Windows Subsystem for Linux +([WSL](https://docs.microsoft.com/en-us/windows/wsl/)). This allows you to run +Linux programs on a Windows machine. When they released WSL version 2 in 2019, +this added support for things like Docker and systemd. As a result, this is +enough to run NixOS on Windows. + +This will give you an environment to run +Nix and Nix Flakes commands with. You can use this to follow along with this +series without having to install NixOS on a VM or cloud server. This is going to +retread a bunch of ground from the first article. If you have been following +along through this entire series, once you get to the point where you convert +the install to flakes there isn't much more new material here. + + +## Installation + +Head to the NixOS-WSL [releases +page](https://github.com/nix-community/NixOS-WSL/releases/) and download the +`nixos-wsl-installer-fixed.tar.gz` file to your Downloads folder. + +Then open Powershell and make a folder called `WSL`: + +```powershell +New-Item -Path .\WSL -ItemType Directory +``` + +It's worth noting that Powershell does +have a bunch of aliases for common coreutils commands to the appropriate +Powershell CMDlets. However these aliases are NOT flag-compatible and use +the Powershell semantics instead of the semantics of the command it is aliasing. +This will bite you when you use commands like wget out of instinct +to download things. In order to avoid your muscle memory betraying you, the +Powershell CMDlets are shown here in their full overly verbose glory. + + +Then enter the directory with `Set-Location`: + +```powershell +Set-Location -Path .\WSL +``` + +This directory is where the NixOS root +filesystem will live. If you want to put this somewhere else, feel free to. +Somewhere in `%APPDATA%` will work, just as long as it's on an NTFS volume +somewhere. + + +Make a folder for the NixOS filesystem: + +```powershell +New-Item -Path .\NixOS -ItemType Directory +``` + +Then install the NixOS root image with the `wsl` command: + +```powershell +wsl --import NixOS .\NixOS\ ..\Downloads\nixos-wsl-installer-fixed.tar.gz --version 2 +``` + +And start NixOS once to have it install itself: + +```powershell +wsl -d NixOS +``` + +Once that finishes, press control-D (or use the `exit` command) to exit out of +NixOS and restart the WSL virtual machine: + +```powershell +exit +wsl --shutdown +wsl -d NixOS +``` + +And then you have yourself a working NixOS environment! It's very barebones, but +we can use it to test the `nix run` command against our gohello command: + +```console +$ nix run github:Xe/gohello +Hello reader! +``` + +## Local Services + +We can also use this NixOS environment to run a local nginx server. Open +`/etc/nixos/configuration.nix`: + +```nix +{ lib, pkgs, config, modulesPath, ... }: + +with lib; +let + nixos-wsl = import ./nixos-wsl; +in +{ + imports = [ + "${modulesPath}/profiles/minimal.nix" + + nixos-wsl.nixosModules.wsl + ]; + + wsl = { + enable = true; + automountPath = "/mnt"; + defaultUser = "nixos"; + startMenuLaunchers = true; + + # Enable integration with Docker Desktop (needs to be installed) + # docker.enable = true; + }; + + # Enable nix flakes + nix.package = pkgs.nixFlakes; + nix.extraOptions = '' + experimental-features = nix-command flakes + ''; +} +``` + +Right after the `wsl` block, add this nginx configuration to the file: + +```nix +services.nginx.enable = true; +services.nginx.virtualHosts."test.local.cetacean.club" = { + root = "/srv/http/test.local.cetacean.club"; +}; +``` + +This will create an nginx configuration that points the domain +`test.local.cetacean.club` to the contents of the folder `/srv/http/test.local.cetacean.club`. + +The /srv folder is set aside +for site-specific data, which is code for "do whatever you want with this +folder". In many cases people make a separate /srv/http folder and +put each static subdomain in its own folder under that, however I am also told +that it is idiomatic to put stuff in /var/www. Pick your poison. + + +Then you can test the web server with the `curl` command: + +```console +$ curl http://test.local.cetacean.club + +404 Not Found + +

404 Not Found

+
nginx
+ + +``` + +This is good! Nginx is running and since we haven't created the folder with our +website content yet, this 404 means that it can't find it! Let's create the +folder so that nginx has permission to it and we can modify things in it: + +``` +sudo mkdir -p /srv/http/test.local.cetacean.club +sudo chown nixos:nginx /srv/http/test.local.cetacean.club +``` + +Finally we can make an amazing website. Open +`/srv/http/test.local.cetacean.club/index.html` in nano: + +``` +nano /srv/http/test.local.cetacean.club/index.html +``` + +And paste in this HTML: + +```html +amazing website xD +

look at my AMAZING WEBSITE

+It's so cool *twerks* +``` + +This doesn't have to just be artisanal +handcrafted HTML in bespoke folders either. You can set the root of +a nginx virtual host to point to a Nix package as well. This will allow you to +automatically generate your website somehow and deploy it with the rest of the +system. Including being able to roll back changes. + +And then you can see it show up with `curl`: + +```console +$ curl http://test.local.cetacean.club +amazing website xD +

look at my AMAZING WEBSITE

+It's so cool *twerks* +``` + +You can also check this out in a browser by clicking +[here](http://test.local.cetacean.club): + +![a browser window titled "amazing website xD" with the header "look at my +AMAZING WEBSITE" and content of "It's so cool +\*twerks\*"](https://cdn.christine.website/file/christine-static/blog/Screenshot+2022-04-23+141937.png) + +## Installing `gohello` + +To install the `gohello` service, first we will need to convert this machine to +use NixOS flakes. We can do that really quick and easy by adding this file to +`/etc/nixos/flake.nix`: + +Do this as root! + +```nix +{ + inputs = { + nixpkgs.url = "nixpkgs/nixos-unstable"; + }; + + outputs = { self, nixpkgs, ... }: { + nixosConfigurations.nixos = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ + ./configuration.nix + + # add things here + ]; + }; + }; +} +``` + +Then run `nix flake check` to make sure everything is okay: + +``` +sudo nix flake check /etc/nixos +``` + +And finally activate the new configuration with flakes: + +``` +sudo nixos-rebuild switch +``` + +Why don't you have the --flake +flag here? Based on what I read in the documentation, I thought you had to have +it there. + +nixos-rebuild will +auomatically detect flakes in /etc/nixos. The only major thing it +cares about is the hostname matching. If you want to customize the hostname of +the WSL VM, change the nixos in +nixosConfigurations.nixos above and set +networking.hostName to the value you want to use. To use flakes +explicitly, pass --flake /etc/nixos#hostname to your +nixos-rebuild call. + + +After it thinks for a bit, you should notice that nothing happened. This is +good, we have just converted the system over to using Nix flakes instead of the +classic `nix-channel` rebuild method. + +To get `gohello` in the system, first we need to add `git` to the commands +available on the system in `configuration.nix`: + +```nix +environment.systemPackages = with pkgs; [ git ]; +``` + +Then we can add `gohello` to our system flake: + +```nix +{ + inputs = { + nixpkgs.url = "nixpkgs/nixos-unstable"; + # XXX(Xe): this URL may change for you, such as github:Xe/gohello-http + gohello.url = "git+https://tulpa.dev/cadey/gohello-http?ref=main"; + }; + + outputs = { self, nixpkgs, gohello, ... }: { + nixosConfigurations.nixos = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ + ./configuration.nix + + # add things here + gohello.nixosModule + ({ pkgs, ... }: { + xeserv.services.gohello.enable = true; + }) + ]; + }; + }; +} +``` + +The block of code under +gohello.nixosModule is an inline NixOS module. If we put +gohello.nixosModule before the ./configuration.nix +reference, we could put the xeserv.services.gohello.enable = true; +line inside ./configuration.nix. This is an exercise for the +reader. + +And rebuild the system with `gohello` enabled: + +``` +sudo nixos-rebuild switch +``` + +Finally, poke it with `curl`: + +```console +$ curl http://gohello.local.cetacean.club +hello world :) +``` + +To update it, update the flake inputs in `/etc/nixos` and run `nixos-rebuild`: + +``` +sudo nix flake update /etc/nixos +sudo nixos-rebuild switch +``` + +--- + +And from here you can do whatever you want with NixOS. You can use +[containers](https://nixos.org/manual/nixos/stable/#ch-containers), set up +arbitrary services, or plan for world domination as normal. + +I thought it was "to save the world from +devastation", not "to plan for world domination". Who needs a monopoly on +violence for world domination when you have Nix expressions? + +Siiiiiiiiiiiiiiiiiigh. + +I will use this setup in future posts to make this more accessible and easy to +hack at without having to have a dedicated NixOS machine laying around.