Nix Package Manager in an Ubuntu 22.04 LXC Container for Testing: Difference between revisions

From CompleteNoobs
Jump to navigation Jump to search
(Created page with "==prerequisite== * LXD - Basic knowledge , install LXD and launch a container * Terminal: will be using the terminal. == Create a container == <code>lxc launch ubuntu:2204 nix</code> <code>lxc exec nix bash</code> <code>apt update && apt upgrade -y</code> == Optional steps for the paranoid == The default Ubuntu containers come with a user named '''ubuntu'''. In a new container, this user does not have a password set and can run sudo without being prompted for a pa...")
 
 
Line 413: Line 413:


The garbage collector in Nix works by deleting any packages from the Nix store that are no longer referenced by any profiles or by the Nix packages channel. This ensures that it's safe to delete the package: it won't break anything else that depends on it.
The garbage collector in Nix works by deleting any packages from the Nix store that are no longer referenced by any profiles or by the Nix packages channel. This ensures that it's safe to delete the package: it won't break anything else that depends on it.
===Using nix-shell for Temporary Environment===
Nix-shell is a command that creates a temporary environment in your shell with certain packages available. The -p option allows you to specify the packages you want to include. For example, if you want to have gcc (the GNU Compiler Collection) available in your shell, you would use:
<code>nix-shell -p gcc</code>
<div class="toccolours mw-collapsible mw-collapsed">
Explanation: <code>nix-shell -p gcc</code>
<div class="mw-collapsible-content">
The '''nix-shell -p gcc''' command creates a temporary environment with the specified packages available for use:
: '''nix-shell''' : This command creates a temporary shell environment. It's a feature of Nix that lets you create an isolated environment for your shell, where you can make certain packages available without affecting your global environment.
: '''-p gcc''' : The -p option specifies the packages you want to include in your temporary environment. In this case, 'gcc' is specified, so the GNU Compiler Collection will be available in the temporary environment.
This command doesn't affect your global environment or other shells. This feature is useful if you want to test a certain package or need to use different versions of packages for different projects. It can also help with scripting, since you can specify exactly which packages a script needs to run.
</div>
</div>

Latest revision as of 13:45, 17 July 2023

prerequisite

  • LXD - Basic knowledge , install LXD and launch a container
  • Terminal: will be using the terminal.

Create a container

lxc launch ubuntu:2204 nix

lxc exec nix bash

apt update && apt upgrade -y

Optional steps for the paranoid

The default Ubuntu containers come with a user named ubuntu. In a new container, this user does not have a password set and can run sudo without being prompted for a password. This configuration is not ideal from a security perspective.

Create a new user

Next, we will create a new user named nix and set a password for this user. This user will be used for the rest of the setup and general use of the container.

Create the new user:

adduser nix

Follow the prompts to set a password and provide any other requested information.

Adding new user to sudoers file

WARNING: Be cautious while editing the sudoers file as errors could lead to some serious issues with the system. A syntax error in the sudoers file could potentially lock out all users from gaining superuser privileges.

  • Note: by default in Ubuntu when you use visudo the default terminal editor is nano

visudo

Once you're in the editor, you can navigate using the arrow keys. Go down to the section that looks like this:

# User privilege specification
root    ALL=(ALL:ALL) ALL


Below the root user line, add a similar line for the 'nix' user:

nix    ALL=(ALL:ALL) ALL

press CTRL O to write to file and CTRL X to exit.

Delete the 'ubuntu' user

Now that we have a new, secure user set up, we can delete the default ubuntu user for added security.

Delete the ubuntu user:

deluser --remove-home ubuntu

Now, switch to the new nix user:

su - nix

You now have a container set up with the nix user. This user is more secure than the default ubuntu user because it requires a password for sudo operations. You can now proceed with the rest of your setup process.

Download and install

If you did not follow the Optional steps for the paranoid change user to ubuntu

  • su - ubuntu

wget https://nixos.org/nix/install

  • install using Single-user installation

sh install --no-daemon

Return Output:

ubuntu@nix:~$ sh install --no-daemon 
downloading Nix 2.16.1 binary tarball for x86_64-linux from 'https://releases.nixos.org/nix/nix-2.16.1/nix-2.16.1-x86_64-linux.tar.xz' to '/tmp/nix-binary-tarball-unpack.g0HlgbTnoO'...
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 21.0M  100 21.0M    0     0  5176k      0  0:00:04  0:00:04 --:--:-- 5178k
Note: a multi-user installation is possible. See https://nixos.org/manual/nix/stable/installation/installing-binary.html#multi-user-installation
performing a single-user installation of Nix...
directory /nix does not exist; creating it by running 'mkdir -m 0755 /nix && chown ubuntu /nix' using sudo
copying Nix to /nix/store.................................................
installing 'nix-2.16.1'
building '/nix/store/2bdqkggqrhiwrklp7y9sfrqdkrw9xihd-user-environment.drv'...
unpacking channels...
modifying /home/ubuntu/.profile...

