DEVELOPMENT ENVIRONMENT

~liljamo/nix-arta

065f55257a7d1df9c0d2cc9257dbe813b65c0e9f — Jonni Liljamo a month ago 503bc69
feat: LXC docs, base LXC, use NixOS LXC module
M .gitignore => .gitignore +3 -2
@@ 1,2 1,3 @@
.pre-commit-config.yaml
.direnv/
/.pre-commit-config.yaml
/.direnv/
/result

M docs/lxc.md => docs/lxc.md +24 -16
@@ 1,31 1,39 @@
# LXC
Docs for LXC things.

## WIP: Creating a new NixOS LXC container
### Download the NixOS system tarball
Download from [hydra.nixos.org](https://hydra.nixos.org/project/nixos).
"-small" releases don't do system tarballs, download a normal release.

Save the release in Proxmox as "nixos-system-x86_64-linux-${RELEASE}-${BUILD_ID}.tar.xz".\
For example, the current tarball is named "nixos-system-x86_64-linux-24.05-269898867.tar.xz", which comes from [hydra.nixos.org/build/269898867](https://hydra.nixos.org/build/269898867).
## Creating a new NixOS LXC container
### Build the base image
```
nix build ".#lxcbase"
```
Take the output of that, and import it into Proxmox.

### Create the container from the image
Do a normal container setup, and set the IP temporarily via Proxmox.

### Log into the container and ready it for the first remote rebuild
Open root SSH permissions.
Do a normal container setup, without IP setup.

### Make an entry in this repository for the container
Also make secrets configuration.
Add the following to `/etc/pve/lxc/ID.conf` for Tailscale to work:
```
lxc.cgroup2.devices.allow: c 10:200 rwm
lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file
```

### Make an entry in this repository for the wanted container
A bare minimum setup, meaning a host with:
 * the LXC profile,
 * the base role,
 * IP combo in util
 * IP map in util,
 * secrets configured

Get the age key for the host with:
```
nix-shell -p ssh-to-age --run 'ssh-keyscan 10.1.2.2 | ssh-to-age'
```
That might fail at first. If it does, ssh once into the container to trust the
fingerprint and try again.

### nixos-rebuild switch
### Rebuild the real container on top of the base, the base is available at 10.1.2.2
Might need two rebuilds.

### Take out IP configuration from Proxmox
### Profit
And done!


M flake.lock => flake.lock +37 -0
@@ 401,6 401,42 @@
        "type": "github"
      }
    },
    "nixlib": {
      "locked": {
        "lastModified": 1726966855,
        "narHash": "sha256-25ByioeOBFcnitO5lM/Mufnv/u7YtHEHEM8QFuiS40k=",
        "owner": "nix-community",
        "repo": "nixpkgs.lib",
        "rev": "575704ff85d3a41dc5bfef7b55380cbc7b87f3c2",
        "type": "github"
      },
      "original": {
        "owner": "nix-community",
        "repo": "nixpkgs.lib",
        "type": "github"
      }
    },
    "nixos-generators": {
      "inputs": {
        "nixlib": "nixlib",
        "nixpkgs": [
          "nixpkgs"
        ]
      },
      "locked": {
        "lastModified": 1727312535,
        "narHash": "sha256-exnTgS6OBYvEa8v5x8UsLQK2ERdDFwXNFQHoT2cqycY=",
        "owner": "nix-community",
        "repo": "nixos-generators",
        "rev": "f31447cd3f8e54674bd1675969e97e6043a309bc",
        "type": "github"
      },
      "original": {
        "owner": "nix-community",
        "repo": "nixos-generators",
        "type": "github"
      }
    },
    "nixos-hardware": {
      "locked": {
        "lastModified": 1727040444,


@@ 600,6 636,7 @@
        "git-hooks": "git-hooks",
        "home-manager": "home-manager",
        "impermanence": "impermanence",
        "nixos-generators": "nixos-generators",
        "nixos-hardware": "nixos-hardware",
        "nixpkgs": "nixpkgs",
        "nixpkgs-unstable": "nixpkgs-unstable",

M flake.nix => flake.nix +5 -0
@@ 15,6 15,11 @@
      inputs.nixpkgs-stable.follows = "nixpkgs";
    };

    nixos-generators = {
      url = "github:nix-community/nixos-generators";
      inputs.nixpkgs.follows = "nixpkgs";
    };

    # Core
    impermanence.url = "github:nix-community/impermanence";


M systems/default.nix => systems/default.nix +24 -0
@@ 20,9 20,33 @@
          ];
      };

    mkLXCTemplatePackage = name: cfg:
      inputs.nixos-generators.nixosGenerate {
        system = cfg.system;
        specialArgs = cfg.profile.specialArgs;
        modules =
          cfg.profile.modules
          ++ cfg.modules
          ++ [
            {
              networking.hostName = name;
            }
          ];
        format = "proxmox-lxc";
      };

    profiles = import ./profiles lib inputs;
    hosts = import ./hosts profiles;

    templatePackages = {
      lxcbase = {
        system = "x86_64-linux";
        profile = profiles.lxcbase;
        modules = [];
      };
    };
  in {
    nixosConfigurations = inputs.nixpkgs.lib.mapAttrs mkHost hosts;
    packages.x86_64-linux = inputs.nixpkgs.lib.mapAttrs mkLXCTemplatePackage templatePackages;
  };
}

