Skip to content

Migration Guide: Production/Pro (External PostgreSQL)📜

This guide covers migrating from the legacy Big Bang nexus-repository-manager chart to the new nxrm-ha chart in production environments with external PostgreSQL. This is primarily a Helm chart architecture change - your data stays the same.

ℹ️ NOTE: This guide assumes you already have an external PostgreSQL database. If you’re migrating from H2 (embedded database), see the OSS/Development Migration Guide instead.

Overview📜

What’s Changing: - Deployment → StatefulSet - Direct values → Passthrough pattern (values nested under upstream key) - Single container → Multi-container pod (main app + log sidecars)

What Stays the Same: - External PostgreSQL database (same connection, same data) - External blob storage (S3/Azure/NFS - same buckets/containers) - All repositories, artifacts, users, and configurations

Prerequisites📜

  • Access to the Kubernetes cluster
  • kubectl CLI tool installed
  • helm CLI tool installed
  • flux CLI tool installed (if using GitOps)
  • Admin access to the existing Nexus instance
  • External PostgreSQL database already configured
  • External blob storage (S3/Azure/NFS) already configured
  • Backups of database and blob storage

Estimated Downtime: 30 - 45 minutes


Values Migration: Passthrough Pattern📜

The main change is restructuring your values file. Big Bang additions stay at root level, upstream chart values move under upstream:.

Values Mapping Reference📜

Configuration Old Chart Location New Chart Location
Hostname/Domain hostname, domain hostname, domain (unchanged)
Admin Password custom_admin_password custom_admin_password (unchanged - MUST match existing password during migration)
Database Config Env vars + secrets nexus.database.host, nexus.database.user, nexus.database.password (chart auto-creates secret)
Istio istio.* istio.* (unchanged)
Network Policies networkPolicies.* networkPolicies.* (unchanged)
Monitoring monitoring.* monitoring.* (unchanged)
SSO/SAML sso.* sso.* (unchanged)
Blob Stores nexus.blobstores.* nexus.blobstores.* (unchanged)
Image image.repository, image.tag upstream.statefulset.container.image.repository, upstream.statefulset.container.image.nexusTag
Resources resources.* upstream.statefulset.container.resources.*
Service Account serviceAccount.* upstream.serviceAccount.*
Environment Vars env.* upstream.statefulset.container.env.*
Probes livenessProbe.*, readinessProbe.* upstream.statefulset.livenessProbe.*, upstream.statefulset.readinessProbe.*

Example Values File📜

