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 docker commands. To verify the daemon is up, run docker info.

  • Configure a server with jf config add or jf c add.

  • Authentication to Artifactory is required. jf docker commands use the credentials stored by jf 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, and jf docker pull will fail with username is empty. To fix this, re-run jf config add and supply a username, or use jf docker login <registry> --username <user> --password-stdin to pass credentials explicitly.

  • For scanning (jf docker scan), JFrog Xray must be configured on your JFrog Platform instance.


Build: jf docker

Run Docker commands with Artifactory integration, including login, build, push, pull, and Xray scanning.

To run Docker commands with Artifactory integration:

  1. Ensure Docker is running and a JFrog server is configured (see Prerequisites).
  2. Run jf docker with 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

ArgumentRequiredDescription
docker-argumentsYesDocker subcommand and arguments

Subcommands

SubcommandDescription
loginLog in to an Artifactory Docker registry
buildRun Docker build (also supports buildx build for multi-platform images)
pushPush image to Artifactory
pullPull image from Artifactory
scanScan a local Docker image for vulnerabilities with JFrog Xray

Build / Push / Pull Options

FlagDefaultDescription
--build-nameBuild name for build information (requires --build-number)
--build-numberBuild number for build information (requires --build-name)
--projectJFrog Artifactory project key
--moduleOptional module name for build information
--skip-loginfalseSkip 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.
--threads3Number of working threads
--detailed-summaryfalseInclude affected files in the command summary
--server-idServer ID configured with jf config add
--validate-shafalseEnable SHA validation during Docker push

Scan Options (jf docker scan)

FlagDefaultDescription
--server-idServer ID configured with jf config add
--projectJFrog Artifactory project key
--watchesComma-separated list of Xray watches for violation evaluation
--repo-pathTarget repo path to enable Xray to determine watches accordingly
--licensesfalseSet to true to receive license information from Xray scanning
--formattableOutput format. Accepts table, json, simple-json, or sarif
--failtrueSet to false to prevent exit code 3 even if the Fail Build rule is matched by Xray
--min-severityMinimum severity of issues to display. Accepts: Low, Medium, High, or Critical
--fixable-onlyfalseSet to true to display only issues that have a fixed version
--vulnfalseSet to true to receive all vulnerabilities regardless of Xray policy configuration
--extended-tablefalseInclude extended fields such as CVSS and Xray Issue ID in table output
--bypass-archive-limitsfalseSet 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.io

Build and Push

📘

Note

: A Dockerfile must exist in the current directory (.). For a minimal example: echo 'FROM alpine:3.19' > Dockerfile. By default, jf docker build runs docker login before building — ensure your server is configured with a username (see Prerequisites). If you already ran jf docker login to the registry host your image tag uses (for example, when Artifactory uses subdomain access and your image is <server>-<repo>.jfrog.io/... while jf config uses <server>.jfrog.io), use jf docker build --skip-login on JFrog CLI 2.98.0 or later so the CLI does not log in to the wrong host. Alternatively, point jf config at 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=1

Multi-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.0

Push with Build Information

jf docker push <registry-url>/<image>:<tag> --build-name=my-app --build-number=1 --threads=5

End-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 1

After jf rt build-publish, the build appears in Artifactory under Build Info > my-app.


Docker Login

To log in to an Artifactory Docker registry:

  1. Configure a JFrog server with jf config add if needed (see Prerequisites).
  2. Run jf docker login with 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-stdin to 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-stdin

Important Notes

  • Docker login: The CLI performs docker login automatically before build, push, and pull unless --skip-login is set. Use --skip-login when you have already authenticated to the correct registry (for example, a prior jf docker login step in CI) and you do not want the CLI to run docker login again. From JFrog CLI 2.98.0 onward, --skip-login applies to jf docker build and jf docker buildx build as well as to push and pull; on older CLI versions, --skip-login is 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.io but 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-login after logging in to the subdomain registry.
  • Xray scanning: jf docker scan scans 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 if jf docker login has 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-name and --build-number, the CLI records Docker layers as build dependencies. After pushing, you must publish the build info separately:
    jf rt build-publish <build-name> <build-number>
    Until this step is run, the build will not appear in Artifactory's build browser.
  • 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.io and tags look like <your-server>-<repo-key>.jfrog.io/<image>:<tag>. Use the same hostname in jf docker login, jf config, and your image tags (or --skip-login on 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's jf docker push and jf docker pull interact 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

SymptomCauseFix
username is empty on any jf docker commandServer configured with a reference (non-JWT) access token and no usernameRe-run jf config add with a username, or use echo "$TOKEN" | jf docker login <registry> --username <user> --password-stdin
docker: not running or socket errorDocker daemon is not runningOn macOS, open Docker Desktop and wait for it to start, then re-run the command
docker login failsIncorrect registry URL or credentialsConfirm 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 buildCLI 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 pullInvalid credentials or insufficient permissionsRe-run jf config add or jf docker login with valid credentials
jf docker push succeeds but image not visiblePushed to wrong repositoryConfirm the image tag includes the correct registry and repo path: <server>.jfrog.io/<repo-key>/<image>:<tag>
jf docker scan returns no resultsXray is not configured on the JFrog PlatformVerify Xray is enabled and the image is indexed
--skip-login causes auth failuresNo prior Docker login for this registryRemove --skip-login or run jf docker login first
Build pushed but not visible in Build Infojf rt build-publish was not run after pushRun jf rt build-publish <build-name> <build-number> to publish the build info
Multi-arch image build-info incompleteEach architecture pushed separatelyPush each architecture with the same --build-name and --build-number

Enable debug logging: export JFROG_CLI_LOG_LEVEL=DEBUG


Related Topics