Phase 3: Artifact migration
Importing Docker images
Container images do not need to be exported to a folder. A registry-to-registry tool such as crane copies an image directly from your existing registry into Cloudsmith, preserving its digest and every platform in a multi-architecture image. This is faster than pulling and pushing through a Docker daemon, needs no local disk, and works for OCI artifacts such as Helm charts too. Because of that, migrate container images first: they are usually the bulk of the bytes and the least work.
How it works
Before you begin
- Create the target repository.
- Install crane.
- Have credentials for the source registry and for Cloudsmith. Authenticate to Cloudsmith with your account name and an API key as the password.
- Know the Cloudsmith image path:
docker.cloudsmith.io/OWNER/REPOSITORY/IMAGE:TAG.
Note
If you use a custom domain for Docker, replace
docker.cloudsmith.iowith it throughout. Set the domain up before the migration so images are pushed to their final address.
Copy one image
Log in to both registries, then copy. Multi-architecture images are copied whole, with every platform:
crane auth login registry.example.com --username source-user --password-stdin
crane auth login docker.cloudsmith.io --username my-user --password-stdin
crane copy \
registry.example.com/team/my-image:1.0.0 \
docker.cloudsmith.io/my-org/my-repo/my-image:1.0.0crane also reads credentials from an existing docker login. See the
crane copy reference
for the full option list. If you already use skopeo,
skopeo copy --all docker://SOURCE docker://DESTINATION does the same job; without --all it copies only the
platform matching the machine it runs on.
Copy a whole repository
crane ls lists the tags of an image, so a loop over it migrates every version. Wrap it in a second loop over
your image names to move a whole registry, logging any failure so the run can be repeated.
for tag in $(crane ls registry.example.com/team/my-image); do
crane copy "registry.example.com/team/my-image:$tag" "docker.cloudsmith.io/my-org/my-repo/my-image:$tag" ||
echo "my-image:$tag" >> copy-failures.log
doneWhere to get the image names depends on the source. crane catalog registry.example.com works for Nexus and
most registries. Artifactory does not serve a top-level catalog; list each Docker repository through its own
endpoint instead:
jf rt curl -s -XGET /api/docker/docker-local/v2/_catalogAlternatives
Docker CLI. If you cannot install crane, pull, retag, and push each image through the Docker daemon. This copies only the platform matching the machine you run it on.
docker pull registry.example.com/team/my-image:1.0.0
docker tag registry.example.com/team/my-image:1.0.0 docker.cloudsmith.io/my-org/my-repo/my-image:1.0.0
docker push docker.cloudsmith.io/my-org/my-repo/my-image:1.0.0Air-gapped export. Where the source registry cannot reach Cloudsmith and no machine can see both, save
images to tarballs with docker save and upload them with the Cloudsmith CLI:
docker save my-image:1.0.0 -o my-image-1.0.0.tar
cloudsmith push docker my-org/my-repo my-image-1.0.0.tarImportant
Images uploaded as tarballs get a different digest from the same image pushed through the registry protocol, so anything that pins by digest must be updated. Prefer a registry-to-registry copy where the network allows it.
Verify
Copied images keep their digests, so compare them directly:
crane digest registry.example.com/team/my-image:1.0.0
crane digest docker.cloudsmith.io/my-org/my-repo/my-image:1.0.0Then confirm nothing is stuck synchronizing:
cloudsmith list packages my-org/my-repo -q 'format:docker status:failed'Next steps
Point Docker clients and CI at the new registry with the instructions in Docker registry, and see Running a bulk import for verifying a large import.