addons:
  nxrm-ha:
    enabled: true
    values:
      # Big Bang-specific configurations
      hostname: nexus
      domain: example.com

      istio:
        enabled: true
        injection: enabled

      networkPolicies:
        enabled: true

      monitoring:
        enabled: true

      sso:
        enabled: false  # Configure if needed

      # Custom admin password (MUST match existing if migrating)
      custom_admin_password: "SomeSecurePassword123!"

      # Security realms configuration
      realms:
        - NexusAuthenticatingRealm
        - LdapRealm
        - NpmToken

      nexus:
        # External database configuration - chart will auto-create "nexus-postgresql" secret
        database:
          host: "postgres.example.com"  # YOUR external PostgreSQL host
          user: "nexus"  # YOUR database user
          password: "your-password"  # YOUR database password

        # Docker registry configuration (optional)
        docker:
          enabled: true
          registries:
            - host: containers.dev.bigbang.mil
              port: 5000

        # Repository configuration (optional)
        repository:
          enabled: true
          repo:
            - name: "containers"
              format: "docker"
              type: "hosted"
              repo_data:
                name: "containers"
                online: true
                storage:
                  blobStoreName: "your-nexus-blobstore"
                  strictContentTypeValidation: true
                  writePolicy: "allow_once"
                docker:
                  v1Enabled: false
                  forceBasicAuth: true
                  httpPort: 5000

        # Blobstore configuration (optional - configure if using S3/Azure)
        blobstores:
          enabled: true
          blobstore:
            - name: "your-nexus-blobstore"
              type: "s3"
              blobstore_data:
                name: "your-nexus-blobstore"
                bucketConfiguration:
                  bucket:
                    region: "your-region"
                    name: "your-nexus-blobstore"
                    prefix: ""
                    expiration: 3
                  bucketSecurity:
                    accessKeyId: "your-accessKeyId"
                    secretAccessKey: "your-secretAccessKey"
                    sessionToken: "your-sessionToken"

      # Disable internal PostgreSQL for production (use external RDS/managed database)
      postgresql:
        install: false

      #=============================================================================
      # Upstream Chart Values (Nested under 'upstream')
      #=============================================================================
      upstream:
        nameOverride: nxrm-ha
        fullnameOverride: nxrm-ha

        serviceAccount:
          enabled: true
          name: nexus-repository-deployment-sa
          # For AWS IRSA (S3 access):
          # annotations:
          #   eks.amazonaws.com/role-arn: arn:aws:iam::123456789:role/nexus-role

        statefulset:
          replicaCount: 1  # OSS mode (use 3 for HA/Pro)
          clustered: false  # Set to true for HA/Pro

          container:
            image:
              repository: registry1.dso.mil/ironbank/sonatype/nexus/nexus
              nexusTag: 3.84.0-03

            resources:
              requests:
                cpu: "4"
                memory: "4Gi"
              limits:
                cpu: "4"
                memory: "4Gi"

            env:
              install4jAddVmParams: "-Xms2048m -Xmx2048m -Dnexus.loadAsOSS=true"
              # For HA/Pro mode: "-Xms2703m -Xmx2703m -Dnexus.datastore.nexus.maximumPoolSize=80"
              jdbcUrlParams: null # Must start with a '?' e.g. "?foo=bar&baz=foo"

          imagePullSecrets:
            existingSecret:
              enabled: true
              name: "private-registry"

        service:
          nexus:
            enabled: true
            type: ClusterIP
            port: 8081

        secret:
          existingDbSecret:
            enabled: true
          nexusAdminSecret:
            enabled: false
          # For HA/Pro with license:
          # license:
          #   licenseSecret:
          #     enabled: true
          #     fileContentsBase64: <nexus-license>

What happens automatically: - Chart creates nexus-postgresql secret from your nexus.database.* values - Both init container and main container reference this secret - No manual secret creation or additional overrides needed!


Step-by-Step Migration Process📜

This process has been tested and successfully preserves: - Repository configurations - Component data and artifacts metadata - User accounts and passwords - System settings

Step 1: Prepare for Migration📜

Backup your current configuration and prepare the environment:

export NEXUS_NAMESPACE="nexus-repository-manager"

# Backup current configuration (if not using GitOps)
kubectl get all,secrets,cm -n $NEXUS_NAMESPACE -o yaml > backup.yaml
helm get values nexus-repository-manager -n bigbang > old-values.yaml

# Create your new nxrm-ha-values.yaml using the example above

Step 2: Suspend Old Flux HelmRelease (If Using GitOps)📜

Important: If using Flux/GitOps, suspend the OLD HelmRelease to prevent Flux from reconciling it back during migration. The new nxrm-ha chart will be managed by a separate HelmRelease.

# Suspend OLD Flux HelmRelease (prevents auto-reconciliation during migration)
flux suspend hr nexus-repository-manager -n bigbang

# Verify suspension
flux get hr nexus-repository-manager -n bigbang
# Expected: SUSPENDED should be True

Note: - Skip this step if not using Flux/GitOps - The old HelmRelease will remain suspended - the new nxrm-ha HelmRelease manages the new deployment - You can delete the old HelmRelease after successful migration

Step 3: Scale Down Old Nexus Deployment and Clean Up Resources📜

