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 candidated 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.

A note about Netcup

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