By default the Nexus 3 software repository does not remove any artifacts from it’s storage backend. You have two options to get rid of artifacts which are not needed any more. First you can configure “cleanup policies”. Another approach is that you might want to set up a task which executes a custom Groovy script which deals with the removal of old artifacts.

Nexus uses a proprietary blob storage engine to save the artifacts to disk. No matter which approach you use (cleanup policies or a custom Groovy script) you have to keep in mind that after deleting the artifacts you have to run the “Compact blob store” task in order for Nexus to actually free up the disk space. You can configure and execute the “Compact blob store” task under “Administration” -> “System” -> “Tasks”.

By the way. As of writting this post I am using the Sonatype Nexus Repository Manager OSS version 3.20.1-01.

Using a Groovy script

If you want to select the candidates for removal based on a more complex query the approcach using a custom Groovy script comes in handy. Below you will find such a script:

import org.sonatype.nexus.repository.storage.Component
import org.sonatype.nexus.repository.storage.Query
import org.sonatype.nexus.repository.storage.StorageFacet

def repoName = "<your repo name (e.g. maven-releases)>"

log.info("delete components for repository: " + repoName)

def compInfo = { Component c -> "${c.group()}:${c.name()}:${c.version()}[${c.lastUpdated()}]}" }

def repo = repository.repositoryManager.get(repoName)
StorageFacet storageFacet = repo.facet(StorageFacet)

def tx = storageFacet.txSupplier().get()
tx.begin()

Iterable<Component> components = tx.findComponents(Query.builder()
  .where('last_updated < ').param('2020-01-31')
  .and('name').like('%<only delete artifacts which contain this substring in their name>%')
  .build(), [repo])

tx.commit()
tx.close()

log.info("Going to delete " + components.size() + " components")

for(Component c : components) {

    if (c.name().contains("<name of an important artifact we have to keep>")) {
     continue;
   }

    log.info("deleting " + compInfo(c))

    tx2 = storageFacet.txSupplier().get()
    tx2.begin()
    tx2.deleteComponent(c)
    tx2.commit()
    tx2.close()
}

log.info("finished delete components script")

To add the script create a new “Execute script” task. In the script language input field do not forget to enter “groovy”. If you want you can also setup an integrated development environment for script development.

Things to keep in mind:

  • Nexus is using OrientDB behind the scene. You can find query examples here.
  • You can find the log statements in the Web UI under “Administration” -> “Support” -> “Logging” -> “Log Viewer”. But each invocation of the script also creates a new log file on the server located at e.g. /var/nexus/log/tasks/script-20200205164127193.log.
  • Nexus also offers a REST API which might come in handy.

Using the UI

First you have to define a cleanup policy. Then you have to attach the cleanup policy to one or more repositories. The “Cleanup repositories using their associated policies” task will then execute the cleanup policies. The documentation about Cleanup Policies can be found here.

In case if you are wondering where this task comes from or how to recreate it if it has been deleted. This task is automatically created each time the Nexus server is started (if it does not exist). For more information about this task see here.

OLowDiskSpaceException

If you are already low on disk space it might happen that the removal of old artifacts is not possible any more. If that’s the case you should find the following error message in the Nexus logs (see the Web UI under “Administration” -> “Support” -> “Logging” -> “Log Viewer”):

com.orientechnologies.orient.core.exception.OLowDiskSpaceException: Error occurred while executing a write operation to database 'config' due to limited free space on the disk (3576 MB). The database is now working in read-only mode. Please close the database (or stop OrientDB), make room on your hard drive and then reopen the database. The minimal required space is 4096 MB. Required space is now set to 4096MB (you can change it by setting parameter storage.diskCache.diskFreeSpaceLimit) .

To remedy the situation first stop Nexus. Then add the following line to the file /opt/nexus/bin/nexus.vmoptions:

-Dstorage.diskCache.diskFreeSpaceLimit=1024

After this start Nexus again, remove all artifacts and compact your blob store to actually free the disk space. Finally comment out the line you just added by prefixing it with a hash mark (#) and restart Nexus one more time.

A note about Netcup (advertisement)

Netcup is a German hosting company. Netcup offers inexpensive, yet powerfull web hosting packages, KVM-based root servers or dedicated servers for example. Using a coupon code from my Netcup coupon code web app you can even save more money (6$ on your first purchase, 30% off any KVM-based root server, ...).