Migrating from Sonatype Nexus
This is the field guide for moving an existing Sonatype Nexus installation to OrbitalReg. It covers Nexus Repository OSS and Nexus Repository Pro on every supported format. The procedures have been validated against installs ranging from 5 GB hobby setups to 14 TB enterprise deployments with 100+ repositories and 30 million artifacts.
Reading this for the first time?
Skip to Pick your strategy if you already know your risk profile. Read What stays the same if you are evaluating before committing.
What stays the same
For your developers, almost nothing visible changes:
- Push and pull commands stay format-native (
mvn deploy,npm publish,docker push,helm push, etc.) - Authentication mechanisms stay supported — basic auth, bearer tokens, Docker login, OAuth-style PATs
- CI pipeline scripts only need their registry URL updated
- Existing artifact identifiers (group:artifact:version, image tags) carry through unchanged
For your operations team, the big-picture shape changes:
- One binary instead of one JVM application server + format-specific database tables
- One Postgres database instead of an embedded H2 / OrientDB
- One S3-compatible bucket instead of file-system blob-store volumes
- Air-gapped operation as the default, rather than a configuration flag set after install
What changes
| Concept | Nexus | OrbitalReg |
|---|---|---|
| Database | Embedded H2 / OrientDB / Postgres | Postgres (managed externally) |
| Blob storage | File-system volume per blob-store | S3-compatible bucket (MinIO / native S3) |
| Format coverage | ~20 formats | 40+ formats, all in one binary |
| Security scanning | Nexus IQ Server (separate licence) | Trivy + Grype, included |
| Signature verification | Nexus Firewall (separate licence) | Sigstore + X.509 + OpenPGP, included |
| OIDC / SSO | Pro tier | All tiers |
| Pricing model | Per-instance Pro licence | Per-deployment annual flat-rate |
| Air-gapped operation | Manual configuration | Default-on |
Pre-migration audit
The first step is always inventory. The orbital migrate plan command walks the entire Nexus instance, catalogues what it finds, and writes a plan file the apply step consumes.
orbital migrate plan \
--source nexus \
--endpoint https://nexus.example.com \
--token "$NEXUS_TOKEN" \
--output migration-plan.jsonWhat gets discovered:
- Repositories — name, format, type (hosted / proxy / group), blob-store, write policy, deployment policy
- Artifacts — counted per repository, sha256 sampled for size estimation
- Permissions — Nexus roles, privileges, content selectors, LDAP / SAML mappings
- Webhooks — global and per-repository, with target URLs and event filters
- Cleanup tasks — Nexus's scheduled-task system that translates to OrbitalReg retention policies
- Capabilities — Nexus capabilities (e.g.
OutreachManagement) that have no OrbitalReg equivalent are flagged so the operator knows what is intentionally not migrated
The output of plan is a JSON file. Read it before running apply. It is the contract between the audit and the migration.
Format coverage
OrbitalReg supports every format Nexus does, plus more. The format-by-format mapping:
| Nexus format | OrbitalReg adapter | Notes |
|---|---|---|
| Maven 2 | maven | Snapshot vs release semantics preserved. Layout handlers (default / strict) carry through. |
| npm | npm | Scoped packages map to OrbitalReg's project namespace. Integrity hashes preserved. |
| Docker | docker | Manifests, layers, tags, multi-arch index.json, signatures (cosign / Notation). |
| NuGet | nuget | NuGet v3 protocol. Semantic Versioning + prerelease tags preserved. |
| RubyGems | rubygems | gem files + spec metadata. Dependency graph preserved. |
| PyPI | pypi | wheels + sdists. Per-project namespace mapping. |
| Helm | helm | index.yaml + .tgz tarballs + signed Chart.yaml provenance. |
| Conan | conan | Both Conan 1.x and 2.x supported. Lockfiles preserved. |
| Raw | generic | Pass-through with sha256 verification. Path-prefix routing. |
| apt | apt | Debian repository metadata + signatures. Distribution + component preserved. |
| yum | yum | RPM metadata + repodata.xml + GPG signatures. |
| CocoaPods | cocoapods | Podspec + .tar.gz preserved. |
| Bower | deprecated | Bower is deprecated upstream — we recommend rebuilding consumers as npm. |
Permission model translation
Nexus uses a roles + privileges + content-selectors model that OrbitalReg re-shapes into roles + scoped tokens + project memberships.
The translator maps automatically where the semantics line up:
| Nexus | OrbitalReg |
|---|---|
| Built-in admin role | system_admin role |
Custom role with nx-repository-admin-*-*-* privilege | Project admin role |
Custom role with nx-repository-view-*-*-read | Project viewer role |
| Content selectors filtering paths | Project-scoped tokens with format-and-path scopes |
| LDAP user-source | LDAP / SAML / OIDC connector (configured separately on OrbitalReg side) |
The translator generates a report showing every Nexus role and its mapped OrbitalReg equivalent. Review it before applying — content-selector edge cases occasionally need manual intervention (e.g. a privilege that includes a wildcard plus a regex).
Webhook + automation translation
Nexus webhook events map to OrbitalReg webhook events:
| Nexus event | OrbitalReg event |
|---|---|
RepositoryCreated | repository.created |
RepositoryDeleted | repository.deleted |
RepositoryConfigurationUpdated | repository.updated |
assetEvent.uploaded | artifact.uploaded |
assetEvent.deleted | artifact.deleted |
assetEvent.updated | artifact.updated |
Cleanup tasks translate to OrbitalReg retention policies. A Nexus cleanup task that deletes "snapshot artifacts older than 30 days unless tagged keep-forever" becomes a retention policy with the identical predicate. The translator emits the policy YAML for review before applying.
Pick your strategy
Use the matrix below — the orbital migrate plan step also recommends one based on what it sees.
| Your situation | Recommended strategy |
|---|---|
| Registry under 500 GB, can take 4 h downtime | Big bang |
| Production-critical, zero downtime, registry under 5 TB | Blue-green parallel run |
| Huge registry (over 10 TB), distributed teams, can't agree on a cutover window | Lazy proxy |
| 14 TB, 30M artifacts (the big-customer profile) | Lazy proxy |
Big bang cutover
Schedule a maintenance window. Run the migration end-to-end. Flip DNS.
Day -7 Announce maintenance window to all developer teams
Day -3 Dry-run on a copy of production (or a representative sample)
Day 0 Window opens
00:00 Block writes to Nexus (read-only mode)
00:15 orbital migrate apply --plan ...
T+2h apply complete — orbital migrate verify --sample 1000
T+3h Flip DNS: registry.example.com → OrbitalReg
T+4h Spot-check pulls from each format
T+5h Window closes — all clear
Day +30 Decommission NexusTotal wall-clock time: 4-12 hours for registries up to 500 GB. Beyond that, prefer one of the other two strategies — the migration alone takes longer than typical maintenance-window budgets allow.
Blue-green parallel run
Run both registries simultaneously. Push twice. Pull from Nexus until verification passes, then flip DNS in a single change.
Day -14 Install OrbitalReg in parallel to Nexus
Configure both as push targets in CI (dual-publish)
Day -14 Run continuous import in the background — at full bandwidth
OrbitalReg catches up over days, not hours
Day -7 Cutover-readiness check — orbital migrate verify
Sample sizes: 5,000 sha256 comparisons per format
Day -3 Flip dev / staging DNS — soak for 72 h
Day 0 Flip production DNS in a single change
Nexus becomes read-only (still serving fallback)
Day +14 Stop dual-publish — push only to OrbitalReg
Day +30 Decommission NexusPush traffic during the dual-publish window goes to both registries, which doubles your CI write traffic. Plan bandwidth accordingly. Pull traffic stays on Nexus until DNS flip — there is zero developer impact until the flip itself.
Lazy proxy cutover
For very large registries (over 10 TB), the lazy-proxy strategy avoids the upfront full-import cost. OrbitalReg fronts Nexus as a remote-proxy. Pulls go through OrbitalReg, which fills its cache from Nexus on demand. Over weeks, the cache populates organically with the artifacts your team actually pulls.
Day -14 Install OrbitalReg in front of Nexus as a remote-proxy
Configure all repository entries as remote-mode pointing at Nexus
Day -14 Flip dev / staging DNS to OrbitalReg immediately
All pulls go through OrbitalReg → cache fills naturally
Day -14 Soak — monitor cache-hit rate, error-rate, latency
Day -7 Production DNS flip
OrbitalReg now in front of all reads
Writes still go to Nexus (will switch in next phase)
Day +0 Switch CI / push targets to OrbitalReg directly
New artifacts now land in OrbitalReg first, async-replicate to Nexus
Day +14 When cache-hit rate exceeds 95%, switch repositories from
remote-mode to local-mode (cached blobs become canonical)
Day +30 When all repositories are local-mode and re-verified,
decommission NexusThis strategy minimises risk — Nexus stays as a fallback for the entire migration window. If anything breaks, flip DNS back. No data was ever lost because OrbitalReg never deleted anything from Nexus.
For a 14 TB / 30M-artifact deployment, this is the recommended path. Total elapsed time: 30-60 days. Active work: ~10-20 hours of operator time spread over that period.
Cutover sequence (lazy proxy, detailed)
Here is the canonical lazy-proxy sequence with concrete commands.
Phase 1: Install OrbitalReg (Day -14)
# Helm install on your existing Kubernetes cluster
helm repo add orbitalreg https://charts.orbitalreg.com
helm install orbitalreg orbitalreg/orbitalreg \
--namespace orbitalreg --create-namespace \
--values your-values.yaml
# Wait for the API to become healthy
kubectl wait --for=condition=ready pod -l app=orbitalreg-api -n orbitalreg --timeout=300sPhase 2: Configure remote-proxy mode (Day -14)
# Run the migration plan in proxy-only mode
orbital migrate plan \
--source nexus \
--endpoint https://nexus.example.com \
--token "$NEXUS_TOKEN" \
--strategy lazy-proxy \
--output migration-plan.json
# Apply — this only registers repositories, no blob copy yet
orbital migrate apply --plan migration-plan.jsonAfter this, OrbitalReg has every Nexus repository configured as a remote-proxy. Pulls go through OrbitalReg, which fetches from Nexus on cache miss.
Phase 3: Soak on dev / staging (Day -14 to Day -7)
Switch dev and staging environments to point at OrbitalReg. Monitor:
- Cache-hit rate per repository (target: 60% within 7 days)
- p99 pull latency vs Nexus baseline (acceptable: same or better)
- Error rate (acceptable: under 0.1%)
The portal observability dashboard tracks all three.
Phase 4: Production DNS flip (Day -7)
# Update DNS — registry.example.com → OrbitalReg ingress
# This is a single CNAME or A record changePulls now flow through OrbitalReg in production. Writes still target Nexus directly (CI configurations unchanged).
Phase 5: Switch CI to push to OrbitalReg (Day 0)
Update your CI pipelines to push to OrbitalReg directly. New artifacts now land in OrbitalReg first; the proxy fills the cache for old artifacts on demand.
# .github/workflows/publish.yml example
- name: Publish
run: |
npm config set registry https://registry.example.com # now OrbitalReg
npm publishPhase 6: Convert remote-mode to local-mode (Day +14)
Once cache-hit rates exceed 95%, you can switch repositories from remote-mode to local-mode. Cached blobs become canonical; OrbitalReg no longer reaches back to Nexus.
orbital migrate finalize --plan migration-plan.jsonThis sweeps the cache, marks all blobs as authoritative, and removes the upstream-proxy configuration. Verification runs again at this stage.
Phase 7: Decommission Nexus (Day +30)
After 30 days of stable local-mode operation with no rollback signals, Nexus can be turned off. Take a final snapshot for the audit log, then shut down the JVM.
Verification
Verification is what tells you it's safe to cut over.
orbital migrate verify --sample 5000What gets verified:
- Sha256 sample comparison — pulls a random sample from OrbitalReg, compares against the source. If any mismatch, the verifier fails and reports which artifact diverged.
- Metadata round-trip — for each format, verifies that format-specific metadata (Maven
pom.xml, npmpackage.json, Docker manifests) round-trip correctly. - Synthetic pull test — performs a real pull through the format-native client (
mvn,npm,docker pull) on a sampled set, ensuring client compatibility. - Permission spot-check — re-runs each translated permission against a synthetic test user; reports any divergence from Nexus's answer.
A clean run looks like this:
✓ 5000/5000 sha256 matches
✓ All metadata round-trips correctly (9 formats checked)
✓ Pull-test from random sample succeeded
✓ Permission spot-check: 47/47 roles match
→ Safe to flip DNSIf any check fails, the report lists the divergence. Do not flip DNS until the report is clean.
Rollback
The lazy-proxy strategy makes rollback trivial: flip DNS back to Nexus. Nothing was ever deleted from Nexus during migration.
For blue-green: same — DNS flip, OrbitalReg becomes write-only-via-CI, Nexus resumes serving pulls.
For big-bang: rollback requires restoring Nexus from your maintenance-window snapshot. This is why we recommend big-bang only for smaller registries where the snapshot-restore time is bounded.
FAQ
Can we migrate without any downtime?
Yes. Use the blue-green or lazy-proxy strategy. Both give you zero developer-visible downtime through the cutover.
Do existing CI pipelines need updates?
Only the registry URL. Push commands, authentication, and artifact identifiers all carry through unchanged.
What about Nexus IQ Server / Firewall?
OrbitalReg includes the equivalent functionality natively — no separate licence, no separate product. Trivy + Grype perform CVE scanning; the pull-gate policy engine enforces signature verification, severity thresholds, and CVE-allowlists. Migrating IQ policies takes a few hours of manual translation since the DSLs differ.
How long does a full migration take?
| Registry size | Big bang | Blue-green | Lazy proxy |
|---|---|---|---|
| Under 500 GB | 4 h | 24 h elapsed | 14 days elapsed |
| 1-5 TB | not recommended | 48-72 h elapsed | 21 days elapsed |
| 5-10 TB | not recommended | 5-7 days elapsed | 30 days elapsed |
| Over 10 TB | not recommended | not recommended | 30-60 days elapsed |
Active operator hours are a fraction of elapsed time — most of the elapsed window is wait-for-traffic-to-fill-cache or wait-for-soak-period.
What's the cost difference vs Nexus Pro?
Nexus Pro is licensed per-instance (~$2k-15k per HA pair per year, plus IQ Server separately at $25k-100k+ for the security features). OrbitalReg is licensed per-deployment, annual flat-rate. See the pricing overview — security is included in every tier, never an upcharge.
Can we run both registries permanently?
Yes — OrbitalReg can stay configured as a proxy in front of Nexus indefinitely. Some teams prefer that posture for the first 12 months to keep Nexus as a hot fallback. After that, the cost of two licences usually outweighs the comfort of redundancy.
Need a working session?
Email info@orbitalreg.com with subject "Nexus migration support" and we'll book a 60-minute working session. Customers in active migration get a dedicated channel for questions during the cutover window.