Next: The GCC toolchain, Previous: Invoking guix environment
, Up: Development [Contents][Index]
guix pack
Occasionally you want to pass software to people who are not (yet!)
lucky enough to be using Guix. You’d tell them to run guix
package -i something
, but that’s not possible in this case. This
is where guix pack
comes in.
Note: If you are looking for ways to exchange binaries among machines that already run Guix, see Invoking
guix copy
, Invokingguix publish
, and Invokingguix archive
.
The guix pack
command creates a shrink-wrapped pack or
software bundle: it creates a tarball or some other archive
containing the binaries of the software you’re interested in, and all
its dependencies. The resulting archive can be used on any machine that
does not have Guix, and people can run the exact same binaries as those
you have with Guix. The pack itself is created in a bit-reproducible
fashion, so anyone can verify that it really contains the build results
that you pretend to be shipping.
For example, to create a bundle containing Guile, Emacs, Geiser, and all their dependencies, you can run:
$ guix pack guile emacs emacs-geiser … /gnu/store/…-pack.tar.gz
The result here is a tarball containing a /gnu/store directory
with all the relevant packages. The resulting tarball contains a
profile with the three packages of interest; the profile is the
same as would be created by guix package -i
. It is this
mechanism that is used to create Guix’s own standalone binary tarball
(see Binary Installation).
Users of this pack would have to run /gnu/store/…-profile/bin/guile to run Guile, which you may find inconvenient. To work around it, you can create, say, a /opt/gnu/bin symlink to the profile:
guix pack -S /opt/gnu/bin=bin guile emacs emacs-geiser
That way, users can happily type /opt/gnu/bin/guile and enjoy.
What if the recipient of your pack does not have root privileges on their machine, and thus cannot unpack it in the root file system? In that case, you will want to use the --relocatable option (see below). This option produces relocatable binaries, meaning they can be placed anywhere in the file system hierarchy: in the example above, users can unpack your tarball in their home directory and directly run ./opt/gnu/bin/guile.
Alternatively, you can produce a pack in the Docker image format using the following command:
guix pack -f docker -S /bin=bin guile guile-readline
The result is a tarball that can be passed to the docker load
command, followed by docker run
:
docker load < file docker run -ti guile-guile-readline /bin/guile
where file is the image returned by guix pack
, and
guile-guile-readline
is its “image tag”. See the
Docker
documentation for more information.
Yet another option is to produce a SquashFS image with the following command:
guix pack -f squashfs bash guile emacs emacs-geiser
The result is a SquashFS file system image that can either be mounted or
directly be used as a file system container image with the
Singularity container execution
environment, using commands like singularity shell
or
singularity exec
.
Several command-line options allow you to customize your pack:
--format=format
-f format
Produce a pack in the given format.
The available formats are:
tarball
This is the default format. It produces a tarball containing all the specified binaries and symlinks.
docker
This produces a tarball that follows the
Docker Image Specification. By default, the “repository name” as it
appears in the output of the docker images
command is computed
from package names passed on the command line or in the manifest file.
Alternatively, the “repository name” can also be configured via the
--image-tag option. Refer to --help-docker-format for
more information on such advanced options.
squashfs
This produces a SquashFS image containing all the specified binaries and symlinks, as well as empty mount points for virtual file systems like procfs.
Note: Singularity requires you to provide /bin/sh in the image. For that reason,
guix pack -f squashfs
always implies-S /bin=bin
. Thus, yourguix pack
invocation must always start with something like:guix pack -f squashfs bash …If you forget the
bash
(or similar) package,singularity run
andsingularity exec
will fail with an unhelpful “no such file or directory” message.
deb
¶This produces a Debian archive (a package with the ‘.deb’ file extension) containing all the specified binaries and symbolic links, that can be installed on top of any dpkg-based GNU(/Linux) distribution. Advanced options can be revealed via the --help-deb-format option. They allow embedding control files for more fine-grained control, such as activating specific triggers or providing a maintainer configure script to run arbitrary setup code upon installation.
guix pack -f deb -C xz -S /usr/bin/hello=bin/hello hello
Note: Because archives produced with
guix pack
contain a collection of store items and because eachdpkg
package must not have conflicting files, in practice that means you likely won’t be able to install more than one such archive on a given system. You can nonetheless pack as many Guix packages as you want in one such archive.
Warning:
dpkg
will assume ownership of any files contained in the pack that it does not know about. It is unwise to install Guix-produced ‘.deb’ files on a system where /gnu/store is shared by other software, such as a Guix installation or other, non-deb packs.
rpm
¶This produces an RPM archive (a package with the ‘.rpm’ file
extension) containing all the specified binaries and symbolic links,
that can be installed on top of any RPM-based GNU/Linux distribution.
The RPM format embeds checksums for every file it contains, which the
rpm
command uses to validate the integrity of the archive.
Advanced RPM-related options are revealed via the --help-rpm-format option. These options allow embedding maintainer scripts that can run before or after the installation of the RPM archive, for example.
The RPM format supports relocatable packages via the --prefix
option of the rpm
command, which can be handy to install an
RPM package to a specific prefix.
guix pack -f rpm -R -C xz -S /usr/bin/hello=bin/hello hello
sudo rpm --install --prefix=/opt /gnu/store/...-hello.rpm
Note: Contrary to Debian packages, conflicting but identical files in RPM packages can be installed simultaneously, which means multiple
guix pack
-produced RPM packages can usually be installed side by side without any problem.
Warning:
rpm
assumes ownership of any files contained in the pack, which means it will remove /gnu/store upon uninstalling a Guix-generated RPM package, unless the RPM package was installed with the --prefix option of therpm
command. It is unwise to install Guix-produced ‘.rpm’ packages on a system where /gnu/store is shared by other software, such as a Guix installation or other, non-rpm packs.
--relocatable
-R
Produce relocatable binaries—i.e., binaries that can be placed anywhere in the file system hierarchy and run from there.
When this option is passed once, the resulting binaries require support for user namespaces in the kernel Linux; when passed twice18, relocatable binaries fall to back to other techniques if user namespaces are unavailable, and essentially work anywhere—see below for the implications.
For example, if you create a pack containing Bash with:
guix pack -RR -S /mybin=bin bash
... you can copy that pack to a machine that lacks Guix, and from your home directory as a normal user, run:
tar xf pack.tar.gz ./mybin/sh
In that shell, if you type ls /gnu/store
, you’ll notice that
/gnu/store shows up and contains all the dependencies of
bash
, even though the machine actually lacks /gnu/store
altogether! That is probably the simplest way to deploy Guix-built
software on a non-Guix machine.
Note: By default, relocatable binaries rely on the user namespace feature of the kernel Linux, which allows unprivileged users to mount or change root. Old versions of Linux did not support it, and some GNU/Linux distributions turn it off.
To produce relocatable binaries that work even in the absence of user namespaces, pass --relocatable or -R twice. In that case, binaries will try user namespace support and fall back to another execution engine if user namespaces are not supported. The following execution engines are supported:
default
Try user namespaces and fall back to PRoot if user namespaces are not supported (see below).
performance
Try user namespaces and fall back to Fakechroot if user namespaces are not supported (see below).
userns
Run the program through user namespaces and abort if they are not supported.
proot
Run through PRoot. The PRoot program provides the necessary support for file system virtualization. It achieves that by using the
ptrace
system call on the running program. This approach has the advantage to work without requiring special kernel support, but it incurs run-time overhead every time a system call is made.fakechroot
Run through Fakechroot. Fakechroot virtualizes file system accesses by intercepting calls to C library functions such as
open
,stat
,exec
, and so on. Unlike PRoot, it incurs very little overhead. However, it does not always work: for example, some file system accesses made from within the C library are not intercepted, and file system accesses made via direct syscalls are not intercepted either, leading to erratic behavior.When running a wrapped program, you can explicitly request one of the execution engines listed above by setting the
GUIX_EXECUTION_ENGINE
environment variable accordingly.
--entry-point=command
Use command as the entry point of the resulting pack, if the pack
format supports it—currently docker
and squashfs
(Singularity)
support it. command must be relative to the profile contained in the
pack.
The entry point specifies the command that tools like docker run
or
singularity run
automatically start by default. For example, you can
do:
guix pack -f docker --entry-point=bin/guile guile
The resulting pack can easily be loaded and docker run
with no extra
arguments will spawn bin/guile
:
docker load -i pack.tar.gz docker run image-id
--entry-point-argument=command
-A command
Use command as an argument to entry point of the resulting pack.
This option is only valid in conjunction with --entry-point
and can
appear multiple times on the command line.
guix pack -f docker --entry-point=bin/guile --entry-point-argument="--help" guile
--max-layers=n
Specifies the maximum number of Docker image layers allowed when building an image.
guix pack -f docker --max-layers=100 guile
This option allows you to limit the number of layers in a Docker image. Docker images are comprised of multiple layers, and each layer adds to the overall size and complexity of the image. By setting a maximum number of layers, you can control the following effects:
--expression=expr
-e expr
Consider the package expr evaluates to.
This has the same purpose as the same-named option in guix
build
(see --expression in
guix build
).
--manifest=file
-m file
Use the packages contained in the manifest object returned by the Scheme code in file. This option can be repeated several times, in which case the manifests are concatenated.
This has a similar purpose as the same-named option in guix
package
(see --manifest) and uses the
same manifest files. It allows you to define a collection of packages
once and use it both for creating profiles and for creating archives
for use on machines that do not have Guix installed. Note that you can
specify either a manifest file or a list of packages,
but not both.
See Writing Manifests, for information on how to write a manifest.
See guix shell --export-manifest
,
for information on how to “convert” command-line options into a
manifest.
--system=system
-s system
Attempt to build for system—e.g., i686-linux
—instead of
the system type of the build host.
--target=triplet
¶Cross-build for triplet, which must be a valid GNU triplet, such
as "aarch64-linux-gnu"
(see GNU
configuration triplets in Autoconf).
--compression=tool
-C tool
Compress the resulting tarball using tool—one of gzip
,
zstd
, bzip2
, xz
, lzip
, or none
for no
compression.
--symlink=spec
-S spec
Add the symlinks specified by spec to the pack. This option can appear several times.
spec has the form source=target
, where
source is the symlink that will be created and target is the
symlink target.
For instance, -S /opt/gnu/bin=bin
creates a /opt/gnu/bin
symlink pointing to the bin sub-directory of the profile.
--save-provenance
Save provenance information for the packages passed on the command line. Provenance information includes the URL and commit of the channels in use (see Channels).
Provenance information is saved in the /gnu/store/…-profile/manifest file in the pack, along with the usual package metadata—the name and version of each package, their propagated inputs, and so on. It is useful information to the recipient of the pack, who then knows how the pack was (supposedly) obtained.
This option is not enabled by default because, like timestamps, provenance information contributes nothing to the build process. In other words, there is an infinity of channel URLs and commit IDs that can lead to the same pack. Recording such “silent” metadata in the output thus potentially breaks the source-to-binary bitwise reproducibility property.
--root=file
¶-r file
Make file a symlink to the resulting pack, and register it as a garbage collector root.
--localstatedir
--profile-name=name
Include the “local state directory”, /var/guix, in the resulting
pack, and notably the /var/guix/profiles/per-user/root/name
profile—by default name is guix-profile
, which corresponds to
~root/.guix-profile.
/var/guix contains the store database (see The Store) as well
as garbage-collector roots (see Invoking guix gc
). Providing it in
the pack means that the store is “complete” and manageable by Guix;
not providing it pack means that the store is “dead”: items cannot be
added to it or removed from it after extraction of the pack.
One use case for this is the Guix self-contained binary tarball (see Binary Installation).
--derivation
-d
Print the name of the derivation that builds the pack.
--bootstrap
Use the bootstrap binaries to build the pack. This option is only useful to Guix developers.
In addition, guix pack
supports all the common build options
(see Common Build Options) and all the package transformation
options (see Package Transformation Options).
Here’s a trick to memorize it: -RR
, which adds
PRoot support, can be thought of as the abbreviation of “Really
Relocatable”. Neat, isn’t it?
Next: The GCC toolchain, Previous: Invoking guix environment
, Up: Development [Contents][Index]