Use Nix with JFrog CLI

Configure and run jf nix with JFrog Artifactory for Nix binary cache, channels, build-info collection, and CI publishing workflows.

Run Nix commands with Artifactory integration for dependency resolution, binary cache publishing, and build-info collection. This topic explains when to use jf nix, how to connect Nix to Artifactory, and how to run builds with optional build-info.

This topic covers the following tasks:

When to Use

Use jf nix if your project uses the Nix package manager and you want packages resolved from or published to JFrog Artifactory. You can also collect build-info and publish it with jf rt build-publish for traceability and security scanning.

There is no jf nix-config command. Configure Nix the same way you would for Artifactory alone (nix.conf, nix-channel); jf nix wraps native Nix tools and adds build-info when you pass --build-name and --build-number.

Use raw nix or nix-channel with Artifactory URLs only when you do not need build-info. For repository setup, see Nix Repositories.

For npm or Yarn workflows, see Use npm with JFrog CLI or Use Yarn with JFrog CLI.

📘

Package Alias (Ghost Frog)

Package Alias does not intercept nix commands. Supported tools are mvn, gradle, npm, yarn, pnpm, go, pip, pipenv, poetry, dotnet, nuget, docker, gem, and bundle. See Use JFrog CLI Package Alias for setup and the full tool list.

Prerequisites

  • Nix installed on your machine or CI agent. On macOS, use the Determinate installer or the official installer (both require administrator access once). After install, open a new shell or run . /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh.

  • JFrog CLI installed. Verify with jf --version and jf nix --help. For installation steps, see Download and Install the JFrog CLI.

  • Configure a server with jf config add or jf c add. Authentication to Artifactory is required.

  • A Nix repository in Artifactory (local, remote, or virtual). See Create a Nix repository.

  • Artifactory connected to Nix: substituter and channels configured. See Connect Nix to Artifactory.

  • nix.conf experimental features when using nix copy or flakes:

    experimental-features = nix-command flakes
  • For flake workflows: a git repository with all flake files committed (Nix requires tracked files).


Configuration: Connect Nix to Artifactory

Configure Nix to resolve from or publish to Artifactory before your first jf nix build. jf nix does not write Nix configuration files.

Complete the steps in Nix Repositories for repository creation and platform setup.

This section covers the following procedures:

To connect Nix to Artifactory:

Binary Cache Substituter

Add Artifactory as a substituter in ~/.config/nix/nix.conf:

substituters = https://<USERNAME>:<TOKEN>@<JFrogPlatformURL>/artifactory/api/nix/<REPO_NAME>?priority=20
experimental-features = nix-command flakes

Use a priority lower than 40 so Artifactory is preferred over cache.nixos.org. Details: Configure Binary Cache.

Channels

For nix-build '<nixpkgs>' examples, register a channel first:

nix-channel --add https://<USERNAME>:<TOKEN>@<JFrogPlatformURL>/artifactory/api/nix/<REPO_NAME>/channels/<CHANNEL_NAME> <CHANNEL_ALIAS>
nix-channel --update

Or use the CLI wrapper (no build-info is collected):

jf nix nix-channel --add https://<USERNAME>:<TOKEN>@<JFROG_PLATFORM_URL>/artifactory/api/nix/<REPO>/channels/nixos-25.11 nixpkgs
jf nix nix-channel --update

Details: Configure Channels.

Authentication

The Nix client does not prompt for credentials. Use credentials in the URL, a .netrc file, or JFrog CLI: with jf config add, the CLI uses your configured server (--server-id or the default) and may set a temporary netrc for Nix. See Nix Authentication.

Configuration Examples

View Channel List

jf nix nix-channel --list

Add and Update a Channel

jf nix nix-channel --add https://<USERNAME>:<TOKEN>@<JFROG_PLATFORM_URL>/artifactory/api/nix/<REPO>/channels/nixos-25.11 nixpkgs
jf nix nix-channel --update

Why Configure First

You must connect Nix to Artifactory before builds that use <nixpkgs> or Artifactory substituters. Without a channel or substituter, nix-build '<nixpkgs>' fails or falls back to public caches only.

jf nix does not replace Nix configuration. It runs native Nix commands and optionally collects build-info.

👍

Shortcut

In CI/CD, write nix.conf and channel URLs from secrets so the setup step is fully automated and reproducible.

Configuration Notes

  • No jf nix-config: Unlike jf yarn-config or jf pip-config, Nix uses standard nix.conf and nix-channel. See Nix Repositories.
  • Re-run when changing repos: Update nix.conf or channels when you change the resolution or deployment repository.
  • Credentials: Expired JFrog CLI tokens cause 401 on jf nix copy and jf rt build-publish. Run jf config add --overwrite to refresh.

How to Verify

Confirm Nix sees your configuration:

nix-channel --list
cat ~/.config/nix/nix.conf

