This guide outlines the process of migrating a Nexus Docker instance from OrientDB (deprecated since version 3.71) to PostgreSQL, with an intermediate step through H2. Follow the instructions step by step to ensure proper execution of the migration.
I decided to create this guide because the official documentation is incomplete and not always reliable. I've consolidated information from Stack Overflow, Reddit, GitHub issues, and the official documentation to provide a more comprehensive solution.
This guide is also suitable for migrating from H2 to Postgres, just skip the first part.
- If you haven't done so, update the Nexus3 Docker image to version 3.70.3 (the latest available for OrientDB).
-
Backup the
nexus.properties
file:docker cp nexus_container_name:/opt/sonatype/sonatype-work/nexus3/etc/nexus.properties .
-
Stop the container:
docker-compose down
-
Backup the Nexus database folder
-
Modify the
docker-compose.yml
file: Add the mapping for thenexus.properties
file:volumes: - ./nexus.properties:/opt/sonatype/sonatype-work/nexus3/etc/nexus.properties
-
Start the container again:
docker-compose up -d
Why not migrate directly to Postgres? Because before version 3.77, you can only do it with the Pro version. :)
-
Access the container:
docker exec -ti nexus_container_name bash
-
From the Nexus web interface, in the Tasks section, perform the backup and store the last 4
.bak
files in a folder. -
Enter the backup folder and download the Nexus database migrator:
curl -s -L -O https://download.sonatype.com/nexus/nxrm3-migrator/nexus-db-migrator-3.70.1-03.jar
-
Run the H2 database migration:
java -Xmx2G -Xms2G -XX:+UseG1GC -XX:MaxDirectMemorySize=28672M -jar nexus-db-migrator-3.70.1-03.jar --migration_type=h2
-
Stop Nexus:
/opt/sonatype/nexus/bin/nexus stop
-
If the
nexus.mv.db
file exists, copy it to the/nexus-data/db
folder:cp nexus.mv.db /nexus-data/db
-
Exit the container
-
Stop the container again:
docker-compose down
-
Add the following configuration in the
nexus.properties
file:nexus.datastore.enabled=true
-
Start the containers:
docker-compose up -d
-
Check the logs to verify that the database was correctly migrated:
docker logs nexus_container_name | grep H2
The database is now perfectly migrated to H2.
Now, you could update to the latest version and it would work, but then you wouldn't be able to migrate to Postgres (I have no idea why they don't mention it in the docs). So, you need to use version 3.77, the version from which it's possible to migrate to Postgres without the Pro version.
-
Update the Nexus version to
3.77.1
and remove the mapping for thenexus.properties
file. -
Start the container:
docker-compose up -d
If you don't have the default encryption key error, skip the following steps.
-
Create a
secret.json
file with the following structure:{ "active": "key", "keys": [ { "id": "key", "key": "very secure and long password string" } ] }
-
Add the following environment variables in the
docker-compose.yml
file:environment: - NEXUS_SECRETS_KEY_FILE=/opt/sonatype/secret.json volumes: - ./secret.json:/opt/sonatype/secret.json
-
Restart the container:
docker-compose down && docker-compose up -d
-
Re-encrypt the secret key using the REST API (you have to change only password and hostname):
curl -u admin:<password> -X 'PUT' \ 'http(s)://your.repo.com/service/rest/v1/secrets/encryption/re-encrypt' \ -H 'accept: application/json' \ -H 'Content-Type: application/json' \ -H 'NX-ANTI-CSRF-TOKEN: token' \ -H 'X-Nexus-UI: true' \ -d '{ "secretKeyId": "key" }'
-
Add PostgreSQL to the
docker-compose.yml
file:postgres: image: postgres:17.4 hostname: db restart: on-failure volumes: - ./postgresql_data:/var/lib/postgresql/data environment: POSTGRES_DB: nexus POSTGRES_USER: nexus POSTGRES_PASSWORD: nexus PGDATA: /var/lib/postgresql/data/pgdata PGOPTIONS: -c max_connections=200 healthcheck: test: ["CMD-SHELL", "sh -c 'pg_isready -U nexus -d nexus'"] interval: 30s timeout: 10s retries: 5
Change the password of course...
PGOPTIONS: -c max_connections=200
It's not required, but it's recommended. -
Add this to nexus service in the
docker-compose.yml
file:depends_on: postgres: condition: service_healthy restart: true
-
Start the containers:
docker-compose up -d
-
Clean the backup directory
-
From the Nexus web interface, in the Tasks section, perform the backup and store the .zip file in a folder
-
Access the container:
docker exec -ti nexus_container_name bash
-
Cd into the zip folder
-
Stop Nexus:
/opt/sonatype/nexus/bin/nexus stop
-
Copy the Nexus database:
cp /nexus-data/db/nexus.mv.db .
-
Download the Nexus database migrator:
curl -s -L -O https://download.sonatype.com/nexus/nxrm3-migrator/nexus-db-migrator-3.77.1-01.jar
-
Run the migration from H2 to PostgreSQL:
java -Xmx16G -Xms16G -XX:+UseG1GC -XX:MaxDirectMemorySize=28672M -jar nexus-db-migrator-*.jar --migration_type=h2_to_postgres --db_url="jdbc:postgresql://db:5432/nexus?user=nexus&password=nexus¤tSchema=public"
-
Exit the container
-
Access the postgres container:
docker exec -ti postgres_container_name bash
-
Access PostgreSQL:
psql -U nexus
-
Run the
VACUUM
command to optimize the database:VACUUM(FULL,ANALYZE,VERBOSE);
-
Check the
max_connections
configuration:SHOW max_connections;
If it's not set to 200, set
max_connections
to 200 and delete the PGOPTIONS env variable fromdocker-compose.yml
:ALTER SYSTEM SET max_connections = 200;
-
Exit the container
-
Stop the containers:
docker-compose down
-
Modify the
docker-compose.yml
file by removing the mappings fornexus-data
andbackup
folder (if any), and adding the following environment variables:environment: - NEXUS_DATASTORE_NEXUS_JDBCURL: jdbc:postgresql://db:5432/nexus?currentSchema=public - NEXUS_DATASTORE_NEXUS_USERNAME: nexus - NEXUS_DATASTORE_NEXUS_PASSWORD: nexus - NEXUS_DATASTORE_NEXUS_ADVANCED: maximumPoolSize=190
190 is arbitrary, the important thing is that it's not 200. If you've left the default value in Postgres (100), set a number lower than one hundred. Otherwise, in Postgres, you'll get "FATAL: sorry, too many clients already."
-
Start the containers:
docker-compose up -d
You may need to run
docker-compose down
anddocker-compose up -d
again.
- If you encounter errors in the Java command, try removing the options
-Xmx2G -Xms2G -XX:+UseG1GC -XX:MaxDirectMemorySize=28672M
.
It took me a lot of time, study, swearing, and more to create this guide. I want to donate the result of my efforts to the community, but if you feel like thanking me, buy me a coffee! : paypal.me/mirawara