Important: Scale down the old deployment BEFORE deploying the new chart to prevent both from accessing the same PostgreSQL database simultaneously.

# Scale down old deployment
kubectl scale deployment nexus-repository-manager -n $NEXUS_NAMESPACE --replicas=0

# Wait for termination
kubectl wait --for=delete pod -l app=nexus-repository-manager \
  -n $NEXUS_NAMESPACE --timeout=300s

# Delete old Istio VirtualServices to prevent conflicts with new chart
kubectl delete virtualservice -n $NEXUS_NAMESPACE --all

Step 4: Deploy NXRM-HA Chart📜

Configure the nxrm-ha addon in your Big Bang values. Important: Ensure database credentials, custom admin password, and blobstore settings match your existing nexusRepositoryManager deployment.

# nxrm-ha-migration.yaml
addons:
  nexusRepositoryManager:
    enabled: true  # Keep old one running during migration
  nxrm-ha:
    enabled: true
    values:
      custom_admin_password: "SomeSecurePassword123!"  # MUST match existing admin password
      realms:
        - NexusAuthenticatingRealm
        - LdapRealm
        - NpmToken
      nexus:
        hostname: nxrm-ha
        docker:
          enabled: true
          registries:
            - host: containers.dev.bigbang.mil
              port: 5000
        repository:
          enabled: true
          repo:
            - name: "containers"
              format: "docker"
              type: "hosted"
              repo_data:
                name: "containers"
                online: true
                storage:
                  blobStoreName: "your-nexus-blobstore"
                  strictContentTypeValidation: true
                  writePolicy: "allow_once"
                cleanup:
                  policyNames:
                    - "string"
                component:
                  proprietaryComponents: true
                docker:
                  v1Enabled: false
                  forceBasicAuth: true
                  httpPort: 5000
        blobstores:
          enabled: true
          blobstore:
            - name: "your-nexus-blobstore"
              type: "s3"
              blobstore_data:
                name: "your-nexus-blobstore"
                bucketConfiguration:
                  bucket:
                    region: "your-region"
                    name: "your-nexus-blobstore"
                    prefix: ""
                    expiration: 3
                  bucketSecurity:
                    accessKeyId: "your-accessKeyId"
                    secretAccessKey: "your-secretAccessKey"
                    sessionToken: "your-sessionToken"
        # External PostgreSQL database configuration for production
        # MUST match your existing nexusRepositoryManager database settings
        database:
          host: "postgres.example.com"   # Replace with your RDS endpoint
          user: "nexus"  # Database username
          password: "your-password"  # Use sealed secrets in production!

      # Disable internal PostgreSQL for production (use external RDS/managed database)
      postgresql:
        install: false

      # HA configuration with Pro license and external PostgreSQL
      # Production-ready setup with:
      # - 3 replicas for high availability
      # - External PostgreSQL database (see nexus.database config above)
      # - S3 blob storage for shared artifact storage
      # - Pro license for HA features
      #
      upstream:
        statefulset:
          replicaCount: 3
          clustered: true
          container:
            env:
              nexusDBName: nexus
              nexusDBPort: 5432
              install4jAddVmParams: "-Xms2703m -Xmx2703m -Dnexus.datastore.nexus.maximumPoolSize=80"
              jdbcUrlParams: null # Must start with a '?' e.g. "?foo=bar&baz=foo"
              zeroDowntimeEnabled: false
            # Override default additionalEnv to remove empty LICENSE_FILE (OSS default)
            # Keep DB vars but omit LICENSE_FILE - chart sets it automatically from license secret
            additionalEnv:
              - name: DB_NAME
                value: "nexus"
              - name: DB_HOST
                valueFrom:
                  secretKeyRef:
                    name: nexus-postgresql
                    key: DB_HOST
              - name: DB_USER
                valueFrom:
                  secretKeyRef:
                    name: nexus-postgresql
                    key: DB_USER
              - name: DB_PASSWORD
                valueFrom:
                  secretKeyRef:
                    name: nexus-postgresql
                    key: DB_PASSWORD
        secret:
          license:
            licenseSecret:
              enabled: true
              fileContentsBase64: <nexus-license>