Installation finished!  To ensure that the necessary environment
variables are set, either log in again, or type

  . /home/ubuntu/.nix-profile/etc/profile.d/nix.sh

in your shell.

  • set necessary environment variables

. /home/ubuntu/.nix-profile/etc/profile.d/nix.sh

Explanation: . /home/ubuntu/.nix-profile/etc/profile.d/nix.sh

Let's break down the command . /home/ubuntu/.nix-profile/etc/profile.d/nix.sh:

. (also known as source in bash): This is a shell built-in command which reads and executes commands from the file specified as its argument, in the current shell environment. So it is as if they were typed at the keyboard.
/home/ubuntu/.nix-profile/etc/profile.d/nix.sh This is the full path of the script that is sourced.

When you execute the command . /home/ubuntu/.nix-profile/etc/profile.d/nix.sh, you are essentially telling your shell to execute the commands in the nix.sh file within the same shell you're currently running. This is done instead of starting a new shell process, which would be the case if you ran the script like a typical shell script with bash /path/to/script.sh or ./script.sh.

The nix.sh script contains environment variable settings and possibly other setup needed for using Nix packages. By running this script with ., these environment settings are preserved in your current shell.

The . command is often used in configuration and startup scripts where you want settings within a script to affect your current shell's environment.

Channels

A channel in Nix is a collection of Nix expressions (the packages available for installation) that are versioned and updated together. In other words, a channel in Nix is similar to a repository in other types of package management systems.

List channels

nix-channel --list

  • Output:
nixpkgs https://nixos.org/channels/nixpkgs-unstable

Update channels

When you update your channels (with the nix-channel --update command), you're downloading the latest set of package expressions from the channels you are subscribed to.

nix-channel --update

Search a package

Syntax: nix search nixpkgs <PACKAGE_NAME>

nix search nixpkgs bluefish

  • Return Output:
ubuntu@nix:~$ nix search nixpkgs bluefish
error: experimental Nix feature 'nix-command' is disabled; use '--extra-experimental-features nix-command' to override

FIX:

nix search nixpkgs bluefish --extra-experimental-features nix-command

  • Return Ouput:
error: experimental Nix feature 'flakes' is disabled; use '--extra-experimental-features flakes' to override

FIX: nix search nixpkgs bluefish --extra-experimental-features nix-command --extra-experimental-features flakes

  • Ruturn output:
* legacyPackages.x86_64-linux.bluefish (2.2.12)
  A powerful editor targeted towards programmers and webdevelopers
trace: warning: qt5 now uses makeScopeWithSplicing which does not have "overrideScope'", use "overrideScope".


This warning is a developer-oriented message and doesn't directly impact you as an end-user:

The trace: warning message is intended for the maintainers of the package you're trying to install (in this case, the bluefish package from nixpkgs).

Nix is telling us that the qt5 package (which bluefish may depend on) has switched to a different method for managing its internal dependencies. More specifically, it's switched to a method called makeScopeWithSplicing.

This is just a way that Nix organizes and overrides dependencies within packages. It seems like qt5 previously used something called overrideScope', but it now uses makeScopeWithSplicing.

The overrideScope' method is no longer available in this context, so the warning is instructing developers to use makeScopeWithSplicing instead when they're working on the qt5 package or packages that depend on it.

For you as an end-user, there is no action required unless the warning turns into an error or if the package does not work as expected. The package should still install and function normally. This warning is more of an FYI for people maintaining or developing with these packages.


Bluefish is a GUI program and we have not setup container for X forwarding so lets try cowsay.

nix search nixpkgs cowsay --extra-experimental-features nix-command --extra-experimental-features flakes

  • Return output:
    • Note: the package name is after legacyPackages.x86_64-linux.
    • legacyPackages.x86_64-linux.<PACKAGE_NAME>
* legacyPackages.x86_64-linux.charasay (3.0.0)
  The future of cowsay - Colorful characters saying something

* legacyPackages.x86_64-linux.cowsay (3.7.0)
  A program which generates ASCII pictures of a cow with a message

* legacyPackages.x86_64-linux.emacsPackages.cowsay (20210510.1540)

* legacyPackages.x86_64-linux.neo-cowsay (2.0.1)
  Cowsay reborn, written in Go

* legacyPackages.x86_64-linux.pokemonsay (1.0.0)
  Print pokemon in the CLI! An adaptation of the classic cowsay

* legacyPackages.x86_64-linux.ponysay (2021-03-27)
  Cowsay reimplemention for ponies

