JFrog Artifactory to CloudRepo Migration Guide

Serving developers since 2016 Founder-run, no venture capital MFA, SSO and audit log on every plan

Every feature on every plan, with unlimited users. 14 days free. No credit card required.

Start free trial

This guide moves you from Artifactory to CloudRepo: what to copy, the one command for Maven, and how to repoint your builds.

Why Teams Are Escaping JFrog Artifactory

Cost savings are only part of it. Teams move to escape a pricing model that punishes growth and creates budget uncertainty.

The Hidden Costs of JFrog Artifactory

JFrog’s pricing model includes multiple cost vectors that compound quickly:

  • Consumption fees - storage and transfer are billed together, per GB above the included amount
  • Storage overage charges when you exceed limits
  • Infrastructure costs for self-hosted deployments

CloudRepo’s Transparent Pricing Model

CloudRepo eliminates pricing complexity with a simple, predictable model:

  • Storage-based pricing only - no per-user fees
  • No minimum commitments - pay for what you use
  • Support included in all plans
  • Transparent calculator - know your costs upfront

Cost Analysis: Calculate Your Savings

CloudRepo’s Business plan is a flat $999/month billed annually, with no per-user fees and support included. JFrog Artifactory prices on consumption instead: a base license plus per-GB egress and storage overages that climb as your CI/CD pipelines grow.

Because JFrog’s total depends on your storage and transfer profile, there’s no single “typical” bill. The more you build, the more you pay. Model your own usage against JFrog’s published rates with our pricing calculator to see your specific savings.

Pre-Migration Assessment

Before beginning your migration, take stock of your Artifactory environment. Every command in this guide only reads from Artifactory: nothing here changes its configuration, its repositories or its users, so Artifactory keeps serving your builds, unchanged, for as long as you need it.

1. Audit Current Artifactory Usage

Use an Artifactory access token that can read every repository you plan to move. The commands read it from your shell, so it is never typed on a command line or kept in your shell history.

Terminal window
# Your Artifactory's base address, ending in /artifactory
export ARTIFACTORY_URL="https://artifactory.example.com/artifactory"
# Paste the access token when asked; it is not shown on screen
read -rs -p "Artifactory access token: " ARTIFACTORY_ACCESS_TOKEN && echo
export ARTIFACTORY_ACCESS_TOKEN
# A read-only call to Artifactory. curl reads the Authorization header from a file
# descriptor (-H @file, curl 7.55 or later)
artifactory_get() {
curl --fail --silent --show-error \
-H @<(printf 'Authorization: Bearer %s\n' "$ARTIFACTORY_ACCESS_TOKEN") "$@"
}
# List every repository, with its type and package type
artifactory_get "$ARTIFACTORY_URL/api/repositories" |
jq -r '.[] | "\(.key)\t\(.type)\t\(.packageType)"'
# Storage used per repository (this one needs an admin token)
artifactory_get "$ARTIFACTORY_URL/api/storageinfo" |
jq -r '.repositoriesSummaryList[] | "\(.repoKey)\t\(.usedSpace)"'

2. Document Repository Structure

Write down what you have and where each repository goes. A short inventory is enough:

repository-inventory.yaml
repositories:
maven:
- name: libs-release
type: local
size: 850GB
- name: libs-snapshot
type: local
size: 420GB
- name: maven-central
type: remote
url: https://repo1.maven.org/maven2
docker:
- name: docker-local
type: local
size: 1.2TB
npm:
- name: npm-local
type: local
size: 180GB
pypi:
- name: pypi-local
type: local
size: 40GB

3. Export Critical Configurations

Keep a copy of each repository’s settings for reference while you set up CloudRepo. These are reads too.

