Removing system packages

Hello Nixers :wave:t2:

I am very new to Nix and need some help figuring out how to remove certain system packages to trim the NixOS down. For context, I am using NixOS inside of LXC containers at the moment and I am trying to shrink the image size. So far I got down to 1.6 Gb, but I feel like I can trim some things even further (coming from Gentoo world where my minimal usable builds were under 200 Mb).

At the moment I am using nix-env --list-generations --profile /nix/var/nix/profiles/system to get me a full list of dependencies required by the system profile. On that list I have quite a few things that I would like to get rid of, for example:

/nix/store/pxp56zkk6wbzf8nrnsq89q73vswy34w8-libressl-3.6.1
/nix/store/0hmm7s3xsip57iza41ybzbqg2aln548s-libressl-3.6.1-nc
/nix/store/di2xpgzgmglq6p6zq4qc8wzlvr7nvzad-mdadm-4.2
/nix/store/9xdak9iv5vvq7xqb2sfy21f3fkxk1c4p-system-sendmail-1.0
/nix/store/0hzd3p6ycddp4mk3scwkqclljfgk4vda-btrfs-progs-6.1.2
/nix/store/sxwpyh0zhg3dwf7izcgjnnya1lskvc2s-mailcap-2.1.53

And many others. Looking for their referrers, I often end up in system-path, system-units or system-shutdown paths and I am struggling to figure out how I can trim them down. For example:

# nix-store --query --referrers /nix/store/di2xpgzgmglq6p6zq4qc8wzlvr7nvzad-mdadm-4.2
/nix/store/di2xpgzgmglq6p6zq4qc8wzlvr7nvzad-mdadm-4.2
/nix/store/0fi5f12xzagldmfni8kb27kzaa9a44h1-system-units
/nix/store/37gpvcj3r1g9qjpr15vv30q6122zc7hn-system-path
/nix/store/5vx86l25fm4wnf95qfiilvxrsriljnk5-system-path
/nix/store/97h0pmajnnyy7zxs4mdxgkjamim589pr-system-units
/nix/store/hhivdc08yk8lmiwaxs1gjxr1hyxx9fmr-system-shutdown
/nix/store/z9zi0vbw3wginj314fkd2wcvgf5l0pvl-system-shutdown

# nix-store --query --referrers /nix/store/0hmm7s3xsip57iza41ybzbqg2aln548s-libressl-3.6.1-nc
/nix/store/37gpvcj3r1g9qjpr15vv30q6122zc7hn-system-path
/nix/store/5vx86l25fm4wnf95qfiilvxrsriljnk5-system-path

What is the best way to approach this?

Appreciate any ideas!

It would help if you shared your config, but some things I know you can get rid of:

environment.defaultPacakages = [];

https://search.nixos.org/options?channel=22.11&show=environment.defaultPackages&from=0&size=50&sort=relevance&type=packages&query=Systempackages

But be careful because this removes nano and you might be left with no way to edit your config.

There’s also lots of required packages here nixpkgs/system-path.nix at cc4bb87f5457ba06af9ae57ee4328a49ce674b1b · NixOS/nixpkgs · GitHub but trying to remove them can be hazardous because the standard NixOS tools like nixos-rebuild probably depend on them.

As for those system services, you might be able to remove them if you figure out what systems.services configuration sets them up. You’re probably going to have to grep the NixOS source code for things like “system-shutdown”.

Hey @ryantm,

Really appreciate your response.

This is my current config:

{ lib, modulesPath, pkgs, ... }: {
  system.stateVersion = "22.11";

  imports = [
    "${toString modulesPath}/virtualisation/lxc-container.nix"
    ./coreutils.nix
    ./dbus.nix
    ./openssh.nix
    ./systemd.nix
    ./util-linux.nix
    ./vim.nix
  ];

  environment.defaultPackages = [];
  environment.systemPackages = with pkgs; [ git ];

  i18n.defaultLocale = "en_AU.UTF-8";

  networking.dhcpcd.enable = false;
  networking.firewall.enable = false;
  networking.hostName = "nixos-lxc";
  networking.resolvconf.enable = false;
  networking.useDHCP = false;
  networking.useNetworkd = true;

  services.nscd.enable = false;
  services.logrotate.enable = lib.mkForce false;

  system.nssModules = lib.mkForce [];

  security.pam.services.su.forwardXAuth = lib.mkForce false;

  # Remove once https://github.com/NixOS/nixpkgs/issues/195795 is fixed
  programs.nano.syntaxHighlight = false;

  fonts.fontconfig.enable = false;

  time.timeZone = "Australia/Sydney";
}

I have a few imports there as well, as you might notice, they are just configuring things in a particular way I need, for example, in dbus.nix I disable X11 integration:

{ ... }: {
  nixpkgs.overlays = [ ( final: prev: {
    dbus = prev.dbus.override {
      x11Support = false;
    };
  } ) ];
}

and in util-linux.nix I disable translations:

{ ... }: {
  nixpkgs.overlays = [ ( final: prev: {
    util-linux = prev.util-linux.override {
      nlsSupport = false;
      translateManpages = false;
    };
  } ) ];
}

and so forth.

I have actually intentionally got rid of nano and replaced it with Vim, so no problem here at all. Thanks for the warning though.

I do understand dangers associated with removing some or all of the packages in that list - I have a lot of experience with Linux, just very little with Nix, i.e. I know what I want to do, just don’t know how to :sweat_smile: (yet)… Do you happen to know how I can actually modify or replace this requiredPackages list? I am quite sure I can get away without cpio, netcat or su in my LXC container.

Also, with that same requiredPackages list I have noticed that mdadm isn’t there, but it is still referenced if I do:

# nix-store --query --referrers /nix/store/di2xpgzgmglq6p6zq4qc8wzlvr7nvzad-mdadm-4.2
...
/nix/store/37gpvcj3r1g9qjpr15vv30q6122zc7hn-system-path
/nix/store/5vx86l25fm4wnf95qfiilvxrsriljnk5-system-path
...

any idea how it is getting there?

Thanks in advance! :bowing_man:t2:

Danger danger don’t copy this without possibly bricking everything:

environment.systemPackages = lib.mkForce [];

This will make it so there are NO system packages installed at all. It will probably break terribly.

1 Like

I suspect mdadm is coming in because of some file system support that maybe you don’t need. I don’t know how to stop that off the top of my head though.

Thank you very much for your help! I will be playing with the mkForce on systemPackages and see how far I can get.

Let’s see if anyone else might have any ideas about mdadm too. :crossed_fingers:t2:

:wave:t2:so, after digging for quite a while and wrapping my head around the whole concept of nixpkgs modules, I have finally found my answer. The swraid module unconditionally adds the mdadm package to the environment.systemPackages.

I have reported the issue on GitHub, but for the time being I solved it by creating the module replacement:

{ config, lib, ... }:


with lib;


let


  cfg = config.boot.initrd.services.swraid;


in




{
  disabledModules = [ "tasks/swraid.nix" ];


  options.boot.initrd.services.swraid = {
    enable = (mkEnableOption (mdDoc "swraid support using mdadm")) // {
      visible = false; # only has effect when the new stage 1 is in place
    };


    mdadmConf = mkOption {
      description = mdDoc "Contents of {file}`/etc/mdadm.conf` in initrd.";
      type = types.lines;
      default = "";
    };
  };


  config = {
    assertions = [
      {
        assertion = cfg.enable != true;
        message = "swraid is forcefully disabled";
      }
    ];
  };
}

Thanks once again @ryantm for giving me some clues to figure out the right direction!

1 Like