Critical Migration Requirements:

  1. Database credentials MUST match your existing nexusRepositoryManager deployment:

    database:
      host: "postgres.example.com"
      user: "nexus"
      password: "your-password"
    

  2. Admin password MUST match your existing Nexus admin password (stored in the database):

First, retrieve your current admin password from the old deployment:

# Get existing admin password from old secret
kubectl get secret nexus-repository-manager-secret -n nexus-repository-manager \
  -o jsonpath='{.data.admin-password}' | base64 -d; echo

Then set it in your nxrm-ha values at the root level:

custom_admin_password: "SomeSecurePassword123!"  # Use the password from above

Important: This password is stored in the migrated database. If the Kubernetes secret password doesn’t match the database password, authentication will fail for automation (EULA job, scripts, etc.).

  1. Blobstore configuration MUST match your existing blob storage setup (if using S3/Azure):

    blobstores:
      enabled: true
      blobstore:
        - name: "your-nexus-blobstore"
          type: "s3"
    

  2. Other upstream settings should mirror your existing deployment (image, resources, service account, etc.)

After configuring, deploy via GitOps or Helm:

# If using GitOps: commit the configuration and let Flux deploy
# OR manually with Helm:
helm upgrade -i bigbang chart/ -n bigbang --create-namespace -f nxrm-ha-migration.yaml

# Wait for HelmRelease to be ready
kubectl wait helmrelease/nxrm-ha -n bigbang --for=condition=Ready --timeout=300s

Step 5: Verify Deployment📜

After deployment, verify these critical checks:

# 1. Verify HelmRelease was successful
flux get hr nxrm-ha -n bigbang
# Expected: READY should be True, MESSAGE should show "Helm install succeeded" or "Helm upgrade succeeded"
# Example output:
# NAME    REVISION        SUSPENDED       READY   MESSAGE
# nxrm-ha 84.0.0-bb.3     False           True    Helm install succeeded for release nxrm-ha/nxrm-ha.v1 with chart nxrm-ha@84.0.0-bb.3

# 2. Verify NXRM-HA pod is running
kubectl get pods -n nxrm-ha -l app.kubernetes.io/name=nxrm-ha
# Expected: 5/5 Running (main app + sidecars)
# Example output:
# NAME        READY   STATUS    RESTARTS   AGE
# nxrm-ha-0   5/5     Running   0          2m

# 3. Get admin password
kubectl get secret nxrm-ha-adminsecret \
  -n nxrm-ha -o jsonpath='{.data.nexus-admin-password}' | base64 -d; echo

# 4. Verify Nexus UI access
# Navigate to https://nexus.example.com (URL remains unchanged)
# Login with admin and the password from above
# Verify repositories and blob stores are accessible
# Check that existing artifacts are available

Important: Do not proceed to the next step until: - HelmRelease shows READY=True - NXRM-HA pod shows 5/5 Running

Step 6: Post-Migration Tasks📜

These tasks are critical to the proper functioning of the repository after the migration process. Some tasks may take a notable amount of time to complete.

⚠️ WARNING: Do not restart your instance while the post-migration tasks are running to avoid damaging your browse and search index.