Build: jf nix

Run Nix commands with Artifactory integration and optional build-info collection.

To run Nix commands with Artifactory integration:

Synopsis

jf nix <native-command> <args> [command options]

Aliases: none

Arguments

ArgumentRequiredDescription
native-commandYesnix-channel, nix-env, nix-build, build, copy, or another nix subcommand (for example flake)
argsVariesArguments passed to the native command

JFrog CLI removes --build-name, --build-number, --module, --project, and --server-id before invoking Nix.

Subcommands and Build-Info

CommandExampleBuild-info
nix-channeljf nix nix-channel --updateNo
nix-envjf nix nix-env -iA nixpkgs.hello --build-name=my-app --build-number=1Yes
nix-buildjf nix nix-build '<nixpkgs>' -A hello --build-name=my-app --build-number=1Yes
buildjf nix build .#hello --build-name=my-app --build-number=1Yes
copyjf nix copy --to "…/api/nix/repo/" ./result --build-name=my-app --build-number=1Yes
Otherjf nix flake lockNo (passthrough)

Build Options

FlagDefaultDescription
--build-nameBuild name for build information. Build number option is mandatory when this option is provided.
--build-numberBuild number for build information. Build name option is mandatory when this option is provided.
--moduleOptional module name for the build information. Build name and number options are mandatory when this option is provided.
--projectJFrog Artifactory project key.
--server-idJFrog CLI server ID from jf config.

Provide both --build-name and --build-number together for build-info. If only one is set, the CLI returns an error. If neither is set, Nix runs without collecting build-info.

Build Examples

View Help

jf nix --help

Install a Package with nix-env

jf nix nix-env -iA nixpkgs.hello --build-name=my-app --build-number=1
jf rt build-publish my-app 1

Build with Channels Using nix-build

Requires a configured nixpkgs channel (see Channels).

jf nix nix-build '<nixpkgs>' -A hello --build-name=my-app --build-number=1

Project-local expression:

jf nix nix-build default.nix --build-name=my-app --build-number=1

Build with Flakes Using nix build

git init
git add .
git commit -m "init"
jf nix build --build-name=my-app --build-number=1

Specific output:

jf nix build .#hello --build-name=my-app --build-number=1

The build argument runs nix build. The CLI reads the ./result symlink and collects build-info from the store closure.

Lock Flake Inputs

jf nix flake lock

Build-info is not collected for passthrough commands such as flake lock.

Publish to Artifactory with nix copy

After nix-build or nix build:

jf nix copy --to "https://<USERNAME>:<TOKEN>@<JFROG_PLATFORM_URL>/artifactory/api/nix/<REPO>/" ./result \
  --build-name=my-app --build-number=1

For a virtual repository, JFrog CLI resolves defaultDeploymentRepo, rewrites the --to URL to the local deployment repository, and adds --refresh for the upload. Set a default deployment repository on the virtual Nix repository in Artifactory.

Full Lifecycle

jf nix nix-build '<nixpkgs>' -A hello --build-name=my-app --build-number=1

jf nix copy --to "https://<USERNAME>:<TOKEN>@<JFROG_PLATFORM_URL>/artifactory/api/nix/nix-local/" ./result \
  --build-name=my-app --build-number=1

jf rt build-publish my-app 1

jf rt bp is shorthand for jf rt build-publish.

Override Module Name

jf nix nix-build '<nixpkgs>' -A hello \
  --build-name=my-app --build-number=1 --module=my-custom-module

Build Output Notes

When build-info is collected:

[Info] Nix build info collected. Use 'jf rt bp my-app 1' to publish it.

The CLI generates a Trace ID at the start of every invocation and logs it at DEBUG level. If the command fails, the Trace ID is additionally printed at INFO level:

[Info] Trace ID for JFrog Platform logs: <id>

To see the Trace ID on a successful run, enable debug logging:

export JFROG_CLI_LOG_LEVEL=DEBUG

Provide this ID to JFrog Support to correlate client-side failures with server-side logs.


Important Notes

  • No jf nix-config: Configure Nix with nix.conf and nix-channel. See Connect Nix to Artifactory.
  • jf nix nix-build vs jf nix build: nix-build is the legacy command (reads output paths from stdout). build runs nix build for flakes (reads the ./result symlink).
  • Substituter vs copy: A substituter lets clients download cached binaries. jf nix copy uploads your build outputs to Artifactory and can record them in build-info. Use copy in CI after you build.
  • nix-channel and flake lock: No build-info is collected. Use nix-env, nix-build, build, or copy with both build flags when you need build-info.
  • Build-info: Use --build-name and --build-number, then publish with jf rt build-publish. Module type is nix. Dependencies come from the runtime closure (nix path-info). Checksums use narHash; run jf nix copy before publish if checksums are missing from Artifactory. See Build-Info Integration.