Terminal window
mkdir -p configs
# One JSON file per repository (artifactory_get is the function from section 1)
for repo in $(artifactory_get "$ARTIFACTORY_URL/api/repositories" | jq -r '.[].key'); do
artifactory_get "$ARTIFACTORY_URL/api/repositories/$repo" > "configs/$repo.json"
done
# The virtual repositories, which Step 6 turns into group repositories
artifactory_get "$ARTIFACTORY_URL/api/repositories?type=virtual" > configs/virtual-repos.json

Note who can read and who can deploy to each repository. You add those people in CloudRepo in Step 7.

4. Analyze Integration Points

Document all systems integrated with Artifactory:

  • CI/CD Pipelines: Jenkins, GitHub Actions, GitLab CI
  • Build Tools: Maven, Gradle, npm, Docker
  • Deployment Systems: Kubernetes, Terraform, Ansible
  • Monitoring: Datadog, New Relic, Prometheus
  • Security Scanners: Snyk, SonarQube, Twistlock

Step-by-Step Migration Process

Step 1: Create Your CloudRepo Account and Repositories

  1. Sign up for CloudRepo: Start free trial. 14 days free. No credit card required.
  2. Choose appropriate plan based on your storage needs
  3. Create your repositories in the admin portal, as below. They come before the token in Step 2, because a token reaches only the repositories you select when you create it.

Create equivalent repositories in CloudRepo for each Artifactory repository:

Repository Type Mapping

Artifactory Type CloudRepo Equivalent Notes
Local Repository Repository Direct mapping
Remote Repository Proxy Repository Caching proxy for external Maven/Python repos
Virtual Repository Repository Group (Maven, Docker, PyPI and npm) Aggregates multiple repositories
Generic Repository Maven Repository Raw files are served over HTTP from it

Create each repository in the CloudRepo admin portal. This guide uses these names; use your own, and map them as Step 4 shows:

  • libs-release and libs-snapshot: Maven repositories, for your own releases and snapshots
  • maven-central: a Maven proxy repository of Maven Central
  • docker-local: a Docker repository
  • npm-local and npm-proxy: an npm repository for your own packages and an npm proxy repository of the public registry
  • pypi-local and pypi-proxy: a Python repository for your own packages and a Python proxy repository of PyPI

The JFrog migration guide in our docs walks through creating them and adding the people who need access.

Step 2: Create a Repository Token

Create a repository token in the admin portal with Download and publish packages access, and select every repository you created in Step 1, the proxy repositories (maven-central, npm-proxy and pypi-proxy) included. That choice is permanent: a repository you create later needs a new token. Builds, the migration tool and every command below authenticate with it.

Your repositories live at https://your-org.mycloudrepo.io/repositories/<repository>, where your-org is your organization’s id. The username that goes with the token is the email address of the CloudRepo account the token belongs to; any other username is refused.

Terminal window
# The email address of the CloudRepo account the token belongs to
export CLOUDREPO_USER="you@example.com"
# Paste the repository token when asked; it is not shown on screen
read -rs -p "CloudRepo repository token: " CLOUDREPO_API_TOKEN && echo
export CLOUDREPO_API_TOKEN

Step 3: Export Artifacts from Artifactory

Maven moves straight from Artifactory to CloudRepo in Step 4, and Docker images move with docker pull and docker push (Repository Type Migration Guide, below), so neither needs an export. The npm and Python packages you published yourself do: copy them down with the JFrog CLI, jf, which takes the token from the environment you set up in the assessment.

#!/bin/bash
# export_from_artifactory.sh: copies your npm and Python packages down from Artifactory, for the
# NPM/PyPI Repository Migration section below to publish. It only reads from Artifactory.
# It stops at the first command that fails, so a failed download never passes for an empty export.
set -eo pipefail
if ! command -v jf > /dev/null; then
echo "Install the JFrog CLI (jf) first."
exit 1
fi
REPOS=(
"npm-local"
"pypi-local"
)
for repo in "${REPOS[@]}"; do
echo "Exporting $repo..."
mkdir -p exports/$repo
# Download every file of the repository, keeping its layout
jf rt download "$repo/*" "exports/$repo/" \
--url="$ARTIFACTORY_URL" \
--access-token="$ARTIFACTORY_ACCESS_TOKEN" \
--flat=false \
--threads=10 \
--retries=3
echo "Exported $(find exports/$repo -type f | wc -l) files from $repo"
done