Run these repair tasks manually via the Nexus UI:

  1. Navigate to AdministrationSystemTasks

  2. First: Create and run Repair - Rebuild repository browse

  3. Task name: Rebuild repository browse
  4. Repository: (All Repositories)
  5. Task frequency: Manual
  6. Click Create task, then click Run

  7. Second: Create and run Repair - Rebuild repository search

  8. Task name: Rebuild repository search
  9. Repository: (All Repositories)
  10. Task frequency: Manual
  11. Click Create task, then click Run

  12. Third: Create and run Repair - Reconcile component database from blob store

  13. Task name: Reconcile blob store
  14. Blob store: default (or your blob store name)
  15. Task frequency: Manual
  16. Click Create task, then click Run
  17. Wait for this task to complete before proceeding (check task status)
  18. This scans the blob store directory and updates the database with blob metadata

  19. Fourth: Create and run Repair - Recalculate blob store storage

  20. Task name: Recalculate blob store metrics
  21. Blob store: default (or your blob store name)
  22. Task frequency: Manual
  23. Click Create task, then click Run
  24. This updates the Blob Count and Total Size metrics displayed in the UI

  25. (If using Helm repositories): Create and run Repair - Rebuild Helm metadata

  26. Verify Scheduled Tasks: Navigate to AdministrationSystemTasks and verify your previously configured scheduled tasks are present. Recreate any missing tasks (e.g., cleanup policies, repository health checks, compact blob store).

Important Notes: - The Reconcile task is essential - it syncs the blob store files with the database - The Recalculate task updates UI metrics - without it, Blob Store page shows 0 blobs - All tasks must complete successfully before the migration is considered complete - Monitor task progress in the Tasks UI before proceeding

Step 7: Disable Old Addon (GitOps)📜

After confirming the migration is successful and stable, disable the old nexusRepositoryManager addon in your Big Bang values:

addons:
  nexusRepositoryManager:
    enabled: false

Note: Only do this after you’re confident the migration is successful and you won’t need to rollback.


Rollback Procedure📜

If issues occur during or after migration, you can rollback to the old deployment:

Option 1: Using GitOps/Flux📜

# 1. Disable nxrm-ha addon in Big Bang values
addons:
  nxrm-ha:
    enabled: false

# 2. Re-enable old nexusRepositoryManager addon
addons:
  nexusRepositoryManager:
    enabled: true
    # ... your previous values

Commit and let Flux reconcile.

Option 2: Manual Rollback📜

# Scale down nxrm-ha StatefulSet
kubectl scale statefulset nxrm-ha -n nxrm-ha --replicas=0

# Wait for pods to terminate
kubectl wait --for=delete pod -l app.kubernetes.io/name=nxrm-ha -n nxrm-ha --timeout=300s

# Resume old Flux HelmRelease (if it was suspended in Step 2)
flux resume hr nexus-repository-manager -n bigbang 2>/dev/null || echo "Not using Flux"

# Scale up old deployment
kubectl scale deployment nexus-repository-manager -n nexus-repository-manager --replicas=1

# Verify old deployment is running
kubectl get pods -n nexus-repository-manager

Important: - Since both deployments use the same external PostgreSQL database, data changes made in NXRM-HA will persist after rollback - Ensure you have backups before attempting rollback


What Gets Migrated📜

The migration successfully preserves: - ✅ All repository configurations (Maven, Docker, NPM, PyPI, etc.) - ✅ Component data and artifacts metadata - ✅ User accounts and passwords - ✅ Roles and permissions - ✅ System configuration - ⚠️ Scheduled tasks (may need to be recreated - verify after migration) - ✅ Security settings - ✅ Blob store configurations


Key Differences After Migration📜

Feature Legacy Chart NXRM-HA
Database External PostgreSQL External PostgreSQL (unchanged)
Namespace nexus-repository-manager nxrm-ha
Pod Name nexus-repository-manager-* nxrm-ha-*
Admin Secret nexus-repository-manager-secret nxrm-ha-adminsecret
Service Name nexus-repository-manager nxrm-ha
Service Account nexus-repository-manager nexus-repository-deployment-sa
Log Access kubectl logs deploy/nexus-repository-manager kubectl logs statefulset/nxrm-ha -c nxrm-app
Values Structure Direct Nested under upstream:
High Availability Not supported Supported (Pro only)

References📜