FieldDescription
Module typenix
DependenciesRuntime closure from nix path-info (excluding the build output root)
ChecksumsnarHash from Nix; may be resolved from Artifactory binary-cache/<store-hash>/
Artifacts (copy).nar.xz and .narinfo in the binary cache layout
Build properties (copy)Applied to artifacts in the closure

Dependency scopes are runtime for nix-env, nix-build, and nix build.


CI/CD Example for GitHub Actions

To run a Nix build with build-info in GitHub Actions:

name: Nix Build
on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: DeterminateSystems/nix-installer-action@v9

      - uses: jfrog/setup-jfrog-cli@v4
        env:
          JF_URL: ${{ vars.JF_URL }}
          JF_ACCESS_TOKEN: ${{ secrets.JF_ACCESS_TOKEN }}

      - name: Configure Nix substituter
        run: |
          mkdir -p ~/.config/nix
          echo "substituters = https://${{ secrets.JF_USER }}:${{ secrets.JF_ACCESS_TOKEN }}@${{ vars.JF_HOST }}/artifactory/api/nix/nix-virtual?priority=20" >> ~/.config/nix/nix.conf
          echo "experimental-features = nix-command flakes" >> ~/.config/nix/nix.conf

      - name: Build with build-info
        run: |
          jf nix nix-build '<nixpkgs>' -A hello \
            --build-name=my-app --build-number=${{ github.run_number }}

      - name: Copy to Artifactory
        run: |
          jf nix copy --to "https://${{ secrets.JF_USER }}:${{ secrets.JF_ACCESS_TOKEN }}@${{ vars.JF_HOST }}/artifactory/api/nix/nix-local/" ./result \
            --build-name=my-app --build-number=${{ github.run_number }}

      - name: Publish build-info
        run: jf rt build-publish my-app ${{ github.run_number }}

Adjust repository keys and channel names for your environment.


Troubleshooting

SymptomCauseFix
'jf nix' is not a jf commandJFrog CLI version does not include Nix supportUpgrade JFrog CLI. See Download and Install the JFrog CLI.
executable file not found in $PATH for nix, nix-build, or nix-channelNix is not installed or not on PATHInstall Nix; open a new shell or run . /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh
Error about build-name / build-numberOnly one of the two flags was providedPass both flags together, or omit both
No build-info after buildCommand does not support build-info, or flags were omittedUse nix-env, nix-build, build, or copy with both build flags
nix-build '<nixpkgs>' failsChannel not configuredRun nix-channel --add and nix-channel --update, or use a flake project
Flake command failsFlake files are not committed in gitCommit all flake files before running jf nix build or jf nix flake lock
copy uploads to wrong repositoryVirtual repository has no default deployment repositorySet defaultDeploymentRepo on the virtual Nix repository
401 / 403 / Invalid token, expiredInvalid or expired credentialsRun jf config add --overwrite. For nix copy, check URL credentials or .netrc
ignoring the client-specified setting 'netrc-file'Multi-user Nix restricts client netrc unless you are a trusted userUse credentials in the URL or rely on jf config add
No build-info after flake lockflake lock is passthrough onlyUse a supported command (nix-env, nix-build, build, copy) for build-info
Missing checksums in build-infoArtifactory binary cache not populatedRun jf nix copy before jf rt build-publish

Enable debug logging: export JFROG_CLI_LOG_LEVEL=DEBUG


Frequently Asked Questions

This section provides answers to frequently asked questions about using Nix with JFrog CLI.

FAQs
Q: How do I run Nix builds with jf nix and build-info?

A: Run jf nix with a supported subcommand such as nix-env, nix-build, build, or copy, and pass both --build-name and --build-number. Publish the result with jf rt build-publish. See Build: jf nix.

Q: What do I need before using jf nix with Artifactory?

A: You need Nix and JFrog CLI installed, a configured server connection, a Nix repository in Artifactory, and nix.conf or channel setup. See Prerequisites and Configuration: Connect Nix to Artifactory.

Q: What is the difference between jf nix nix-build and jf nix build?

A: jf nix nix-build runs the legacy nix-build command and reads output paths from stdout. jf nix build runs nix build for flake workflows and reads the ./result symlink. See Important Notes.

Q: Why does nix-build '<nixpkgs>' fail with jf nix?

A: The nixpkgs channel is not registered or updated. Run nix-channel --add and nix-channel --update, or use a flake-based project instead. See Channels and Troubleshooting.

Q: Why is there no jf nix-config command?

A: Nix uses standard nix.conf and nix-channel configuration instead of a JFrog CLI config subcommand. Connect substituters and channels per Nix Repositories. See Configuration Notes.

Q: Does Package Alias intercept nix commands?

A: No. Package Alias supports 14 tools including npm and Maven, but not nix. Use jf nix explicitly or native nix with Artifactory URLs. See Use JFrog CLI Package Alias.

Related Topics