Step 4: Move Maven Repositories with cloudrepo-migrate

For local Maven repositories, one command, cloudrepo-migrate artifactory, moves them into CloudRepo and reads each file back to check it. The Artifactory migration guide has the steps.

More formats are coming to the migration tool. Until then, Docker images, npm packages and Python packages move by hand, as the Repository Type Migration Guide below shows.

Install it with pipx (or with pip, in a virtual environment). It needs Python 3.8 or later.

Terminal window
pipx install cloudrepo-migrate
cloudrepo-migrate --version
# The tool takes both credentials from the environment: ARTIFACTORY_ACCESS_TOKEN, set in the assessment, and CLOUDREPO_TOKEN
export CLOUDREPO_TOKEN="$CLOUDREPO_API_TOKEN"
# First, a dry run: it lists what would move and uploads nothing
cloudrepo-migrate artifactory \
--artifactory-url "$ARTIFACTORY_URL" \
--org your-org \
--repo libs-release \
--repo libs-snapshot \
--dry-run
# Then the same command without --dry-run, keeping the report
cloudrepo-migrate artifactory \
--artifactory-url "$ARTIFACTORY_URL" \
--org your-org \
--repo libs-release \
--repo libs-snapshot \
--report-json report.json

Each --repo names one Artifactory repository. When its CloudRepo repository has another name, write both: --repo libs-release-local=libs-release.

Step 5: Update Build Configurations

Maven Configuration

Update settings.xml to point to CloudRepo. For a refresher on how Maven repositories work, including settings.xml configuration, see our comprehensive guide.

Maven sends a credential only to a repository or mirror whose <id> has a <server> entry, so every id below has one. The credentials come from the environment you set in Step 2, so the file holds no token.

~/.m2/settings.xml
<settings>
<servers>
<server>
<id>cloudrepo-central</id>
<username>${env.CLOUDREPO_USER}</username>
<password>${env.CLOUDREPO_API_TOKEN}</password>
</server>
<server>
<id>cloudrepo-releases</id>
<username>${env.CLOUDREPO_USER}</username>
<password>${env.CLOUDREPO_API_TOKEN}</password>
</server>
<server>
<id>cloudrepo-snapshots</id>
<username>${env.CLOUDREPO_USER}</username>
<password>${env.CLOUDREPO_API_TOKEN}</password>
</server>
</servers>
<mirrors>
<mirror>
<id>cloudrepo-central</id>
<mirrorOf>central</mirrorOf>
<url>https://your-org.mycloudrepo.io/repositories/maven-central</url>
</mirror>
</mirrors>
<profiles>
<profile>
<id>cloudrepo</id>
<repositories>
<repository>
<id>cloudrepo-releases</id>
<url>https://your-org.mycloudrepo.io/repositories/libs-release</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>cloudrepo-snapshots</id>
<url>https://your-org.mycloudrepo.io/repositories/libs-snapshot</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>cloudrepo</activeProfile>
</activeProfiles>
</settings>

mvn deploy publishes to the repositories your pom.xml names, with the same ids:

pom.xml
<distributionManagement>
<repository>
<id>cloudrepo-releases</id>
<url>https://your-org.mycloudrepo.io/repositories/libs-release</url>
</repository>
<snapshotRepository>
<id>cloudrepo-snapshots</id>
<url>https://your-org.mycloudrepo.io/repositories/libs-snapshot</url>
</snapshotRepository>
</distributionManagement>

Gradle Configuration

Gradle reads an environment variable named ORG_GRADLE_PROJECT_ plus a property name as that project property, so the credential stays out of every file:

Terminal window
export ORG_GRADLE_PROJECT_cloudrepoUsername="$CLOUDREPO_USER"
export ORG_GRADLE_PROJECT_cloudrepoToken="$CLOUDREPO_API_TOKEN"
build.gradle
plugins {
id 'java'
id 'maven-publish'
}
repositories {
maven {
url = 'https://your-org.mycloudrepo.io/repositories/libs-release'
credentials {
username = findProperty('cloudrepoUsername')
password = findProperty('cloudrepoToken')
}
}
maven {
url = 'https://your-org.mycloudrepo.io/repositories/libs-snapshot'
credentials {
username = findProperty('cloudrepoUsername')
password = findProperty('cloudrepoToken')
}
}
maven {
url = 'https://your-org.mycloudrepo.io/repositories/maven-central'
credentials {
username = findProperty('cloudrepoUsername')
password = findProperty('cloudrepoToken')
}
}
}
publishing {
publications {
maven(MavenPublication) {
from components.java
}
}
repositories {
maven {
name = 'cloudrepo'
def releases = 'https://your-org.mycloudrepo.io/repositories/libs-release'
def snapshots = 'https://your-org.mycloudrepo.io/repositories/libs-snapshot'
url = version.toString().endsWith('SNAPSHOT') ? snapshots : releases
credentials {
username = findProperty('cloudrepoUsername')
password = findProperty('cloudrepoToken')
}
}
}
}

The maven-central entry sends your public dependencies through your CloudRepo proxy repository, the one the <mirror> in settings.xml uses.

Step 6: Migrate Virtual Repositories

Create Repository Groups in CloudRepo to replace your Artifactory Maven, Docker, PyPI and npm Virtual Repositories. PyPI and npm groups are in early access. An npm virtual repository can move as an npm group, or as a hosted repository and a proxy repository, as below.

configs/virtual-repos.json, from the assessment, lists your virtual repositories. For each Maven, Docker, PyPI or npm one, create a group repository in the admin portal with the same members, for example libs-release, libs-snapshot and maven-central. A group holds other repositories, not other groups. Builds read through the group’s one address and deploy to the repository itself, because a group takes no uploads.

Step 7: Configure Authentication and Permissions

Add each person who needs access in the admin portal, as Read Only or Read/Write (Challenge 2, below, maps Artifactory’s permissions onto these). The portal takes each person’s email address and a starting password: give it to them directly, never through a script or a file.

Give each CI system its own repository token, scoped to the repositories it reads or publishes, and keep it in that system’s secret store. Step 8 shows where each one reads it.

Step 8: Update CI/CD Pipelines

Commit the settings.xml from Step 5 to each repository as ci-settings.xml. It holds no credential, only the ${env.CLOUDREPO_USER} and ${env.CLOUDREPO_API_TOKEN} references, which each pipeline below fills from its secret store.

Jenkins Migration

Store the token account’s email address and the repository token as a Jenkins Username with password credential, here with the id cloudrepo-repository-token:

// Jenkinsfile
pipeline {
agent any
stages {
stage('Build and deploy') {
steps {
withCredentials([usernamePassword(credentialsId: 'cloudrepo-repository-token',
usernameVariable: 'CLOUDREPO_USER',
passwordVariable: 'CLOUDREPO_API_TOKEN')]) {
sh 'mvn -B -s ci-settings.xml deploy'
}
}
}
}
}

GitHub Actions Migration

Add CLOUDREPO_USER and CLOUDREPO_API_TOKEN as repository secrets:

.github/workflows/build.yml
name: Build
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '21'
- name: Build and deploy
run: mvn -B -s ci-settings.xml deploy
env:
CLOUDREPO_USER: ${{ secrets.CLOUDREPO_USER }}
CLOUDREPO_API_TOKEN: ${{ secrets.CLOUDREPO_API_TOKEN }}

GitLab CI Migration

Add CLOUDREPO_USER and CLOUDREPO_API_TOKEN as masked CI/CD variables in the project’s settings. GitLab gives every job its variables as environment variables:

.gitlab-ci.yml
stages:
- build
build:
stage: build
image: maven:3.9-eclipse-temurin-21
script:
- mvn -B -s ci-settings.xml deploy

For npm and Python jobs, keep the same two secrets: npm reads ${CLOUDREPO_API_TOKEN} from the environment when it appears in an .npmrc (see npm), and pip reads the login for the host from a ~/.netrc you write from the secret store (see pip).

Step 9: Test and Validate

Build each project against CloudRepo alone. Every command below exits with an error when CloudRepo refuses or lacks what it asks for, so the script stops at the first problem instead of reporting a false pass.

validate_migration.sh
#!/bin/bash
set -e
# Maven: an empty local repository makes Maven download every dependency again, through CloudRepo
mvn -B -U -Dmaven.repo.local="$(mktemp -d)" verify
# npm: the versions of one of your own packages, read from the hosted repository
npm view @your-scope/your-package versions --registry https://your-org.mycloudrepo.io/repositories/npm-local/
# Python: one of your own packages, downloaded from the hosted repository's index
pip download --no-deps -d "$(mktemp -d)" \
--index-url https://your-org.mycloudrepo.io/repositories/pypi-local/simple/ your-package
# Docker: one migrated image
docker pull your-org.mycloudrepo.io/repositories/docker-local/myimage:1.0.0
echo "Every check passed"

The report.json from Step 4 lists each Maven file the tool moved and checked.

Step 10: Decommission Artifactory

Keep Artifactory running, unchanged, until every build and every deploy has run against CloudRepo through a full release cycle. Then retire it on your own schedule.

Repoint clients rather than hostnames. CloudRepo does not serve Artifactory’s /artifactory/<repository>/ paths, so pointing your old Artifactory hostname at CloudRepo would break every client still configured with an old URL. Every client moves to its your-org.mycloudrepo.io/repositories/ address, as Step 5 and Step 8 show. If you want a branded hostname for CloudRepo, such as repo.example.com, contact support, who set custom domains up.

CloudRepo and JFrog Artifactory, side by side

CloudRepo and JFrog Artifactory, side by side
Question CloudRepo Essentials JFrog Artifactory Cloud Pro
Included each month 10 GB storage and 250 GB transfer 25 GB, then $1.25/GB storage and transfer counted together [1]
Users Unlimited, on every plan Typically up to 50 users how JFrog sizes Pro [1]
Support Human support, on every plan Community support: public documentation, a knowledge base and Stack Overflow [2]

Every feature on every plan

Start free trial Or compare your JFrog quote with ours

14 days free. No credit card required.

Sources (2): each vendor's own pages, read 2026-10-06 to 2026-10-07. Prices as each vendor listed them on the date shown.
  1. JFrog pricing, read (archived)
  2. JFrog pricing, read (archived) Community Support - Available for Free solutions and Pro subscriptions - JFrog maintains public documentation, knowledge base, and engages in conversations on Stack Overflow.

Repository Type Migration Guide

Docker Registry Migration

CloudRepo serves the Docker Registry HTTP API V2, so migrating images is a re-tag and a push. Note the shape difference: docker login takes the host on its own, while the image reference carries a literal repositories/ segment.

Terminal window
printf '%s' "$CLOUDREPO_API_TOKEN" | docker login your-org.mycloudrepo.io --username "$CLOUDREPO_USER" --password-stdin
docker pull yourcompany.jfrog.io/docker-local/myimage:1.0.0
docker tag yourcompany.jfrog.io/docker-local/myimage:1.0.0 \
your-org.mycloudrepo.io/repositories/docker-local/myimage:1.0.0
docker push your-org.mycloudrepo.io/repositories/docker-local/myimage:1.0.0

Authenticate with a Generic repository token from the admin portal rather than a portal password. An organization owner’s password is refused at the registry. Helm charts move the same way, since a CloudRepo Docker repository is an OCI registry. Without a credential helper configured, Docker keeps the login in ~/.docker/config.json unencrypted, so set one up first (Docker Desktop does this for you).

