Skip to content

Publish custom packages

We've previously learned how to share environments. In short: this is done by pushing your environment (with flox push) to your floxmeta repository.

We've also learned how to build a custom package and now it is time to share it. We can share a package by publishing it to a flox channel to which our friends and colleagues can subscribe.

Channels solve the unfortunate requirement of Nix to access and evaluate Nix source code in order to install a package. Like your floxmeta repository, a flox channel is simply a repository you push to. By convention, we call this repository floxpkgs. Whether channels are public or private depends on whether the repository is public or private.

Let's look at an example of how we can publish a package.

If you haven't already, please install flox before continuing.

flox publish command is experimental

While the flox publish command is working, we know that there is a lot we need to do to make it more appealing to use.

We wrote this tutorial with the intention to showcase the concept behind the command.

1. Example package

To be able to publish a package we need a repository with a flox package. For this example we will use the work we did in the previous tutorial (Custom package).

Let's clone the floxified branch from our hello-python example where the build recipe for our package already exists.

$ git clone https://github.com/flox-examples/hello-python
$ cd hello-python

$ flox build # (1)!
warning: not writing modified lock file of flake 'git+file:///home/USER/dev/hello-python'
...
• Added input 'flox-floxpkgs/tracelinks/flox-floxpkgs':
    follows 'flox-floxpkgs'

$ ./result/bin/hello
Hello world!
  1. Let's build a package to make sure our example package is ready to be published.

2. flox publish - publish package to a channel

Once the package builds successfully, it can be published to a flox channel.

$ flox publish \ # (1)! \
    hello-python \ # (2)! \
    --cache-url s3://flox-examples \ # (3)! \
    --public-cache-url https://examples-cache.flox.dev # (4)! \
    --signing-key /path/to/binary_cache_secret_key \ # (5)! \
    --stability unstable # (6)!
  1. If the flox publish command is run without any command line options, flox will infer or prompt for (if possible) the package to publish and expect all other required arguments to be provided via the user's config (see flox-config(1))

    For the purpose of this tutorial we will provide options via command line in order to describe them.

  2. The package we want to publish. Packages can be referred to simply by their name within the repository. If we want to publish packages for other systems or from other (remote) projects we can use more specific references. In this case, we could also use for example the following references:

    • packages.<system>.hello-python
    • .#packages.<system>.hello-python
    • /home/USER/dev/hello-python#packages.<system>.hello-python

    For publish the package must be defined in a remote git repository and be referred to either directly by a git+ssh://<url>[#<package>] URL or another URL that can be resolved to an upstream git resource.

    In this case, the package defined in a local repository is resolved to the current branch's upstream branch at https://github.com/flox-examples/hello-python.

    Packages referred to by a github:<user>/<owner>[#<package>] URL are resolved to ssh://[email protected] by default or https://github.com, if --prefer-https is provided.

  3. The binary cache to upload the build artifacts to. Must be provided by any of the following in decreasing priority:

    • The --cache-url option
    • The FLOX_CACHE_URL environment variable
    • The cache_url config key (set using e.g. flox config --set cache_url s3://flox-examples)
  4. (Optional) The binary cache URL to download the build artifacts from, if it is different from the --cache-url.

    Optionally provided by any of the following in decreasing priority: - The --public-cache-url option - The FLOX_PUBLIC_CACHE_URL environment variable - The public_cache_url config key (set using e.g. flox config --set public_cache_url https://examples-cache.flox.dev)

    If omitted, cache_url is used.

  5. The binary cache private signing key. Every build artifact has to be signed to improve security.

    Signing keys can be generated using

    nix key generate-secret --key-name example-key > key.sec
    

    They should not be shared publically but can be reused at any scope (package, project, user/machine, team,...).

    Must be provided by any of the following in decreasing priority: - The --signing-key option - The FLOX_SIGNING_KEY environment variable - The signing_key config key (set using e.g. flox config --set signing-key /path/to/binary_cache_secret_key)

  6. (Optional) The stability branch of nixpkgs to use.

    Uses the locked referencs found in the repo by default.

flox publish will create a detached catalog/<system> branch in the upstream repository (https://github.com/flox-examples/hello-python).

3. flox channels - list subscribed channels

Before we subscribe to any channel let us first explore our existing channels. After a fresh flox installation these are the flox channels you are automatically subscribed to:

$ flox channels                                                                                                   \
                                                                                                                  \
      CHANNEL     TYPE                URL                                                                       \
  ───────────────┼──────┼──────────────────────────────────                                                       \
    flox          flox  github:flox/floxpkgs/master # (1)! \
    nixpkgs-flox  flox  github:flox/nixpkgs-flox/master # (2)!
  1. The channel where you can find latest releases of flox itself, including pre-releases.

  2. The channel where you can find all the packages from upstream NixOS/nixpkgs.

    nixpkgs-flox is a floxified version of nixpkgs.

4. flox subscribe - subscribe to a channel

To be able to use a package from a channel, we need to subscribe to that channel.

$ flox subscribe hello-example git+https://github.com/flox-examples/hello-python
subscribed channel 'example'

When listing our channels we can now see that the hello-example channel is listed.

$ flox channels

      CHANNEL    │ TYPE │                       URL
  ───────────────┼──────┼────────────────────────────────────────────────────
    hello-example │ user │ git+https://github.com/flox-examples/hello-python
    flox         │ flox │ github:flox/floxpkgs/master
    nixpkgs-flox │ flox │ github:flox/nixpkgs-flox/master

Once a user subscribes to a channel, they can search for packages in that channel.

$ flox search hello-python
hello-example.hello-python - An example of a flox package.

We can also install it to a flox environment.

$ flox install hello-example.hello-python
Installed 'hello-example.hello-python' package(s) into 'default' environment.

$ flox activate -- hello-python
Hello world!

5. flox unsubscribe - unsubscribe from a channel

When you no longer wish to use packages from a certain channel you can always unsubscribe from that channel.

$ flox unsubscribe hello-example
unsubscribed from channel 'hello-example'

The package you installed to one of your environments from a channel you unsubscribed from will still continue to work. But upgrading that package will fail.

Where to next?