* legacyPackages.x86_64-linux.tewisay (2022-11-04)
  Cowsay replacement with unicode and partial ansi escape support

* legacyPackages.x86_64-linux.xcowsay (1.6)
  Tool to display a cute cow and messages

Install a package

nix-env -iA nixpkgs.pokemonsay

Explanation: nix-env -iA nixpkgs.pokemonsay

The command nix-env -iA nixpkgs.pokemonsay is used to install the pokemonsay package from the nixpkgs channel in Nix.

Here's a breakdown of the command:

nix-env: This is the main command used for user environment management in Nix. It can install, upgrade, and remove software, among other tasks.
-iA: This is a combination of two options. -i stands for install and -A stands for attribute. The -A option allows you to install a package using its attribute path (nixpkgs.pokemonsay in this case), which is often more reliable than using the package name.
nixpkgs.pokemonsay: This is the attribute path of the package you want to install. nixpkgs is the name of the channel, and pokemonsay is the name of the package in that channel.

So, when you run nix-env -iA nixpkgs.pokemonsay, Nix will look for the pokemonsay package in the nixpkgs channel and install it into your user environment.

Understanding -A flag in Nix commands:

The command nix-env -i <package> installs a package by its name rather than its attribute path. For example, nix-env -i firefox will install the Firefox browser.

This command can sometimes lead to ambiguity because multiple versions of the same package may be available in the channel, or there may be similarly-named packages. This is why it is often recommended to install packages using the -A flag and the package's attribute path, like nix-env -iA nixpkgs.firefox.

It's important to note that while the attribute path usually includes the package name, it might also include other information. For instance, a channel might have separate attributes for different versions of a package, or for the same package built with different options.

Here's a little more information on the difference between these two commands:

  • nix-env -i <package>: This command installs a package by its name. The name is a human-readable identifier for the package, like "firefox".
  • nix-env -iA <attribute path>: This command installs a package by its attribute path. The attribute path is a precise identifier for the package within a channel, like "nixpkgs.firefox". This command is more reliable because it is more specific.

If you're uncertain about the attribute path for a package, you can find it by searching the package in the Nix Packages Search page.

Where does Nix Package Manager install packages?

When you install a package using Nix, the package's files are installed into a directory in the Nix store, which is typically located at /nix/store. Each package gets its own unique directory in the Nix store, which includes a hash of the package's dependencies to ensure isolation and reproducibility.

For example, if you install the pokemonsay package, you might end up with a directory like /nix/store/abcd1234-pokemonsay-0.0.1 (the actual hash will be different).

The binary executables of a package are typically located in the bin subdirectory of the package's directory in the Nix store. For example, the pokemonsay executable might be located at /nix/store/abcd1234-pokemonsay-0.0.1/bin/pokemonsay.

When you install a package with nix-env -i, Nix creates symlinks in your user profile (usually in /nix/var/nix/profiles) to the package's files in the Nix store. When you run a command like pokemonsay, your shell finds the pokemonsay executable through these symlinks.

The result is that each user can have their own set of installed packages, and packages can be installed, upgraded, and removed atomically and without interfering with each other.

using pokemonsay

pokemonsay is a fun little command line utility that generates an ASCII picture of a random Pokemon saying a message you provide. Here's how to use it:

pokemonsay -p Pikachu "Greetings fellow Noob"

Explain Syntax: pokemonsay -p Pikachu "Greetings fellow Noob"

  • pokemonsay is the main command. It's the name of the program you're running. It generates an ASCII art image of a Pokémon saying a message.
  • -p Pikachu is an option given to the pokemonsay command. The -p flag specifies that the next argument will be the name of the Pokémon you want to use. In this case, you're asking for Pikachu.
    • See list of Pokemon Use: pokemonsay -l
  • "Greetings fellow Noob" is the message you're asking Pikachu to say. The quotes are used to group the words together into a single argument to the command. Without the quotes, each word would be treated as a separate argument, which is not what you want in this case.

pokemonsay --help for more info.

Upgrade a package

To upgrade a package installed with Nix, you can use the following command:

nix-env -uA nixpkgs.pokemonsay

Explanation: nix-env -uA nixpkgs.pokemonsay

The command nix-env -uA nixpkgs.pokemonsay is used to upgrade the pokemonsay package from the nixpkgs channel in Nix.

Here's a breakdown of the command:

nix-env: This is the main command used for user environment management in Nix. It can install, upgrade, and remove software, among other tasks.
-uA: This is a combination of two options. -u stands for upgrade and -A stands for attribute. The -A option allows you to upgrade a package using its attribute path (nixpkgs.pokemonsay in this case), which is often more reliable than using the package name.
nixpkgs.pokemonsay: This is the attribute path of the package you want to upgrade. nixpkgs is the name of the channel, and pokemonsay is the name of the package in that channel.