NPM/PyPI Repository Migration

Group repositories are available for Maven, Docker, PyPI and npm. An Artifactory virtual repository for PyPI becomes a PyPI group, which is in early access. Its members are your hosted repository and a proxy repository of PyPI, and pip points at the group’s one index URL, as the Python guide shows. An Artifactory virtual repository for npm can become an npm group, also in early access, with your hosted repository and a proxy repository of the public npm registry as members, as the npm guide shows. The steps below keep the two repositories apart instead, each at its own address: a hosted repository for your own packages and a proxy repository for the public ones. A repository’s address is https://<organization>.mycloudrepo.io/repositories/<repository>/, and pip’s index URL adds simple/ to it. npm sends the packages of your own scope to the hosted repository and everything else to the proxy repository. The docs have the full steps for npm and pip.

Run this from the directory that holds the exports/ folder from Step 3. If a package’s package.json sets publishConfig, check that package with npm publish --dry-run first: it prints the registry it would publish to.

migrate_npm_packages.sh
#!/bin/bash
# Configure npm for CloudRepo
npm config set registry https://your-org.mycloudrepo.io/repositories/npm-proxy/
npm config set @your-scope:registry https://your-org.mycloudrepo.io/repositories/npm-local/
# npm sends a credential only to the registry its own //host/path/: line names, so each registry above gets one
npm config set //your-org.mycloudrepo.io/repositories/npm-proxy/:_authToken=$CLOUDREPO_API_TOKEN
npm config set //your-org.mycloudrepo.io/repositories/npm-local/:_authToken=$CLOUDREPO_API_TOKEN
# Publish the npm packages exported from Artifactory
cd exports/npm-local
for package in $(find . -name "*.tgz"); do
echo "Publishing $package to CloudRepo"
npm publish $package --registry https://your-org.mycloudrepo.io/repositories/npm-local/
done
# Python/PyPI migration
# Point pip at your PyPI group's one index URL; the PyPI groups section of the Python guide in the docs shows how.
# The index URL carries no credential: when CloudRepo asks pip to sign in, pip asks you for the username (the token
# account's email address) and the token, and with the keyring package installed it offers to keep them in your keyring.
# Upload Python packages; twine reads its credential from TWINE_USERNAME and TWINE_PASSWORD
export TWINE_USERNAME="$CLOUDREPO_USER"
export TWINE_PASSWORD="$CLOUDREPO_API_TOKEN"
cd ../../exports/pypi-local
for package in $(find . -name "*.whl" -o -name "*.tar.gz"); do
twine upload \
--repository-url https://your-org.mycloudrepo.io/repositories/pypi-local/ \
$package
done

Feature Comparison

Understanding what changes between Artifactory and CloudRepo:

What You’ll Gain

Feature CloudRepo Advantage
Cost Flat pricing, every feature on every plan
Pricing Model Simple, transparent, no hidden fees
Maintenance Zero - fully managed
Support Included in all plans
Performance Managed cloud infrastructure
Security AES-256 encryption at rest, TLS 1.2+ in transit

Feature Parity

Feature Artifactory CloudRepo Notes
Maven/Gradle ✓ ✓ Full support
NPM ✓ ✓ Full support
Docker ✓ ✓ Registry HTTP API V2
PyPI ✓ ✓ Full support
NuGet ✓ ✗ Not currently planned
REST API ✓ ✓ Different endpoints
Virtual Repos ✓ ✓ Called Repository Groups (Maven, Docker, PyPI and npm)
Access Tokens ✓ ✓ Full support
Webhooks ✓ ✓ Full support
Replication ✓ ✗ Not currently planned
Xray Integration ✓ ✗ Use alternative scanners

Workarounds for Missing Features

JFrog Xray Alternative: Integrate with Snyk, Sonatype Nexus IQ, or GitHub Security Scanning. For example, as GitHub Actions steps:

