Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/harness/harness-cli/llms.txt

Use this file to discover all available pages before exploring further.

Migrate your artifacts from JFrog Artifactory or Nexus Repository Manager to Harness Artifact Registry using the CLI’s automated migration tool.

Overview

The migration tool provides:
  • Automated transfers from JFrog and Nexus registries
  • Multiple artifact types including Docker, Maven, NPM, Helm, Python, and more
  • Concurrent operations for faster migration
  • Dry-run mode to preview what will be migrated
  • Graceful shutdown with interrupt signal handling

Supported Source Registries

  • JFrog Artifactory
  • Nexus Repository Manager

Supported Artifact Types

Docker

Maven

NPM

Helm

Python

Go

NuGet

Generic

Conda

Additional supported types: HELM_LEGACY, RPM, COMPOSER, DART

Configuration File

Create a YAML configuration file defining your source and destination registries:
config.yaml
version: 1.0.0
concurrency: 5
overwrite: false

source:
  endpoint: https://source-registry.example.com
  type: JFROG                    # JFROG or NEXUS
  credentials:
    username: source_user
    password: source_password
  insecure: false

destination:
  endpoint: https://pkg.harness.io
  type: HAR
  credentials:
    username: harness_user
    password: harness_api_key

mappings:
  - artifactType: DOCKER
    sourceRegistry: docker-repo
    destinationRegistry: harness-docker-repo

  - artifactType: MAVEN
    sourceRegistry: maven-releases
    destinationRegistry: harness-maven

  - artifactType: NPM
    sourceRegistry: npm-local
    destinationRegistry: harness-npm

  - artifactType: HELM
    sourceRegistry: helm-charts
    destinationRegistry: harness-helm

Configuration Options

version
string
required
Configuration version (use 1.0.0)
concurrency
integer
default:"1"
Number of concurrent operations for faster migration
overwrite
boolean
default:"false"
Allow overwriting existing artifacts in destination
dryRun
boolean
default:"false"
Run in dry-run mode (no uploads, generates reports)
source.endpoint
string
required
Source registry URL
source.type
string
required
Registry type: JFROG or NEXUS
source.credentials
object
required
Username and password/token for authentication
destination
object
required
Same structure as source, with type: HAR
mappings
array
required
List of artifact mappings from source to destination

Environment Variables

You can use environment variables in your configuration:
source:
  credentials:
    username: ${SOURCE_USERNAME}
    password: ${SOURCE_PASSWORD}

destination:
  credentials:
    username: ${HARNESS_USERNAME}
    password: ${HARNESS_API_KEY}

Migration Workflow

1

Create Configuration File

Create a config.yaml file with your source and destination registry details.
cat > config.yaml <<EOF
version: 1.0.0
concurrency: 5
source:
  endpoint: https://jfrog.example.com
  type: JFROG
  credentials:
    username: ${SOURCE_USER}
    password: ${SOURCE_TOKEN}
destination:
  endpoint: https://pkg.harness.io
  type: HAR
  credentials:
    username: ${HARNESS_USER}
    password: ${HARNESS_API_KEY}
mappings:
  - artifactType: DOCKER
    sourceRegistry: docker-local
    destinationRegistry: my-docker-repo
EOF
2

Run Dry-Run (Optional)

Test your configuration with a dry-run to see what will be migrated:
hc registry migrate -c config.yaml --dry-run
This generates two files in the dry-run-output/ directory:
  • file_list_YYYYMMDD_HHMMSS.json - List of all files to be migrated
  • directory_structure_YYYYMMDD_HHMMSS.json - Directory structure report
[
  {
    "registry": "docker-local",
    "package": "nginx",
    "version": "1.21.0",
    "path": "/v2/nginx/manifests/1.21.0",
    "size": 12345
  }
]
3

Execute Migration

Run the migration:
hc registry migrate -c config.yaml
The tool will:
  1. Load and validate your configuration
  2. Create API clients for source and destination
  3. Process each mapping concurrently
  4. Display progress and transfer statistics
4

