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
nixcommands. Supported tools aremvn,gradle,npm,yarn,pnpm,go,pip,pipenv,poetry,dotnet,nuget,docker,gem, andbundle. 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 --versionandjf nix --help. For installation steps, see Download and Install the JFrog CLI. -
Configure a server with
jf config addorjf 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.confexperimental features when usingnix copyor 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:
- Configure a binary cache substituter
- Configure channels
- Configure authentication
- Verify configuration
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 flakesUse 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 --updateOr 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 --updateDetails: 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 --listAdd 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 --updateWhy 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.confand channel URLs from secrets so the setup step is fully automated and reproducible.
Configuration Notes
- No
jf nix-config: Unlikejf yarn-configorjf pip-config, Nix uses standardnix.confandnix-channel. See Nix Repositories. - Re-run when changing repos: Update
nix.confor channels when you change the resolution or deployment repository. - Credentials: Expired JFrog CLI tokens cause
401onjf nix copyandjf rt build-publish. Runjf config add --overwriteto refresh.
How to Verify
Confirm Nix sees your configuration:
nix-channel --list
cat ~/.config/nix/nix.confBuild: jf nix
jf nixRun 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
| Argument | Required | Description |
|---|---|---|
native-command | Yes | nix-channel, nix-env, nix-build, build, copy, or another nix subcommand (for example flake) |
args | Varies | Arguments passed to the native command |
JFrog CLI removes --build-name, --build-number, --module, --project, and --server-id before invoking Nix.
Subcommands and Build-Info
| Command | Example | Build-info |
|---|---|---|
nix-channel | jf nix nix-channel --update | No |
nix-env | jf nix nix-env -iA nixpkgs.hello --build-name=my-app --build-number=1 | Yes |
nix-build | jf nix nix-build '<nixpkgs>' -A hello --build-name=my-app --build-number=1 | Yes |
build | jf nix build .#hello --build-name=my-app --build-number=1 | Yes |
copy | jf nix copy --to "…/api/nix/repo/" ./result --build-name=my-app --build-number=1 | Yes |
| Other | jf nix flake lock | No (passthrough) |
Build Options
| Flag | Default | Description |
|---|---|---|
--build-name | — | Build name for build information. Build number option is mandatory when this option is provided. |
--build-number | — | Build number for build information. Build name option is mandatory when this option is provided. |
--module | — | Optional module name for the build information. Build name and number options are mandatory when this option is provided. |
--project | — | JFrog Artifactory project key. |
--server-id | — | JFrog 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 --helpInstall 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 1Build 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=1Project-local expression:
jf nix nix-build default.nix --build-name=my-app --build-number=1Build with Flakes Using nix build
git init
git add .
git commit -m "init"
jf nix build --build-name=my-app --build-number=1Specific output:
jf nix build .#hello --build-name=my-app --build-number=1The 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 lockBuild-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=1For 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 1jf 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-moduleBuild 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=DEBUGProvide this ID to JFrog Support to correlate client-side failures with server-side logs.
Important Notes
- No
jf nix-config: Configure Nix withnix.confandnix-channel. See Connect Nix to Artifactory. jf nix nix-buildvsjf nix build:nix-buildis the legacy command (reads output paths from stdout).buildrunsnix buildfor flakes (reads the./resultsymlink).- Substituter vs
copy: A substituter lets clients download cached binaries.jf nix copyuploads your build outputs to Artifactory and can record them in build-info. Usecopyin CI after you build. nix-channelandflake lock: No build-info is collected. Usenix-env,nix-build,build, orcopywith both build flags when you need build-info.- Build-info: Use
--build-nameand--build-number, then publish withjf rt build-publish. Module type isnix. Dependencies come from the runtime closure (nix path-info). Checksums usenarHash; runjf nix copybefore publish if checksums are missing from Artifactory. See Build-Info Integration.
| Field | Description |
|---|---|
| Module type | nix |
| Dependencies | Runtime closure from nix path-info (excluding the build output root) |
| Checksums | narHash 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
| Symptom | Cause | Fix |
|---|---|---|
'jf nix' is not a jf command | JFrog CLI version does not include Nix support | Upgrade JFrog CLI. See Download and Install the JFrog CLI. |
executable file not found in $PATH for nix, nix-build, or nix-channel | Nix is not installed or not on PATH | Install Nix; open a new shell or run . /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh |
| Error about build-name / build-number | Only one of the two flags was provided | Pass both flags together, or omit both |
| No build-info after build | Command does not support build-info, or flags were omitted | Use nix-env, nix-build, build, or copy with both build flags |
nix-build '<nixpkgs>' fails | Channel not configured | Run nix-channel --add and nix-channel --update, or use a flake project |
| Flake command fails | Flake files are not committed in git | Commit all flake files before running jf nix build or jf nix flake lock |
copy uploads to wrong repository | Virtual repository has no default deployment repository | Set defaultDeploymentRepo on the virtual Nix repository |
401 / 403 / Invalid token, expired | Invalid or expired credentials | Run 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 user | Use credentials in the URL or rely on jf config add |
No build-info after flake lock | flake lock is passthrough only | Use a supported command (nix-env, nix-build, build, copy) for build-info |
| Missing checksums in build-info | Artifactory binary cache not populated | Run 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?
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.
