Use Docker with JFrog CLI
Run Docker commands with Artifactory integration, including login, build, push, pull, and Xray scanning.
This topic covers the following tasks:
When to Use
Use jf docker to build, push, pull, and scan Docker images with Artifactory integration. The CLI handles Docker login automatically and collects build-info for traceability. For Helm chart operations, use jf helm.
Automatic docker login uses the hostname from your configured server (jf config). If your image tags or FROM lines use a different registry host (for example, subdomain Docker URLs), use jf docker build --skip-login or jf docker buildx build --skip-login on JFrog CLI 2.98.0 or later after logging in to that host, or configure the server URL to match the host in your tags.
Prerequisites
-
Docker must be installed and its daemon running. On macOS, open Docker Desktop before running any
jf dockercommands. To verify the daemon is up, rundocker info. -
Configure a server with
jf config addorjf c add. -
Authentication to Artifactory is required.
jf dockercommands use the credentials stored byjf config add.Reference (non-JWT) tokens: If your JFrog server was configured with only an access token and no username,
jf docker login,jf docker build,jf docker push, andjf docker pullwill fail withusername is empty. To fix this, re-runjf config addand supply a username, or usejf docker login <registry> --username <user> --password-stdinto pass credentials explicitly. -
For scanning (
jf docker scan), JFrog Xray must be configured on your JFrog Platform instance.
Build: jf docker
jf dockerRun Docker commands with Artifactory integration, including login, build, push, pull, and Xray scanning.
To run Docker commands with Artifactory integration:
- Ensure Docker is running and a JFrog server is configured (see Prerequisites).
- Run
jf dockerwith the Docker subcommand (build,push,pull,scan, and others) and optional build-info or scan flags (see Build Examples).
Synopsis
jf docker <docker-arguments> [options]
Aliases: none
Arguments
| Argument | Required | Description |
|---|---|---|
docker-arguments | Yes | Docker subcommand and arguments |
Subcommands
| Subcommand | Description |
|---|---|
login | Log in to an Artifactory Docker registry |
build | Run Docker build (also supports buildx build for multi-platform images) |
push | Push image to Artifactory |
pull | Pull image from Artifactory |
scan | Scan a local Docker image for vulnerabilities with JFrog Xray |
Build / Push / Pull Options
| Flag | Default | Description |
|---|---|---|
--build-name | — | Build name for build information (requires --build-number) |
--build-number | — | Build number for build information (requires --build-name) |
--project | — | JFrog Artifactory project key |
--module | — | Optional module name for build information |
--skip-login | false | Skip performing Docker login before build, push, or pull. JFrog CLI 2.98.0 and later honor this flag for jf docker build and jf docker buildx build (skip the pre-build loginCmd); on older CLI versions, --skip-login is ignored for build and the CLI always runs docker login against the configured server host before building. |
--threads | 3 | Number of working threads |
--detailed-summary | false | Include affected files in the command summary |
--server-id | — | Server ID configured with jf config add |
--validate-sha | false | Enable SHA validation during Docker push |
Scan Options (jf docker scan)
jf docker scan)| Flag | Default | Description |
|---|---|---|
--server-id | — | Server ID configured with jf config add |
--project | — | JFrog Artifactory project key |
--watches | — | Comma-separated list of Xray watches for violation evaluation |
--repo-path | — | Target repo path to enable Xray to determine watches accordingly |
--licenses | false | Set to true to receive license information from Xray scanning |
--format | table | Output format. Accepts table, json, simple-json, or sarif |
--fail | true | Set to false to prevent exit code 3 even if the Fail Build rule is matched by Xray |
--min-severity | — | Minimum severity of issues to display. Accepts: Low, Medium, High, or Critical |
--fixable-only | false | Set to true to display only issues that have a fixed version |
--vuln | false | Set to true to receive all vulnerabilities regardless of Xray policy configuration |
--extended-table | false | Include extended fields such as CVSS and Xray Issue ID in table output |
--bypass-archive-limits | false | Set to true to bypass the indexer-app archive limits |
Build Examples
Login to Artifactory
jf docker login <registry-url>Where:
<registry-url>is your Artifactory Docker registry URL (for example,acme.jfrog.io)
For example:
jf docker login acme.jfrog.ioBuild and Push
Note
: A
Dockerfilemust exist in the current directory (.). For a minimal example:echo 'FROM alpine:3.19' > Dockerfile. By default,jf docker buildrunsdocker loginbefore building — ensure your server is configured with a username (see Prerequisites). If you already ranjf docker loginto the registry host your image tag uses (for example, when Artifactory uses subdomain access and your image is<server>-<repo>.jfrog.io/...whilejf configuses<server>.jfrog.io), usejf docker build --skip-loginon JFrog CLI 2.98.0 or later so the CLI does not log in to the wrong host. Alternatively, pointjf configat the same registry hostname you use in image tags.
jf docker build -t <registry-url>/<image>:<tag> .
jf docker push <registry-url>/<image>:<tag> --build-name=<build-name> --build-number=<build-number>Where:
<registry-url>is your Artifactory Docker registry (for example,acme.jfrog.io)<image>is the Docker image name (for example,my-app)<tag>is the image tag (for example,1.0.0)
For example:
jf docker build -t acme.jfrog.io/docker-local/my-app:1.0.0 .
jf docker push acme.jfrog.io/docker-local/my-app:1.0.0 --build-name=my-app --build-number=1Multi-Platform Build with Docker Buildx
jf docker buildx build supports multi-platform image builds with build-info collection. Standard Docker Buildx arguments are supported.
jf docker buildx build --platform linux/amd64,linux/arm64 \
-t <registry-url>/<image>:<tag> . \
--build-name=<build-name> --build-number=<build-number>Scan Image
jf docker scan <image-name>:<tag>For example:
jf docker scan acme.jfrog.io/docker-local/my-app:1.0.0Push with Build Information
jf docker push <registry-url>/<image>:<tag> --build-name=my-app --build-number=1 --threads=5End-to-End: Build, Push, and Publish Build Info
jf docker build -t acme.jfrog.io/docker-local/my-app:1.0.0 .
jf docker push acme.jfrog.io/docker-local/my-app:1.0.0 --build-name=my-app --build-number=1
jf rt build-publish my-app 1After jf rt build-publish, the build appears in Artifactory under Build Info > my-app.
Docker Login
To log in to an Artifactory Docker registry:
- Configure a JFrog server with
jf config addif needed (see Prerequisites). - Run
jf docker loginwith an optional registry argument and credential options as needed (see the examples later in this section).
Synopsis
jf docker login [registry] [--server-id <id>] [--username <name>] [--password <pwd>]
Logs your local Docker client into an Artifactory Docker registry using credentials managed by JFrog CLI. After a successful login, you can run native Docker commands (for example, docker pull, docker push, docker build) that interact with Artifactory without re-authenticating each time.
Arguments
registry(optional) — The Docker registry to log into (for example,my-docker.jfrog.io). If omitted, JFrog CLI uses the platform URL from the configured server.
Options
--server-id(optional) — Use a specific configured server.--username(optional) — Docker registry username.--password(optional) — Docker registry password. Prefer--password-stdinto avoid exposing credentials in shell history and to suppress the Docker insecure-password warning.
When using --username/--password or --username/--password-stdin, the registry argument is mandatory.
Examples
jf docker login
jf docker login --server-id my-jfrog
jf docker login my-docker-registry.jfrog.io --server-id my-jfrog
echo "$MY_TOKEN" | jf docker login my-docker-registry.jfrog.io --username <USERNAME> --password-stdinImportant Notes
- Docker login: The CLI performs
docker loginautomatically before build, push, and pull unless--skip-loginis set. Use--skip-loginwhen you have already authenticated to the correct registry (for example, a priorjf docker loginstep in CI) and you do not want the CLI to rundocker loginagain. From JFrog CLI 2.98.0 onward,--skip-loginapplies tojf docker buildandjf docker buildx buildas well as to push and pull; on older CLI versions,--skip-loginis ignored for build, so upgrading is required for that workflow. If auto-login targets the wrong host (common when the configured platform URL is<server>.jfrog.iobut image tags use subdomain URLs such as<server>-<repo>.jfrog.io), either align the configured URL with the registry used in tags or use--skip-loginafter logging in to the subdomain registry. - Xray scanning:
jf docker scanscans a locally-built image against Xray policies. It communicates directly with Xray and does not require Docker login — you can scan a local image even ifjf docker loginhas not been run. The image does not need to be pushed to Artifactory first. Requires Xray to be configured on your JFrog Platform. - Build info: When using
--build-nameand--build-number, the CLI records Docker layers as build dependencies. After pushing, you must publish the build info separately:Until this step is run, the build will not appear in Artifactory's build browser.jf rt build-publish <build-name> <build-number> - Multi-architecture images: Build and push each architecture separately, then create a manifest list. The CLI's build info captures each push independently.
- Registry URL: With repository path access, tags often look like
<your-server>.jfrog.io/<repo-key>/<image>:<tag>(for example,acme.jfrog.io/docker-local/my-app:1.0.0). With subdomain access, the registry host is<your-server>-<repo-key>.jfrog.ioand tags look like<your-server>-<repo-key>.jfrog.io/<image>:<tag>. Use the same hostname injf docker login,jf config, and your image tags (or--skip-loginon build after logging in to the tag host; see When to Use).
Coming from the UI?
In the Artifactory UI, you can view Docker images under Artifacts >
<docker-repo>. The CLI'sjf docker pushandjf docker pullinteract with the same Docker repositories you see in the UI.
Native Mode
Docker supports Native Mode, which runs the native Docker build directly instead of the legacy JFrog build flow. Build-info is still collected when --build-name and --build-number are provided.
Enable with: export JFROG_RUN_NATIVE=true
For full setup instructions, per-tool comparison, and when to use each mode, see Native Mode.
CI/CD Example (GitHub Actions)
# .github/workflows/build.yml
# Path-style registry example (login host matches image tag host).
# Subdomain access: if JF_URL is acme.jfrog.io but images use acme-docker-local.jfrog.io/...,
# log in to the subdomain in the step below, then run jf docker build ... --skip-login (JFrog CLI 2.98.0+).
steps:
- uses: actions/checkout@v4
- name: Setup JFrog CLI
uses: jfrog/setup-jfrog-cli@v4
env:
JF_URL: ${{ vars.JF_URL }}
JF_ACCESS_TOKEN: ${{ secrets.JF_ACCESS_TOKEN }}
- name: Login to Docker registry
run: jf docker login acme.jfrog.io --server-id=setup-jfrog-cli-server
- name: Build Docker image
run: jf docker build -t acme.jfrog.io/docker-local/my-app:${{ github.run_number }} .
- name: Push Docker image
run: jf docker push acme.jfrog.io/docker-local/my-app:${{ github.run_number }} --build-name=my-app --build-number=${{ github.run_number }}
- name: Scan Docker image
run: jf docker scan acme.jfrog.io/docker-local/my-app:${{ github.run_number }}
- name: Publish build info
run: jf rt build-publish my-app ${{ github.run_number }}If you run jf docker login in an earlier step to a registry hostname that differs from the URL in jf config (for example, subdomain Docker registries), append --skip-login to the jf docker build line on JFrog CLI 2.98.0 or later so the build step does not trigger a second login to the wrong host.
Advanced Operations
For container operations using alternative tools (Podman, Kaniko, buildx, OpenShift) and Docker image lifecycle commands (build-docker-create, docker-promote), see Docker Advanced Operations.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
username is empty on any jf docker command | Server configured with a reference (non-JWT) access token and no username | Re-run jf config add with a username, or use echo "$TOKEN" | jf docker login <registry> --username <user> --password-stdin |
docker: not running or socket error | Docker daemon is not running | On macOS, open Docker Desktop and wait for it to start, then re-run the command |
docker login fails | Incorrect registry URL or credentials | Confirm which Docker access method you use: repository path — registry host is often <server>.jfrog.io and the repo key appears in the image path (for example, <server>.jfrog.io/<repo-key>/<image>:<tag>; the host is not <server>.jfrog.io/<repo-key> alone). Subdomain — registry host is <server>-<repo>.jfrog.io with no repo segment in the hostname. Match jf docker login to that host. |
login attempt to https://<server>.jfrog.io/v2/ failed with status: 400 Bad Request during jf docker build | CLI auto-login uses the configured platform host while the Dockerfile references a subdomain registry (<server>-<repo>.jfrog.io) | Upgrade to JFrog CLI 2.98.0 or later and run jf docker build --skip-login after jf docker login to the subdomain host, or add the server with jf config using the same hostname as in your image tags |
| 401 / 403 on push or pull | Invalid credentials or insufficient permissions | Re-run jf config add or jf docker login with valid credentials |
jf docker push succeeds but image not visible | Pushed to wrong repository | Confirm the image tag includes the correct registry and repo path: <server>.jfrog.io/<repo-key>/<image>:<tag> |
jf docker scan returns no results | Xray is not configured on the JFrog Platform | Verify Xray is enabled and the image is indexed |
--skip-login causes auth failures | No prior Docker login for this registry | Remove --skip-login or run jf docker login first |
| Build pushed but not visible in Build Info | jf rt build-publish was not run after push | Run jf rt build-publish <build-name> <build-number> to publish the build info |
| Multi-arch image build-info incomplete | Each architecture pushed separately | Push each architecture with the same --build-name and --build-number |
Enable debug logging: export JFROG_CLI_LOG_LEVEL=DEBUG
Related Topics
- Build Tools Overview — Capabilities matrix and tool reference
- Native Mode — Supported packages with Native Mode
Updated 9 days ago