Monitor Progress

The migration displays real-time progress:
Starting migration process
Processing registry migration: docker-local -> harness-docker-repo
Transferring: nginx:1.21.0 [████████████████████] 100%
Transferring: redis:6.2 [████████████████████] 100%
Migration process completed
Press Ctrl+C to gracefully shutdown if needed.
5

Review Results

After completion, review the statistics table:
NameRegistrySizeStatusUriError
nginx:1.21.0docker-local128 MBSUCCESSpkg.harness.io/docker/nginx:1.21.0-
redis:6.2docker-local45 MBSUCCESSpkg.harness.io/docker/redis:6.2-

Command Reference

Basic Usage

hc registry migrate -c config.yaml

With Options

hc registry migrate \
  --config config.yaml \
  --concurrency 10 \
  --overwrite \
  --dry-run

Command Options

--config, -c
string
required
Path to configuration file (default: config.yaml)
--pkg-url
string
Base URL for the API (overrides config)
--concurrency
integer
default:"1"
Number of concurrent operations (overrides config)
--overwrite
boolean
default:"false"
Allow overwriting artifacts (overrides config)
--dry-run
boolean
default:"false"
Run migration in dry-run mode (no uploads, generates reports)

Migration Strategies

JFrog Artifactory Migration

When migrating from JFrog:
The migration tool uses JFrog’s REST API to:
  • Discover packages via catalog endpoints
  • Download artifacts and metadata
  • Extract Maven, NPM, and Python package information
  • Handle Helm charts and Docker images via OCI protocol
Special considerations:
  • Docker/Helm (OCI): Migrated using container registry protocols
  • Maven: Extracts from maven-metadata.xml and POM files
  • NPM: Reads from package.json embedded in tarballs
  • Python: Parses .pypi/simple.html for package discovery
  • Helm Legacy: Uses index.yaml for chart enumeration

Nexus Repository Migration

When migrating from Nexus:
The migration tool uses Nexus V3 API to:
  • Search components via /service/rest/v1/search
  • Download assets with proper authentication
  • Discover Docker ports automatically
  • Handle Maven, NPM, Python, and other formats
Special considerations:
  • Docker: Automatically discovers Docker connector ports
  • Maven: Groups by groupId/artifactId/version
  • Hosted repositories only: Proxy repos are not migrated

Advanced Scenarios

Multiple Artifact Types

Migrate multiple artifact types in one configuration:
mappings:
  - artifactType: DOCKER
    sourceRegistry: docker-prod
    destinationRegistry: prod/docker

  - artifactType: MAVEN
    sourceRegistry: maven-releases
    destinationRegistry: prod/maven

  - artifactType: NPM
    sourceRegistry: npm-registry
    destinationRegistry: prod/npm

  - artifactType: HELM
    sourceRegistry: helm-stable
    destinationRegistry: prod/helm

High-Concurrency Migration

For large migrations, increase concurrency:
version: 1.0.0
concurrency: 20  # Process 20 artifacts simultaneously

mappings:
  - artifactType: GENERIC
    sourceRegistry: binaries
    destinationRegistry: prod/binaries
High concurrency may impact source registry performance. Start with lower values and increase gradually.

Selective Migration with Patterns

Filter which artifacts to migrate using include and exclude patterns:
mappings:
  - artifactType: DOCKER
    sourceRegistry: docker-repo
    destinationRegistry: prod/docker
    includePatterns:
      - "nginx*"
      - "redis*"
    excludePatterns:
      - "*-snapshot"
      - "*-dev"

Custom Package Hostname

For Docker/OCI registries with custom hostnames:
mappings:
  - artifactType: DOCKER
    sourceRegistry: docker-virtual
    destinationRegistry: prod/docker
    sourcePackageHostname: docker.jfrog.io

Troubleshooting

Authentication Errors

Error: failed to validate credentialsSolution:
  • Verify username and password/token in config
  • For JFrog, use API key or identity token
  • For Nexus, ensure user has appropriate permissions
  • Test credentials manually with curl
