Title: Guix: fetch packages from other Guix in the LAN
Author: Solène
Date: 07 June 2021
Tags: guix
Description: 

# Introduction

In this how-to I will explain how to configure two Guix system to share
packages from one to another.  The idea is that most of the time
packages are downloaded from ci.guix.gnu.org but sometimes you can
compile local packages too, in both case you will certainly prefer
computers from your network to get the same packages from a computer
that already had them to save some bandwidth.  This is quite easy to
achieve in Guix.

We need at least two Guix systems, I'll name the one with the package
"server" and the system that will install packages the "client".

# Prepare the server

On the server, edit your /etc/config.scm file and add this service:

```Code: scheme language
(service guix-publish-service-type
         (guix-publish-configuration
             (host "0.0.0.0")
             (port 8080)
             (advertise? #t))))
```
Guix Manual: guix-publish service
Run "guix archive --generate-key" as root to create a public key and
then reconfigure the system.  Your system is now publishing packages on
port 8080 and advertising it with mDNS (involving avahi).

Your port 8080 should be reachable now with a link to a public key.

# Prepare the client

On the client, edit your /etc/config.scm file and modify the
"%desktop-services" or "%base-services" if any.

```Code: scheme language
(guix-service-type
  config =>
    (guix-configuration
      (inherit config)
      (discover? #t)
      (authorized-keys
        (append (list (local-file "/etc/key.pub"))
                %default-authorized-guix-keys)))))))
```
Guix Manual: Getting substitutes from other servers
Download the public key from the server (visiting its ip on port 8080
you will get a link) and store it in "/etc/key.pub", reconfigure your
system.

Now, when you install a package, you should see from where the
substitution (name for packages) are downloaded from.

# Declaring a repository (not dynamic)

In the previous example, we are using advertising on the server and
discovery on the client, this may not be desired and won't work from a
different network.

You can manually register a remote substitute server instead of using
discovery by using "substitute-urls" like this:

```
(guix-service-type
  config =>
    (guix-configuration
      (inherit config)
      (discover? #t)
      (substitute-urls
        (append (list "http://192.168.1.66:8080")
                %default-substitute-urls))
      (authorized-keys
        (append (list (local-file "/etc/key.pub"))
                %default-authorized-guix-keys)))))))
```

# Conclusion

I'm doing my best to avoid wasting bandwidth and resources in general,
I really like this feature because this doesn't require much
configuration or infrastructure and work in a sort of peer-to-peer.

Other projects like Debian prefer using a proxy that keep in cache the
packages downloaded and act as a repository provider itself to proxyfi
the service.

In case of doubts of the validity of the substitutions provided by an
url, the challenge feature can be used to check if reproducible builds
done locally match the packages provided by a source.
Guix Manual: guix challenge documentation
Guix Manual: guix weather, a command to get information from a repository