M systems/profiles/default.nix => systems/profiles/default.nix +1 -0
@@ 2,5 2,6 @@ lib: inputs: {
  desktop = import ./desktop inputs;
  laptop = import ./laptop inputs;
  lxc = import ./lxc lib inputs;
  lxcbase = import ./lxcbase lib inputs;
  vm = import ./vm lib inputs;
}

M systems/profiles/lxc/default.nix => systems/profiles/lxc/default.nix +6 -0
@@ 4,6 4,12 @@ lib: inputs @ {
  ...
}: {
  modules = [
    "${inputs.nixpkgs}/nixos/modules/virtualisation/proxmox-lxc.nix"
    {
      proxmoxLXC.manageNetwork = true;
      proxmoxLXC.manageHostName = true;
    }

    sops-nix.nixosModules.sops
    home-manager.nixosModules.home-manager


M systems/profiles/lxc/lxc.nix => systems/profiles/lxc/lxc.nix +0 -10
@@ 6,14 6,6 @@
}: {
  sops.defaultSopsFile = ../../../secrets/${config.networking.hostName}/secrets.yaml;

  boot.isContainer = true;

  # Install new init script
  system.activationScripts.installInitScript = lib.mkForce ''
    mkdir -p /sbin
    ln -fs $systemConfig/init /sbin/init
  '';

  time.timeZone = "Europe/Helsinki";

  networking.defaultGateway = {


@@ 46,8 38,6 @@
  };

  systemd.suppressedSystemUnits = [
    "console-getty.service"
    "getty@.service"
    "systemd-udev-trigger.service"
    "systemd-udevd.service"
    "sys-fs-fuse-connections.mount"

A systems/profiles/lxcbase/default.nix => systems/profiles/lxcbase/default.nix +14 -0
@@ 0,0 1,14 @@
lib: inputs: {
  modules = [
    "${inputs.nixpkgs}/nixos/modules/virtualisation/proxmox-lxc.nix"
    {
      proxmoxLXC.manageNetwork = true;
      proxmoxLXC.manageHostName = true;
    }

    ./lxcbase.nix
  ];
  specialArgs = {
    inherit inputs;
  };
}

A systems/profiles/lxcbase/lxcbase.nix => systems/profiles/lxcbase/lxcbase.nix +48 -0
@@ 0,0 1,48 @@
{lib, ...}: {
  time.timeZone = "Europe/Helsinki";

  networking.defaultGateway = {
    address = "10.1.2.1";
    interface = "eth0";
  };
  networking.nameservers = ["10.1.2.3"];
  networking.interfaces."eth0".ipv4.addresses = [
    {
      address = "10.1.2.2";
      prefixLength = 24;
    }
  ];

  nix.settings.trusted-users = ["root"];

  users.users.root = {
    openssh.authorizedKeys.keys = [
      "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGAlif3ABIk0YSx++A+sEeRYPNMMZWLcDuoTKhmcCL6K jonni@liljamo.com"
    ];
  };

  services.openssh = {
    enable = true;
    settings = {
      PasswordAuthentication = lib.mkForce false;
      KbdInteractiveAuthentication = lib.mkForce false;
      PermitRootLogin = lib.mkForce "prohibit-password";
    };
  };

  systemd.suppressedSystemUnits = [
    "systemd-udev-trigger.service"
    "systemd-udevd.service"
    "sys-fs-fuse-connections.mount"
    "sys-kernel-debug.mount"
    "dev-mqueue.mount"
  ];
  services = {
    journald.extraConfig = "SystemMaxUse=4G";
    cron.systemCronJobs = [
      "0 22 * * * root journalctl --vacuum-time=7d"
    ];
  };

  system.stateVersion = "24.05";
}