Error: 401 UnauthorizedSolution:
  • Regenerate API tokens
  • Use service accounts with non-expiring tokens
  • Set tokens as environment variables for easy rotation

Migration Failures

Error: context deadline exceededSolution:
  • Reduce concurrency value
  • Check network connectivity
  • Use --pkg-url to specify alternative endpoint
  • Verify firewall rules allow outbound connections
Error: get registry: registry not foundSolution:
  • Verify registry names in source system
  • Check registry identifiers are correct
  • Ensure destination registries exist in Harness
  • Use hc registry list to view available registries
Error: artifact already existsSolution:
  • Use --overwrite flag to replace existing artifacts
  • Or add overwrite: true to config file
  • Consider using different destination registry

Performance Issues

Symptoms: Very slow transfer speedsSolutions:
  • Increase concurrency value (try 5, 10, or 20)
  • Check source registry performance
  • Verify network bandwidth
  • Run migration from server with better connectivity
Symptoms: Process consuming too much RAMSolutions:
  • Reduce concurrency value
  • Process registries one at a time
  • Split large migrations into smaller batches

Best Practices

Always run with --dry-run flag first to:
  • Validate configuration
  • Preview what will be migrated
  • Estimate migration size and duration
  • Identify potential issues early
Store credentials in environment variables:
export SOURCE_PASSWORD="your-jfrog-api-key"
export HARNESS_API_KEY="your-harness-token"
hc registry migrate -c config.yaml
Begin with concurrency: 1 or concurrency: 5, then increase based on:
  • Source registry capacity
  • Network bandwidth
  • Migration performance
During migration:
  • Watch source registry load
  • Monitor network traffic
  • Check error logs
  • Be prepared to pause if issues occur
For migrations with thousands of artifacts:
  • Split into multiple configuration files
  • Migrate during off-peak hours
  • Allow ample time for completion
  • Have rollback plan ready

Examples

Migrate Docker Images from JFrog

version: 1.0.0
concurrency: 10

source:
  endpoint: https://jfrog.company.com/artifactory
  type: JFROG
  credentials:
    username: ${JFROG_USER}
    password: ${JFROG_TOKEN}

destination:
  endpoint: https://pkg.harness.io
  type: HAR
  credentials:
    username: ${HARNESS_USER}
    password: ${HARNESS_KEY}

mappings:
  - artifactType: DOCKER
    sourceRegistry: docker-prod
    destinationRegistry: production/docker
    sourcePackageHostname: company.jfrog.io

Migrate Maven Artifacts from Nexus

version: 1.0.0
concurrency: 5

source:
  endpoint: https://nexus.company.com
  type: NEXUS
  credentials:
    username: ${NEXUS_USER}
    password: ${NEXUS_PASSWORD}

destination:
  endpoint: https://pkg.harness.io
  type: HAR
  credentials:
    username: ${HARNESS_USER}
    password: ${HARNESS_KEY}

mappings:
  - artifactType: MAVEN
    sourceRegistry: maven-releases
    destinationRegistry: prod/maven

Multi-Type Migration

version: 1.0.0
concurrency: 8
overwrite: false

source:
  endpoint: https://artifactory.example.com
  type: JFROG
  credentials:
    username: ${SOURCE_USER}
    password: ${SOURCE_TOKEN}

destination:
  endpoint: https://pkg.harness.io
  type: HAR
  credentials:
    username: ${HARNESS_USER}
    password: ${HARNESS_KEY}

mappings:
  - artifactType: DOCKER
    sourceRegistry: docker-local
    destinationRegistry: company/docker

  - artifactType: HELM
    sourceRegistry: helm-local
    destinationRegistry: company/helm

  - artifactType: NPM
    sourceRegistry: npm-local
    destinationRegistry: company/npm

  - artifactType: PYTHON
    sourceRegistry: pypi-local
    destinationRegistry: company/python

Next Steps

Artifact Management

Learn how to manage artifacts after migration

Registry Commands

View all registry management commands

Build docs developers (and LLMs) love