gnu: adms: Update to 2.3.7.
[jackhill/guix/guix.git] / doc / guix-cookbook.texi
index 02869a8..a783c0a 100644 (file)
 Copyright @copyright{} 2019 Ricardo Wurmus@*
 Copyright @copyright{} 2019 Efraim Flashner@*
 Copyright @copyright{} 2019 Pierre Neidhardt@*
+Copyright @copyright{} 2020 Oleg Pykhalov@*
+Copyright @copyright{} 2020 Matthew Brooks@*
+Copyright @copyright{} 2020 Marcin Karpezo@*
+Copyright @copyright{} 2020 Brice Waegeneire@*
+Copyright @copyright{} 2020 André Batista@*
+Copyright @copyright{} 2020 Christopher Lemmer Webber
 
 Permission is granted to copy, distribute and/or modify this document
 under the terms of the GNU Free Documentation License, Version 1.3 or
@@ -59,6 +65,7 @@ Translation Project}.
 * Packaging::                   Packaging tutorials
 * System Configuration::        Customizing the GNU System
 * Advanced package management:: Power to the users!
+* Environment management::      Control environment
 
 * Acknowledgments::             Thanks!
 * GNU Free Documentation License::  The license of this document.
@@ -105,15 +112,16 @@ Let's get started!
 
 Guix uses the Guile implementation of Scheme.  To start playing with the
 language, install it with @code{guix install guile} and start a
-@uref{https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop,
-REPL} by running @code{guile} from the command line.
+@dfn{REPL}---short for @uref{https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop,
+@dfn{read-eval-print loop}}---by running @code{guile} from the command line.
 
 Alternatively you can also run @code{guix environment --ad-hoc guile -- guile}
 if you'd rather not have Guile installed in your user profile.
 
-In the following examples we use the @code{>} symbol to denote the REPL
-prompt, that is, the line reserved for user input.  @xref{Using Guile
-Interactively,,, guile, GNU Guile Reference Manual}) for more details on the
+In the following examples, lines show what you would type at the REPL;
+lines starting with ``@result{}'' show evaluation results, while lines
+starting with ``@print{}'' show things that get printed.  @xref{Using Guile
+Interactively,,, guile, GNU Guile Reference Manual}, for more details on the
 REPL.
 
 @itemize