When you run nix-env -uA nixpkgs.pokemonsay, Nix will look for the pokemonsay package in the nixpkgs channel and upgrade it in your user environment.

To upgrade all installed packages in your user environment, you can use the command nix-env -u without specifying a package.



Check for updates

To check for updates to the packages installed on your system without actually installing them, you can use the `nix-env -u` command in "dry run" mode by including the `--dry-run` option. The command would look like this:

nix-env -u --dry-run

Explanation: nix-env -u --dry-run

The nix-env -u --dry-run command will list the updates available for the packages installed on your system without actually applying the updates.

nix-env : This is the main command used for user environment management in Nix.
-u : This flag stands for update. When used alone, it will update all installed packages to their latest versions.
--dry-run : This option prevents the command from actually installing the updates. Instead, it just shows what updates would be installed if you ran the command without the --dry-run option.

List installed packages

To list the packages that you have installed using Nix, you can use the nix-env -q command. If you want to see more details, including the version number, you can use the --verbose flag:

nix-env -q --verbose

Explanation: nix-env -q --verbose

The nix-env -q --verbose command lists all installed packages, showing their names and versions:

nix-env : This is the main command used for user environment management in Nix. It can install, upgrade, and remove software, among other tasks.
-q : This option stands for "query". It lists the installed packages.
--verbose : This option shows more detailed information, including the version number of each installed package.

Check for specific package version

To check the version of a specific package available in the Nix packages channel, you can use the `nix-env -qaP` command with a regex pattern matching the package name:

nix-env -qaP '.*pokemonsay.*'

Explanation: nix-env -qaP '.*pokemonsay.*'

The nix-env -qaP '.*pokemonsay.* command queries the Nix packages channel for available versions of 'pokemonsay', and shows the latest version that is available in the channel.

nix-env : This is the main command used for user environment management in Nix.
-qaP : These options stand for "query available --attr-path". It queries the available packages in the Nix packages channel and shows their attribute paths and versions.
.*pokemonsay.* : This is a regex pattern matching the package name. It will match any package name that contains 'pokemonsay'.
  • .*: This part of the pattern matches any number of any characters. The . means "any character", and the * means "zero or more times".
  • pokemonsay': This is the sequence of characters that you want to find.
  • .*: This part of the pattern matches any number of any characters after 'pokemonsay'.

Certainly, here's the formatted wiki entry:

Remove/Uninstall a Package

To remove or uninstall a package that you have installed using Nix, you can use the nix-env -e command followed by the package name:

nix-env -e pokemonsay

Explanation: nix-env -e pokemonsay

The nix-env -e pokemonsay command uninstalls the 'pokemonsay' package from your user environment in Nix.

Here's a breakdown of the command:

nix-env: This is the main command used for user environment management in Nix.
-e: This option stands for "erase", which is used to remove a package.
pokemonsay: This is the name of the package that you want to remove. You should use the same name format that nix-env -q uses when it lists your installed packages.

After running this command, the 'pokemonsay' package will be removed from your user environment.

To confirm the package has been removed successfully, you can run the nix-env -q command again and you should not see the uninstalled package in the list of installed packages.

Troubleshooting: Uninstalling a Package

In case you encounter an error similar to the following: warning: selector 'nixpkgs.pokemonsay' matched no installed derivations This might mean that the package name you're trying to uninstall does not match exactly with the installed version. You should use the name format that appears when you list your installed packages with the `nix-env -q` command.

This command will only remove the package from your user environment. The package's files will remain in the Nix store (/nix/store) until you run a garbage collection operation, which you can do with the nix-collect-garbage command. This is because other users or profiles might still be using the package.

The garbage collector in Nix works by deleting any packages from the Nix store that are no longer referenced by any profiles or by the Nix packages channel. This ensures that it's safe to delete the package: it won't break anything else that depends on it.

Using nix-shell for Temporary Environment

Nix-shell is a command that creates a temporary environment in your shell with certain packages available. The -p option allows you to specify the packages you want to include. For example, if you want to have gcc (the GNU Compiler Collection) available in your shell, you would use:

nix-shell -p gcc

Explanation: nix-shell -p gcc

The nix-shell -p gcc command creates a temporary environment with the specified packages available for use:

nix-shell : This command creates a temporary shell environment. It's a feature of Nix that lets you create an isolated environment for your shell, where you can make certain packages available without affecting your global environment.
-p gcc : The -p option specifies the packages you want to include in your temporary environment. In this case, 'gcc' is specified, so the GNU Compiler Collection will be available in the temporary environment.

This command doesn't affect your global environment or other shells. This feature is useful if you want to test a certain package or need to use different versions of packages for different projects. It can also help with scripting, since you can specify exactly which packages a script needs to run.