# Example: Snyk in a GitHub Actions job
- name: Security scan
run: |
snyk test --all-projects
snyk monitor --all-projects
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}

Common Migration Challenges and Solutions

Challenge 1: Maven Snapshots with Timestamps

Problem: Builds that depend on a -SNAPSHOT version must keep resolving to the same timestamped files after the move.

Solution: Nothing to configure. cloudrepo-migrate copies the files of a local Maven repository with their maven-metadata.xml files, so Maven resolves each snapshot version from CloudRepo as it did from Artifactory.

Challenge 2: Permission Model Differences

Problem: Artifactory’s fine-grained permissions don’t map 1:1 to CloudRepo

Solution: Map each Artifactory permission onto a scoped credential:

  • CI jobs that deploy: a repository token with write scope, limited to the repositories they publish to
  • CI jobs that only download: a read-only repository token
  • People who deploy: Read/Write users; people who only download: Read Only users
  • People who administer Artifactory: the administrator permissions they need (billing, repositories, software distribution, users, webhooks)

Each repository token has the expiry chosen when it is created: 90, 180 or 365 days later, or a date you pick. Only a personal token can be set to never expire. An organization token always expires, at most 1 year after you create it. Give CI tokens a date and rotate them before it. CloudRepo has no named roles or user groups.

Challenge 3: Build Cache Dependencies

Problem: Builds fail due to missing cached dependencies

Solution: Nothing to upload. A proxy repository fills itself from its upstream, so a public dependency your Artifactory remote repository had cached comes through maven-central, npm-proxy or pypi-proxy the first time a build asks for it.

Post-Migration Optimization

Performance Tuning

CloudRepo has no caching or region options for downloads: artifacts are served from our US region. Tune your builds instead:

  • Enable HTTP/2 and connection pooling in CI/CD
  • Use shallow cloning for large repositories
  • Enable Snapshot Cleanup on Maven repositories that collect many snapshots

Security Best Practices

Implement security measures in CloudRepo:

CloudRepo provides AES-256 encryption at rest and TLS 1.2+ in transit between your clients and CloudRepo for all artifacts. Access is managed through CloudRepo’s access token system. For vulnerability scanning, integrate your CI/CD pipeline with tools like Snyk or GitHub Security Scanning to scan artifacts before or after upload.

Risk Mitigation Strategies

Parallel Run Strategy

Run both systems side by side during the transition. Move one project at a time: repoint its build at CloudRepo (Step 5), run it green, then deploy its new releases to CloudRepo. Artifactory keeps serving every project you have not moved yet.

Because no step in this guide changes your Artifactory, going back is a matter of pointing a build at its old Artifactory address again.

Conclusion

Migrating from JFrog Artifactory to CloudRepo is one of the most impactful decisions you can make for your organization’s bottom line and developer productivity. With simple, published pricing and a dramatically simplified operational model, the payoff is immediate.

Key Takeaways: - Flat pricing, every feature on every plan - Migration can be completed in days, not weeks

  • Zero infrastructure overhead means your team focuses on shipping code - Support included in all plans - no expensive contracts

Need a hand planning or running the migration? Contact our team.

Next Steps

  1. Calculate Your Savings: Use our pricing calculator to see your exact savings
  2. Start free trial: 14 days free. No credit card required.
  3. Get Migration Support: Contact our team for migration assistance and scripts

Ready to escape JFrog’s complex pricing and move to simple, published pricing? Start free trial and join the teams who’ve made the switch to CloudRepo. 14 days free. No credit card required.


For step-by-step instructions, follow the migration process outlined above. Our team is ready to help with any questions.

Every feature on every plan, with unlimited users

14 days free. No credit card required.

Chris Shellenbarger, founder of CloudRepo

Founder-run since 2016, with no venture capital. A real person answers within one business day. Usually it's me.

Chris, founder of CloudRepo