@@ -121,17 +129,20 @@ REPL.
 Scheme syntax boils down to a tree of expressions (or @emph{s-expression} in
 Lisp lingo).  An expression can be a literal such as numbers and strings, or a
 compound which is a parenthesized list of compounds and literals.  @code{#t}
-and @code{#f} stand for the booleans "true" and "false", respectively.
+and @code{#f} stand for the Booleans ``true'' and ``false'', respectively.
 
 Examples of valid expressions:
 
 @lisp
-> "Hello World!"
 "Hello World!"
-> 17
+@result{} "Hello World!"
+
 17
-> (display (string-append "Hello " "Guix" "\n"))
-"Hello Guix!"
+@result{} 17
+
+(display (string-append "Hello " "Guix" "\n"))
+@print{} Hello Guix!
+@result{} #<unspecified>
 @end lisp
 
 @item
@@ -144,8 +155,8 @@ last evaluated expression as its return value.
 Anonymous functions are declared with the @code{lambda} term:
 
 @lisp
-(lambda (x) (* x x))
-#<procedure 120e348 at <unknown port>:24:0 (x)>
+(lambda (x) (* x x))
+@result{} #<procedure 120e348 at <unknown port>:24:0 (x)>
 @end lisp
 
 The above procedure returns the square of its argument.  Since everything is
@@ -153,18 +164,18 @@ an expression, the @code{lambda} expression returns an anonymous procedure,
 which can in turn be applied to an argument:
 
 @lisp
-((lambda (x) (* x x)) 3)
-9
+((lambda (x) (* x x)) 3)
+@result{} 9
 @end lisp
 
 @item
 Anything can be assigned a global name with @code{define}:
 
 @lisp
-(define a 3)
-(define square (lambda (x) (* x x)))
-(square a)
-9
+(define a 3)
+(define square (lambda (x) (* x x)))
+(square a)
+@result{} 9
 @end lisp
 
 @item
@@ -178,58 +189,63 @@ Procedures can be defined more concisely with the following syntax:
 A list structure can be created with the @code{list} procedure:
 
 @lisp
-(list 2 a 5 7)
-(2 3 5 7)
+(list 2 a 5 7)
+@result{} (2 3 5 7)
 @end lisp
 
 @item
-The @emph{quote} disables evaluation of a parenthesized expression: the first
-term is not called over the other terms.  Thus it effectively returns a list
-of terms.
+The @dfn{quote} disables evaluation of a parenthesized expression: the
+first term is not called over the other terms (@pxref{Expression Syntax,
+quote,, guile, GNU Guile Reference Manual}).  Thus it effectively
+returns a list of terms.
 
 @lisp
-> '(display (string-append "Hello " "Guix" "\n"))
-(display (string-append "Hello " "Guix" "\n"))
-> '(2 a 5 7)
-(2 a 5 7)
+'(display (string-append "Hello " "Guix" "\n"))
+@result{} (display (string-append "Hello " "Guix" "\n"))
+
+'(2 a 5 7)
+@result{} (2 a 5 7)
 @end lisp
 
 @item
-The @emph{quasiquote} disables evaluation of a parenthesized expression until
-a comma re-enables it.  Thus it provides us with fine-grained control over
-what is evaluated and what is not.
+The @dfn{quasiquote} disables evaluation of a parenthesized expression
+until @dfn{unquote} (a comma) re-enables it.  Thus it provides us with
+fine-grained control over what is evaluated and what is not.
 
 @lisp
-`(2 a 5 7 (2 ,a 5 ,(+ a 4)))
-(2 a 5 7 (2 3 5 7))
+`(2 a 5 7 (2 ,a 5 ,(+ a 4)))
+@result{} (2 a 5 7 (2 3 5 7))
 @end lisp
 
 Note that the above result is a list of mixed elements: numbers, symbols (here
 @code{a}) and the last element is a list itself.
 
 @item
-Multiple variables can be named locally with @code{let}:
+Multiple variables can be named locally with @code{let} (@pxref{Local
+Bindings,,, guile, GNU Guile Reference Manual}):
 
 @lisp
-> (define x 10)
-> (let ((x 2)
-        (y 3))
-    (list x y))
-(2 3)
-> x
-10
-> y
-ERROR: In procedure module-lookup: Unbound variable: y
+(define x 10)
+(let ((x 2)
+      (y 3))
+  (list x y))
+@result{} (2 3)
+
+x
+@result{} 10
+
+y
+@error{} In procedure module-lookup: Unbound variable: y
 @end lisp
 
 Use @code{let*} to allow later variable declarations to refer to earlier
 definitions.
 
 @lisp
-(let* ((x 2)
-         (y (* x 3)))
-    (list x y))
-(2 6)
+(let* ((x 2)
+       (y (* x 3)))
+  (list x y))
+@result{} (2 6)
 @end lisp
 
 @item
@@ -242,7 +258,8 @@ the build stage.  Note that it is merely a convention, like @code{_} in C.
 Scheme treats @code{%} exactly the same as any other letter.
 
 @item
-Modules are created with @code{define-module}.  For instance
+Modules are created with @code{define-module} (@pxref{Creating Guile
+Modules,,, guile, GNU Guile Reference Manual}).  For instance
 
 @lisp
 (define-module (guix build-system ruby)
@@ -314,7 +331,7 @@ package definitions.
 @item
 Inheritance makes it easy to customize a package by inheriting from it and
 modifying only what is needed.
+
 @item
 Batch processing: the whole package collection can be parsed, filtered and
 processed.  Building a headless server with all graphical interfaces stripped
@@ -331,14 +348,14 @@ It does not assume much knowledge of the Guix system nor of the Lisp language.
 The reader is only expected to be familiar with the command line and to have some
 basic programming knowledge.
 
-@node A "Hello World" package
-@subsection A "Hello World" package
+@node A ``Hello World'' package
+@subsection A ``Hello World'' package
 
-The “Defining Packages” section of the manual introduces the basics of Guix
+The ``Defining Packages'' section of the manual introduces the basics of Guix
 packaging (@pxref{Defining Packages,,, guix, GNU Guix Reference Manual}).  In
 the following section, we will partly go over those basics again.
 
-``GNU hello'' is a dummy project that serves as an idiomatic example for
+GNU@tie{}Hello is a dummy project that serves as an idiomatic example for
 packaging.  It uses the GNU build system (@code{./configure && make && make
 install}).  Guix already provides a package definition which is a perfect
 example to start with.  You can look up its declaration with @code{guix edit
@@ -416,10 +433,10 @@ available licenses.
 @end table
 
 Time to build our first package!  Nothing fancy here for now: we will stick to a
-dummy "my-hello", a copy of the above declaration.
+dummy @code{my-hello}, a copy of the above declaration.
 
-As with the ritualistic "Hello World" taught with most programming languages,
-this will possibly be the most "manual" approach.  We will work out an ideal
+As with the ritualistic ``Hello World'' taught with most programming languages,
+this will possibly be the most ``manual'' approach.  We will work out an ideal
 setup later; for now we will go the simplest route.
 
 Save the following to a file @file{my-hello.scm}.
@@ -554,22 +571,22 @@ earlier example.
 
 The @code{use-modules} expression tells which of the modules we need in the file.
 Modules are a collection of values and procedures.  They are commonly called
-"libraries" or "packages" in other programming languages.
+``libraries'' or ``packages'' in other programming languages.
 
 @node @samp{GUIX_PACKAGE_PATH}
 @subsubsection @samp{GUIX_PACKAGE_PATH}
 
-@emph{Note: Starting from Guix 0.16, the more flexible Guix "channels" are the
+@emph{Note: Starting from Guix 0.16, the more flexible Guix @dfn{channels} are the
 preferred way and supersede @samp{GUIX_PACKAGE_PATH}.  See next section.}
 
 It can be tedious to specify the file from the command line instead of simply
 calling @code{guix package --install my-hello} as you would do with the official
 packages.
 
-Guix makes it possible to streamline the process by adding as many "package
-declaration paths" as you want.
+Guix makes it possible to streamline the process by adding as many ``package
+declaration directories'' as you want.
 
-Create a directory, say @samp{~./guix-packages} and add it to the @samp{GUIX_PACKAGE_PATH}
+Create a directory, say @file{~./guix-packages} and add it to the @samp{GUIX_PACKAGE_PATH}
 environment variable:
 
 @example
@@ -670,7 +687,7 @@ In the rest of this article, we use @samp{$GUIX_CHECKOUT} to refer to the locati
 the checkout.
 
 
-Follow the instruction in the manual (@pxref{Contributing,,, guix, GNU Guix
+Follow the instructions in the manual (@pxref{Contributing,,, guix, GNU Guix
 Reference Manual}) to set up the repository environment.
 
 Once ready, you should be able to use the package definitions from the
@@ -679,7 +696,8 @@ repository environment.
 Feel free to edit package definitions found in @samp{$GUIX_CHECKOUT/gnu/packages}.
 
 The @samp{$GUIX_CHECKOUT/pre-inst-env} script lets you use @samp{guix} over the package
-collection of the repository.
+collection of the repository (@pxref{Running Guix Before It Is
+Installed,,, guix, GNU Guix Reference Manual}).
 
 @itemize
 @item
@@ -735,7 +753,7 @@ It's a community effort so the more join in, the better Guix becomes!
 @node Extended example
 @subsection Extended example
 
-The above "Hello World" example is as simple as it goes.  Packages can be more
+The above ``Hello World'' example is as simple as it goes.  Packages can be more
 complex than that and Guix can handle more advanced scenarios.  Let's look at
 another, more sophisticated package (slightly modified from the source):
 
@@ -828,21 +846,39 @@ tags, so if the @code{version} is tagged, then it can be used directly.  Sometim
 the tag is prefixed with a @code{v}, in which case you'd use @code{(commit (string-append
 "v" version))}.
 
-To ensure that the source code from the Git repository is stored in a unique
-directory with a readable name we use @code{(file-name (git-file-name name
+To ensure that the source code from the Git repository is stored in a
+directory with a descriptive name, we use @code{(file-name (git-file-name name
 version))}.
 
-Note that there is also a @code{git-version} procedure that can be used to derive the
-version when packaging programs for a specific commit.
+The @code{git-version} procedure can be used to derive the
+version when packaging programs for a specific commit, following the
+Guix contributor guidelines (@pxref{Version Numbers,,, guix, GNU Guix
+Reference Manual}).
+
+How does one obtain the @code{sha256} hash that's in there, you ask?  By
+invoking @command{guix hash} on a checkout of the desired commit, along
+these lines:
+
+@example
+git clone https://github.com/libgit2/libgit2/
+cd libgit2
+git checkout v0.26.6
+guix hash -rx .
+@end example
+
+@command{guix hash -rx} computes a SHA256 hash over the whole directory,
+excluding the @file{.git} sub-directory (@pxref{Invoking guix hash,,,
+guix, GNU Guix Reference Manual}).
+
+In the future, @command{guix download} will hopefully be able to do
+these steps for you, just like it does for regular downloads.
 
 @subsubsection Snippets
 
 Snippets are quoted (i.e. non-evaluated) Scheme code that are a means of patching
-the source.  They are a Guix-y alternative to the traditional @samp{.patch} files.
+the source.  They are a Guix-y alternative to the traditional @file{.patch} files.
 Because of the quote, the code in only evaluated when passed to the Guix daemon
-for building.
-
-There can be as many snippet as needed.
+for building.  There can be as many snippets as needed.
 
 Snippets might need additional Guile modules which can be imported from the
 @code{modules} field.
@@ -883,7 +919,7 @@ being present at build time.
 
 The distinction between the various inputs is important: if a dependency can be
 handled as an @emph{input} instead of a @emph{propagated input}, it should be done so, or
-else it "pollutes" the user profile for no good reason.
+else it ``pollutes'' the user profile for no good reason.
 
 For instance, a user installing a graphical program that depends on a
 command line tool might only be interested in the graphical part, so there is no
@@ -944,9 +980,9 @@ $ make CC=gcc prefix=/gnu/store/...-<out>
 This sets the C compiler to @code{gcc} and the @code{prefix} variable (the installation
 directory in Make parlance) to @code{(assoc-ref %outputs "out")}, which is a build-stage
 global variable pointing to the destination directory in the store (something like
-@samp{/gnu/store/...-my-libgit2-20180408}).
+@file{/gnu/store/...-my-libgit2-20180408}).
 
-Similarly, it's possible to set the "configure" flags.
+Similarly, it's possible to set the configure flags:
 
 @lisp
 #:configure-flags '("-DUSE_SHA1DC=ON")
@@ -983,10 +1019,10 @@ definition in @samp{$GUIX_CHECKOUT/guix/build/gnu-build-system.scm}:
 Or from the REPL:
 
 @lisp
-(add-to-load-path "/path/to/guix/checkout")
-> ,module (guix build gnu-build-system)
-(map first %standard-phases)
-(set-SOURCE-DATE-EPOCH set-paths install-locale unpack bootstrap patch-usr-bin-file patch-source-shebangs configure patch-generated-file-shebangs build check install patch-shebangs strip validate-runpath validate-documentation-location delete-info-dir-file patch-dot-desktop-files install-license-files reset-gzip-timestamps compress-documentation)
+(add-to-load-path "/path/to/guix/checkout")
+,use (guix build gnu-build-system)
+(map first %standard-phases)
+@result{} (set-SOURCE-DATE-EPOCH set-paths install-locale unpack bootstrap patch-usr-bin-file patch-source-shebangs configure patch-generated-file-shebangs build check install patch-shebangs strip validate-runpath validate-documentation-location delete-info-dir-file patch-dot-desktop-files install-license-files reset-gzip-timestamps compress-documentation)
 @end lisp
 
 If you want to know more about what happens during those phases, consult the
@@ -1066,11 +1102,11 @@ argument field.  Indeed, the build code in the package declaration should not be
 evaluated on the client side, but only when passed to the Guix daemon.  This
 mechanism of passing code around two running processes is called @uref{https://arxiv.org/abs/1709.00833, code staging}.
 
-@subsubsection "Utils" functions
+@subsubsection Utility functions
 
 When customizing @code{phases}, we often need to write code that mimics the
-equivalent system invocations (@code{make}, @code{mkdir}, @code{cp}, etc.) commonly used during
-regular "Unix-style" installations.
+equivalent system invocations (@code{make}, @code{mkdir}, @code{cp}, etc.)@: commonly used during
+regular ``Unix-style'' installations.
 
 Some like @code{chmod} are native to Guile.
 @xref{,,, guile, Guile reference manual} for a complete list.
@@ -1103,7 +1139,7 @@ Run an executable.  This should be used instead of @code{system*}.
 Run the body in a different working directory,
 then restore the previous working directory.
 @item substitute*
-A "sed-like" function.
+A ``@command{sed}-like'' function.
 @end table
 
 @subsubsection Module prefix
@@ -1130,14 +1166,10 @@ For the other build systems, such as ASDF, Emacs, Perl, Ruby and many more, the
 process is very similar to the GNU build system except for a few specialized
 arguments.
 
-Learn more about build systems in
-@itemize
-@item
-@uref{https://www.gnu.org/software/guix/manual/en/html_node/Build-Systems.html#Build-Systems, the manual, section 4.2 Build systems},
-@item
-the source code in the @samp{$GUIX_CHECKOUT/guix/build} and
+@xref{Build Systems,,, guix, GNU Guix Reference Manual}, for more
+information on build systems, or check the source code in the
+@samp{$GUIX_CHECKOUT/guix/build} and
 @samp{$GUIX_CHECKOUT/guix/build-system} directories.
-@end itemize
 
 @node Programmable and automated package definition
 @subsection Programmable and automated package definition
@@ -1258,7 +1290,7 @@ version or compilation options.
 @subsection Getting help
 
 Sadly, some applications can be tough to package.  Sometimes they need a patch to
-work with the non-standard filesystem hierarchy enforced by the store.
+work with the non-standard file system hierarchy enforced by the store.
 Sometimes the tests won't run properly.  (They can be skipped but this is not
 recommended.)  Other times the resulting package won't be reproducible.
 
@@ -1299,7 +1331,7 @@ The @uref{https://www.gnu.org/software/guix/manual/en/html_node/Defining-Package
 @uref{https://gitlab.com/pjotrp/guix-notes/blob/master/HACKING.org, Pjotr’s hacking guide to GNU Guix}
 
 @item
-@uref{https://www.gnu.org/software/guix/guix-ghm-andreas-20130823.pdf, "GNU Guix: Package without a scheme!"}, by Andreas Enge
+@uref{https://www.gnu.org/software/guix/guix-ghm-andreas-20130823.pdf, ``GNU Guix: Package without a scheme!''}, by Andreas Enge
 @end itemize
 
 @c *********************************************************************
@@ -1314,7 +1346,12 @@ chapter is to demonstrate some advanced configuration concepts.
 reference.
 
 @menu
-* Customizing the Kernel::     Creating and using a custom Linux kernel on Guix System.
+* Customizing the Kernel::       Creating and using a custom Linux kernel on Guix System.
+* Connecting to Wireguard VPN::  Connecting to a Wireguard VPN.
+* Customizing a Window Manager:: Handle customization of a Window manager on Guix System.
+* Running Guix on a Linode Server:: Running Guix on a Linode Server
+* Setting up a bind mount:: Setting up a bind mount in the file-systems definition.
+* Getting substitutes from Tor:: Configuring Guix daemon to get substitutes through Tor.
 @end menu
 
 @node Customizing the Kernel
@@ -1467,7 +1504,7 @@ custom kernel:
 @lisp
 (define %macbook41-full-config
   (append %macbook41-config-options
-          %filesystems
+          %file-systems
           %efi-support
           %emulation
           (@@@@ (gnu packages linux) %default-extra-linux-options)))
@@ -1483,8 +1520,8 @@ custom kernel:
                       #:extra-options %macbook41-config-options))
 @end lisp
 
-In the above example @code{%filesystems} is a collection of flags enabling
-different filesystem support, @code{%efi-support} enables EFI support and
+In the above example @code{%file-systems} is a collection of flags enabling
+different file system support, @code{%efi-support} enables EFI support and
 @code{%emulation} enables a x86_64-linux machine to act in 32-bit mode also.
 @code{%default-extra-linux-options} are the ones quoted above, which had to be
 added in since they were replaced in the @code{extra-options} keyword.
@@ -1533,7 +1570,7 @@ CONFIG_VIRTIO=m
 @end example
 
 After copying all the configuration options, run @code{make localmodconfig}
-again to make sure that you don't have any output starting with "module".
+again to make sure that you don't have any output starting with ``module''.
 After all of these machine specific modules there are a couple more left that
 are also needed.  @code{CONFIG_MODULES} is necessary so that you can build and
 load modules separately and not have everything built into the kernel.
@@ -1548,7 +1585,7 @@ The second way to setup the kernel configuration makes more use of Guix's
 features and allows you to share configuration segments between different
 kernels.  For example, all machines using EFI to boot have a number of EFI
 configuration flags that they need.  It is likely that all the kernels will
-share a list of filesystems to support.  By using variables it is easier to
+share a list of file systems to support.  By using variables it is easier to
 see at a glance what features are enabled and to make sure you don't have
 features in one kernel but missing in another.
 
@@ -1557,6 +1594,525 @@ likely that you'll need to modify the initrd on a machine using a custom
 kernel, since certain modules which are expected to be built may not be
 available for inclusion into the initrd.
 
+@node Connecting to Wireguard VPN
+@section Connecting to Wireguard VPN
+
+To connect to a Wireguard VPN server you need the kernel module to be
+loaded in memory and a package providing networking tools that support
+it (e.g.  @code{wireguard-tools} or @code{network-manager}).
+
+Here is a configuration example for Linux-Libre < 5.6, where the module
+is out of tree and need to be loaded manually---following revisions of
+the kernel have it built-in and so don't need such configuration:
+
+@lisp
+(use-modules (gnu))
+(use-service-modules desktop)
+(use-package-modules vpn)
+
+(operating-system
+  ;; …
+  (services (cons (simple-service 'wireguard-module
+                                  kernel-module-loader-service-type
+                                  '("wireguard"))
+                  %desktop-services))
+  (packages (cons wireguard-tools %base-packages))
+  (kernel-loadable-modules (list wireguard-linux-compat)))
+@end lisp
+
+After reconfiguring and restarting your system you can either use
+Wireguard tools or NetworkManager to connect to a VPN server.
+
+@subsection Using Wireguard tools
+
+To test your Wireguard setup it is convenient to use @command{wg-quick}.
+Just give it a configuration file @command{wg-quick up ./wg0.conf}; or
+put that file in @file{/etc/wireguard} and run @command{wg-quick up wg0}
+instead.
+
+@quotation Note
+Be warned that the author described this command as a: “[…] very quick
+and dirty bash script […]”.
+@end quotation
+
+@subsection Using NetworkManager
+
+Thanks to NetworkManager support for Wireguard we can connect to our VPN
+using @command{nmcli} command.  Up to this point this guide assumes that
+you're using Network Manager service provided by
+@code{%desktop-services}.  Ortherwise you need to adjust your services
+list to load @code{network-manager-service-type} and reconfigure your
+Guix system.
+
+To import your VPN configuration execute nmcli import command:
+
+@example shell
+# nmcli connection import type wireguard file wg0.conf
+Connection 'wg0' (edbee261-aa5a-42db-b032-6c7757c60fde) successfully added
+@end example
+
+This will create a configuration file in
+@file{/etc/NetworkManager/wg0.nmconnection}.  Next connect to the
+Wireguard server:
+
+@example shell
+$ nmcli connection up wg0
+Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/6)
+@end example
+
+By default NetworkManager will connect automatically on system boot.  To
+change that behaviour you need to edit your config:
+
+@example shell
+# nmcli connection modify wg0 connection.autoconnect no
+@end example
+
+For more specific information about NetworkManager and wireguard
+@uref{https://blogs.gnome.org/thaller/2019/03/15/wireguard-in-networkmanager/,see
+this post by thaller}.
+
+@node Customizing a Window Manager
+@section Customizing a Window Manager
+@cindex wm
+
+@node StumpWM
+@subsection StumpWM
+@cindex stumpwm
+
+You could install StumpWM with a Guix system by adding
+@code{stumpwm} and optionally @code{`(,stumpwm "lib")}
+packages to a system configuration file, e.g.@: @file{/etc/config.scm}.
+
+An example configuration can look like this:
+
+@lisp
+(use-modules (gnu))
+(use-package-modules wm)
+
+(operating-system
+  ;; …
+  (packages (append (list sbcl stumpwm `(,stumpwm "lib"))
+                    %base-packages)))
+@end lisp
+
+@cindex stumpwm fonts
+By default StumpWM uses X11 fonts, which could be small or pixelated on
+your system.  You could fix this by installing StumpWM contrib Lisp
+module @code{sbcl-ttf-fonts}, adding it to Guix system packages:
+
+@lisp
+(use-modules (gnu))
+(use-package-modules fonts wm)
+
+(operating-system
+  ;; …
+  (packages (append (list sbcl stumpwm `(,stumpwm "lib"))
+                    sbcl-ttf-fonts font-dejavu %base-packages)))
+@end lisp
+
+Then you need to add the following code to a StumpWM configuration file
+@file{~/.stumpwm.d/init.lisp}:
+
+@lisp
+(require :ttf-fonts)
+(setf xft:*font-dirs* '("/run/current-system/profile/share/fonts/"))
+(setf clx-truetype:+font-cache-filename+ (concat (getenv "HOME") "/.fonts/font-cache.sexp"))
+(xft:cache-fonts)
+(set-font (make-instance 'xft:font :family "DejaVu Sans Mono" :subfamily "Book" :size 11))
+@end lisp
+
+@node Session lock
+@subsection Session lock
+@cindex sessionlock
+
+Depending on your environment, locking the screen of your session might come built in
+or it might be something you have to set up yourself. If you use a desktop environment
+like GNOME or KDE, it's usually built in. If you use a plain window manager like
+StumpWM or EXWM, you might have to set it up yourself.
+
+@node Xorg
+@subsubsection Xorg
+
+If you use Xorg, you can use the utility
+@uref{https://www.mankier.com/1/xss-lock, xss-lock} to lock the screen of your session.
+xss-lock is triggered by DPMS which since Xorg 1.8 is auto-detected and enabled if
+ACPI is also enabled at kernel runtime.
+
+To use xss-lock, you can simple execute it and put it into the background before
+you start your window manager from e.g. your @file{~/.xsession}:
+
+@example
+xss-lock -- slock &
+exec stumpwm
+@end example
+
+In this example, xss-lock uses @code{slock} to do the actual locking of the screen when
+it determines it's appropriate, like when you suspend your device.
+
+For slock to be allowed to be a screen locker for the graphical session, it needs to
+be made setuid-root so it can authenticate users, and it needs a PAM service. This
+can be achieved by adding the following service to your @file{config.scm}:
+
+@lisp
+(screen-locker-service slock)
+@end lisp
+
+If you manually lock your screen, e.g. by directly calling slock when you want to lock
+your screen but not suspend it, it's a good idea to notify xss-lock about this so no
+confusion occurs. This can be done by executing @code{xset s activate} immediately
+before you execute slock.
+
+@node Running Guix on a Linode Server
+@section Running Guix on a Linode Server
+@cindex linode, Linode
+
+To run Guix on a server hosted by @uref{https://www.linode.com, Linode},
+start with a recommended Debian server.  We recommend using the default
+distro as a way to bootstrap Guix. Create your SSH keys.
+
+@example
+ssh-keygen
+@end example
+
+Be sure to add your SSH key for easy login to the remote server.
+This is trivially done via Linode's graphical interface for adding
+SSH keys.  Go to your profile and click add SSH Key.
+Copy into it the output of:
+
+@example
+cat ~/.ssh/<username>_rsa.pub
+@end example
+
+Power the Linode down. In the Linode's Disks/Configurations tab, resize
+the Debian disk to be smaller. 30 GB is recommended.
+
+In the Linode settings, "Add a disk", with the following:
+@itemize @bullet
+@item
+Label: "Guix"
+
+@item
+Filesystem: ext4
+
+@item
+Set it to the remaining size
+@end itemize
+
+On the "configuration" field that comes with the default image, press
+"..." and select "Edit", then on that menu add to @file{/dev/sdc} the "Guix"
+label.
+
+Now "Add a Configuration", with the following:
+@itemize @bullet
+@item
+Label: Guix
+
+@item
+Kernel:GRUB 2 (it's at the bottom!  This step is @b{IMPORTANT!})
+
+@item
+Block device assignment:
+
+@item
+@file{/dev/sda}: Guix
+
+@item
+@file{/dev/sdb}: swap
+
+@item
+Root device: @file{/dev/sda}
+
+@item
+Turn off all the filesystem/boot helpers
+@end itemize
+
+Now power it back up, picking the Debian configuration.  Once it's
+booted up, ssh in your server via @code{ssh
+root@@@var{<your-server-IP-here>}}. (You can find your server IP address in
+your Linode Summary section.) Now you can run the "install guix from
+@pxref{Binary Installation,,, guix, GNU Guix}" steps:
+
+@example
+sudo apt-get install gpg
+wget https://sv.gnu.org/people/viewgpg.php?user_id=15145 -qO - | gpg --import -
+wget https://git.savannah.gnu.org/cgit/guix.git/plain/etc/guix-install.sh
+chmod +x guix-install.sh
+./guix-install.sh
+guix pull
+@end example
+
+Now it's time to write out a config for the server.  The key information
+is below. Save the resulting file as @file{guix-config.scm}.
+
+@lisp
+(use-modules (gnu)
+             (guix modules))
+(use-service-modules networking
+                     ssh)
+(use-package-modules admin
+                     certs
+                     package-management
+                     ssh
+                     tls)
+
+(operating-system
+  (host-name "my-server")
+  (timezone "America/New_York")
+  (locale "en_US.UTF-8")
+  ;; This goofy code will generate the grub.cfg
+  ;; without installing the grub bootloader on disk.
+  (bootloader (bootloader-configuration
+               (bootloader
+                (bootloader
+                 (inherit grub-bootloader)
+                 (installer #~(const #t))))))
+  (file-systems (cons (file-system
+                        (device "/dev/sda")
+                        (mount-point "/")
+                        (type "ext4"))
+                      %base-file-systems))
+
+
+  (swap-devices (list "/dev/sdb"))
+
+
+  (initrd-modules (cons "virtio_scsi"    ; Needed to find the disk
+                        %base-initrd-modules))
+
+  (users (cons (user-account
+                (name "janedoe")
+                (group "users")
+                ;; Adding the account to the "wheel" group
+                ;; makes it a sudoer.
+                (supplementary-groups '("wheel"))
+                (home-directory "/home/janedoe"))
+               %base-user-accounts))
+
+  (packages (cons* nss-certs            ;for HTTPS access
+                   openssh-sans-x
+                   %base-packages))
+
+  (services (cons*
+             (service dhcp-client-service-type)
+             (service openssh-service-type
+                      (openssh-configuration
+                       (openssh openssh-sans-x)
+                       (password-authentication? #f)
+                       (authorized-keys
+                        `(("janedoe" ,(local-file "janedoe_rsa.pub"))
+                          ("root" ,(local-file "janedoe_rsa.pub"))))))
+             %base-services)))
+@end lisp
+
+Replace the following fields in the above configuration:
+@lisp
+(host-name "my-server")       ; replace with your server name
+; if you chose a linode server outside the U.S., then
+; use tzselect to find a correct timezone string
+(timezone "America/New_York") ; if needed replace timezone
+(name "janedoe")              ; replace with your username
+("janedoe" ,(local-file "janedoe_rsa.pub")) ; replace with your ssh key
+("root" ,(local-file "janedoe_rsa.pub")) ; replace with your ssh key
+@end lisp
+
+The last line in the above example lets you log into the server as root
+and set the initial root password.  After you have done this, you may
+delete that line from your configuration and reconfigure to prevent root
+login.
+
+Save your ssh public key (eg: @file{~/.ssh/id_rsa.pub}) as
+@file{@var{<your-username-here>}_rsa.pub} and your
+@file{guix-config.scm} in the same directory.  In a new terminal run
+these commands.
+
+@example
+sftp root@@<remote server ip address>
+put /home/<username>/ssh/id_rsa.pub .
+put /path/to/linode/guix-config.scm .
+@end example
+
+In your first terminal, mount the guix drive:
+
+@example
+mkdir /mnt/guix
+mount /dev/sdc /mnt/guix
+@end example
+
+Due to the way we set things up above, we do not install GRUB
+completely.  Instead we install only our grub configuration file.  So we
+need to copy over some of the other GRUB stuff that is already there:
+
+@example
+mkdir -p /mnt/guix/boot/grub
+cp -r /boot/grub/* /mnt/guix/boot/grub/
+@end example
+
+Now initialize the Guix installation:
+
+@example
+guix system init guix-config.scm /mnt/guix
+@end example
+
+Ok, power it down!
+Now from the Linode console, select boot and select "Guix".
+
+Once it boots, you should be able to log in via SSH!  (The server config
+will have changed though.)  You may encounter an error like:
+
+@example
+$ ssh root@@<server ip address>
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
+Someone could be eavesdropping on you right now (man-in-the-middle attack)!
+It is also possible that a host key has just been changed.
+The fingerprint for the ECDSA key sent by the remote host is
+SHA256:0B+wp33w57AnKQuHCvQP0+ZdKaqYrI/kyU7CfVbS7R4.
+Please contact your system administrator.
+Add correct host key in /home/joshua/.ssh/known_hosts to get rid of this message.
+Offending ECDSA key in /home/joshua/.ssh/known_hosts:3
+ECDSA host key for 198.58.98.76 has changed and you have requested strict checking.
+Host key verification failed.
+@end example
+
+Either delete @file{~/.ssh/known_hosts} file, or delete the offending line
+starting with your server IP address.
+
+Be sure to set your password and root's password.
+
+@example
+ssh root@@<remote ip address>
+passwd  ; for the root password
+passwd <username> ; for the user password
+@end example
+
+You may not be able to run the above commands at this point.  If you
+have issues remotely logging into your linode box via SSH, then you may
+still need to set your root and user password initially by clicking on
+the ``Launch Console'' option in your linode.  Choose the ``Glish''
+instead of ``Weblish''.  Now you should be able to ssh into the machine.
+
+Horray!  At this point you can shut down the server, delete the
+Debian disk, and resize the Guix to the rest of the size.
+Congratulations!
+
+By the way, if you save it as a disk image right at this point, you'll
+have an easy time spinning up new Guix images!  You may need to
+down-size the Guix image to 6144MB, to save it as an image.  Then you
+can resize it again to the max size.
+
+@node Setting up a bind mount
+@section Setting up a bind mount
+
+To bind mount a file system, one must first set up some definitions
+before the @code{operating-system} section of the system definition.  In
+this example we will bind mount a folder from a spinning disk drive to
+@file{/tmp}, to save wear and tear on the primary SSD, without
+dedicating an entire partition to be mounted as @file{/tmp}.
+
+First, the source drive that hosts the folder we wish to bind mount
+should be defined, so that the bind mount can depend on it.
+
+@lisp
+(define source-drive ;; "source-drive" can be named anything you want.
+   (file-system
+    (device (uuid "UUID goes here"))
+    (mount-point "/path-to-spinning-disk-goes-here")
+    (type "ext4"))) ;; Make sure to set this to the appropriate type for your drive.
+@end lisp
+
+The source folder must also be defined, so that guix will know it's not
+a regular block device, but a folder.
+@lisp
+(define (%source-directory) "/path-to-spinning-disk-goes-here/tmp") ;; "source-directory" can be named any valid variable name.
+@end lisp
+
+Finally, inside the @code{file-systems} definition, we must add the
+mount itself.
+
+@lisp
+(file-systems (cons*
+
+                ...<other drives omitted for clarity>...
+
+                source-drive ;; Must match the name you gave the source drive in the earlier definition.
+
+                (file-system
+                 (device (%source-directory)) ;; Make sure "source-directory" matches your earlier definition.
+                 (mount-point "/tmp")
+                 (type "none") ;; We are mounting a folder, not a partition, so this type needs to be "none"
+                 (flags '(bind-mount))
+                 (dependencies (list source-drive)) ;; Ensure "source-drive" matches what you've named the variable for the drive.
+                 )
+
+                 ...<other drives omitted for clarity>...
+
+                ))
+@end lisp
+
+@node Getting substitutes from Tor
+@section Getting substitutes from Tor
+
+Guix daemon can use a HTTP proxy to get substitutes, here we are
+configuring it to get them via Tor.
+
+@quotation Warning
+@emph{Not all} Guix daemon's traffic will go through Tor!  Only
+HTTP/HTTPS will get proxied; FTP, Git protocol, SSH, etc connections
+will still go through the clearnet.  Again, this configuration isn't
+foolproof some of your traffic won't get routed by Tor at all.  Use it
+at your own risk.
+
+Also note that the procedure described here applies only to package
+substitution. When you update your guix distribution with
+@command{guix pull}, you still need to use @command{torsocks} if
+you want to route the connection to guix's git repository servers
+through Tor.
+@end quotation
+
+Guix's substitute server is available as a Onion service, if you want
+to use it to get your substitutes through Tor configure your system as
+follow:
+
+@lisp
+(use-modules (gnu))
+(use-service-module base networking)
+
+(operating-system
+  …
+  (services
+    (cons
+      (service tor-service-type
+              (tor-configuration
+                (config-file (plain-file "tor-config"
+                                         "HTTPTunnelPort 127.0.0.1:9250"))))
+      (modify-services %base-services
+        (guix-service-type
+          config => (guix-configuration
+                      (inherit config)
+                      ;; ci.guix.gnu.org's Onion service
+                      (substitute-urls "https://bp7o7ckwlewr4slm.onion")
+                      (http-proxy "http://localhost:9250")))))))
+@end lisp
+
+This will keep a tor process running that provides a HTTP CONNECT tunnel
+which will be used by @command{guix-daemon}.  The daemon can use other
+protocols than HTTP(S) to get remote resources, request using those
+protocols won't go through Tor since we are only setting a HTTP tunnel
+here.  Note that @code{substitutes-urls} is using HTTPS and not HTTP or
+it won't work, that's a limitation of Tor's tunnel; you may want to use
+@command{privoxy} instead to avoid such limitations.
+
+If you don't want to always get substitutes through Tor but using it just
+some of the times, then skip the @code{guix-configuration}.  When you
+want to get a substitute from the Tor tunnel run:
+
+@example
+sudo herd set-http-proxy guix-daemon http://localhost:9250
+guix build --substitute-urls=https://bp7o7ckwlewr4slm.onion …
+@end example
+
 @c *********************************************************************
 @node Advanced package management
 @chapter Advanced package management
@@ -1683,8 +2239,8 @@ where we will store our profiles in the rest of this article.
 
 Placing all your profiles in a single directory, with each profile getting its
 own sub-directory, is somewhat cleaner.  This way, each sub-directory will
-contain all the symlinks for precisely one profile.  Besides, "looping over
-profiles" becomes obvious from any programming language (e.g. a shell script) by
+contain all the symlinks for precisely one profile.  Besides, ``looping over
+profiles'' becomes obvious from any programming language (e.g.@: a shell script) by
 simply looping over the sub-directories of @samp{$GUIX_EXTRA_PROFILES}.
 
 Note that it's also possible to loop over the output of
@@ -1693,9 +2249,9 @@ Note that it's also possible to loop over the output of
 guix package --list-profiles
 @end example
 
-although you'll probably have to filter out @samp{~/.config/guix/current}.
+although you'll probably have to filter out @file{~/.config/guix/current}.
 
-To enable all profiles on login, add this to your @samp{~/.bash_profile} (or similar):
+To enable all profiles on login, add this to your @file{~/.bash_profile} (or similar):
 
 @example
 for i in $GUIX_EXTRA_PROFILES/*; do
@@ -1709,8 +2265,8 @@ done
 @end example
 
 Note to Guix System users: the above reflects how your default profile
-@samp{~/.guix-profile} is activated from @samp{/etc/profile}, that latter being loaded by
-@samp{~/.bashrc} by default.
+@file{~/.guix-profile} is activated from @file{/etc/profile}, that latter being loaded by
+@file{~/.bashrc} by default.
 
 You can obviously choose to only enable a subset of them:
 
@@ -1753,8 +2309,8 @@ guix package -m /path/to/guix-my-project-manifest.scm -p "$GUIX_EXTRA_PROFILES"/
 
 To upgrade all profiles, it's easy enough to loop over them.  For instance,
 assuming your manifest specifications are stored in
-@samp{~/.guix-manifests/guix-$profile-manifest.scm}, with @samp{$profile} being the name
-of the profile (e.g. "project1"), you could do the following in Bourne shell:
+@file{~/.guix-manifests/guix-$profile-manifest.scm}, with @samp{$profile} being the name
+of the profile (e.g.@: "project1"), you could do the following in Bourne shell:
 
 @example
 for profile in "$GUIX_EXTRA_PROFILES"/*; do
@@ -1813,12 +2369,12 @@ The same is true for @samp{INFOPATH} (you can install @samp{info-reader}),
 @node Default profile
 @subsection Default profile
 
-What about the default profile that Guix keeps in @samp{~/.guix-profile}?
+What about the default profile that Guix keeps in @file{~/.guix-profile}?
 
 You can assign it the role you want.  Typically you would install the manifest
 of the packages you want to use all the time.
 
-Alternatively, you could keep it "manifest-less" for throw-away packages
+Alternatively, you could keep it ``manifest-less'' for throw-away packages
 that you would just use for a couple of days.
 This way makes it convenient to run
 
@@ -1849,7 +2405,7 @@ Manifests come with multiple benefits.  In particular, they ease maintenance:
 @itemize
 @item
 When a profile is set up from a manifest, the manifest itself is
-self-sufficient to keep a "package listing" around and reinstall the profile
+self-sufficient to keep a ``package listing'' around and reinstall the profile
 later or on a different system.  For ad-hoc profiles, we would need to
 generate a manifest specification manually and maintain the package versions
 for the packages that don't use the default version.
@@ -1886,7 +2442,7 @@ They can be manipulated in Scheme and passed to the various Guix @uref{https://e
 
 It's important to understand that while manifests can be used to declare
 profiles, they are not strictly equivalent: profiles have the side effect that
-they "pin" packages in the store, which prevents them from being
+they ``pin'' packages in the store, which prevents them from being
 garbage-collected (@pxref{Invoking guix gc,,, guix, GNU Guix Reference Manual})
 and ensures that they will still be available at any point in
 the future.
@@ -1955,6 +2511,130 @@ mkdir -p "$GUIX_EXTRA_PROFILES/my-project"
 It's safe to delete the Guix channel profile you've just installed with the
 channel specification, the project profile does not depend on it.
 
+@c *********************************************************************
+@node Environment management
+@chapter Environment management
+
+Guix provides multiple tools to manage environment.  This chapter
+demonstrate such utilities.
+
+@menu
+* Guix environment via direnv:: Setup Guix environment with direnv
+@end menu
+
+@node Guix environment via direnv
+@section Guix environment via direnv
+
+Guix provides a @samp{direnv} package, which could extend shell after
+directory change.  This tool could be used to prepare a pure Guix
+environment.
+
+The following example provides a shell function for @file{~/.direnvrc}
+file, which could be used from Guix Git repository in
+@file{~/src/guix/.envrc} file to setup a build environment similar to
+described in @pxref{Building from Git,,, guix, GNU Guix Reference
+Manual}.
+
+Create a @file{~/.direnvrc} with a Bash code:
+
+@example
+# Thanks <https://github.com/direnv/direnv/issues/73#issuecomment-152284914>
+export_function()
+@{
+  local name=$1
+  local alias_dir=$PWD/.direnv/aliases
+  mkdir -p "$alias_dir"
+  PATH_add "$alias_dir"
+  local target="$alias_dir/$name"
+  if declare -f "$name" >/dev/null; then
+    echo "#!$SHELL" > "$target"
+    declare -f "$name" >> "$target" 2>/dev/null
+    # Notice that we add shell variables to the function trigger.
+    echo "$name \$*" >> "$target"
+    chmod +x "$target"
+  fi
+@}
+
+use_guix()
+@{
+    # Set GitHub token.
+    export GUIX_GITHUB_TOKEN="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+
+    # Unset 'GUIX_PACKAGE_PATH'.
+    export GUIX_PACKAGE_PATH=""
+
+    # Recreate a garbage collector root.
+    gcroots="$HOME/.config/guix/gcroots"
+    mkdir -p "$gcroots"
+    gcroot="$gcroots/guix"
+    if [ -L "$gcroot" ]
+    then
+        rm -v "$gcroot"
+    fi
+
+    # Miscellaneous packages.
+    PACKAGES_MAINTENANCE=(
+        direnv
+        git
+        git:send-email
+        git-cal
+        gnupg
+        guile-colorized
+        guile-readline
+        less
+        ncurses
+        openssh
+        xdot
+    )
+
+    # Environment packages.
+    PACKAGES=(help2man guile-sqlite3 guile-gcrypt)
+
+    # Thanks <https://lists.gnu.org/archive/html/guix-devel/2016-09/msg00859.html>
+    eval "$(guix environment --search-paths --root="$gcroot" --pure guix --ad-hoc $@{PACKAGES[@@]@} $@{PACKAGES_MAINTENANCE[@@]@} "$@@")"
+
+    # Predefine configure flags.
+    configure()
+    @{
+        ./configure --localstatedir=/var --prefix=
+    @}
+    export_function configure
+
+    # Run make and optionally build something.
+    build()
+    @{
+        make -j 2
+        if [ $# -gt 0 ]
+        then
+            ./pre-inst-env guix build "$@@"
+        fi
+    @}
+    export_function build
+
+    # Predefine push Git command.
+    push()
+    @{
+        git push --set-upstream origin
+    @}
+    export_function push
+
+    clear                        # Clean up the screen.
+    git-cal --author='Your Name' # Show contributions calendar.
+
+    # Show commands help.
+    echo "
+build          build a package or just a project if no argument provided
+configure      run ./configure with predefined parameters
+push           push to upstream Git repository
+"
+@}
+@end example
+
+Every project containing @file{.envrc} with a string @code{use guix}
+will have predefined environment variables and procedures.
+
+Run @command{direnv allow} to setup the environment for the first time.
+
 @c *********************************************************************
 @node Acknowledgments
 @chapter Acknowledgments