A declarative, infrastructure-as-code tool for cleaning up artifacts in a Sonatype Nexus Repository (OSS or Pro)
Nexus Repository Managerβs built-in Cleanup Policies do not support filtering by βnever downloadedβ artifacts, and the upcoming Nexus versions may deprecate Groovy scripting. This project fills that gap by providing:
- Declarative configuration: Define cleanup rules in YAML.
- Code-driven: Manage policies alongside the CI/CD pipeline or Kubernetes Jobs.
- REST API integration: Works with Nexus OSS or Pro over HTTP(S).
- Extensible filters: Out-of-the-box support for βnever downloaded,β age, and more.
- βNever downloadedβ filter
Delete components that have never been requested by any client. - Age-based cleanup
Remove artifacts older than a specified number of days. - Repository scoping
Target specific repositories or repository groups. - Dry-run mode
Preview what would be deleted without making changes. - Audit reporting
Generate a summary report of deleted components.
- Java 17+ or Container runtime (depending on your preferred runtime)
- Network access to your Nexus Repository Manager
- User with nx-admin or equivalent REST-API permissions
Create a cleanup-rules.yml file that defines the cleanup policies and their filters. The YAML format supports defining multiple cleanup rules, each with customizable filters.
rules:
- name: "rule-name" # Required: Unique name for the rule
description: "Optional description" # Optional: Human-readable description
enabled: true # Optional: Whether rule is enabled (default: true)
action: delete # Optional: "delete" (default) or "keep"
filters: # Required: At least one filter must be specified
repositories: # Optional: Repository name patterns (supports wildcards)
- "maven-*"
- "npm-releases"
formats: # Optional: Repository format filters
- "maven2"
- "npm"
groups: # Optional: Component group patterns (supports wildcards)
- "com.example.*"
- "org.springframework.*"
names: # Optional: Component name patterns (supports wildcards)
- "spring-*"
- "*-test"
versions: # Optional: Version patterns (supports wildcards)
- "1.*"
- "*-SNAPSHOT"
updated: "90 days" # Optional: Components last updated before this time
downloaded: "60 days" # Optional: Components last downloaded before this time or "never"The updated and downloaded filters support multiple date formats:
- Relative formats:
"30d","30 days","30 Days","30 days ago" - Absolute ISO dates:
"2025-03-01","2025-03-01T00:00:00Z" - Special values:
downloaded: "never"for components that have never been downloaded
rules:
- name: "cleanup-stale-components"
description: >
Remove components last modified more than 90 days ago
that have not been downloaded in the last 60 days
enabled: true
action: delete
filters:
repositories:
- "maven-releases"
- "maven-snapshots"
formats:
- "maven2"
groups:
- "com.example.*"
- "org.springframework.*"
names:
- "spring-*"
- "*-deprecated"
versions:
- "1.*"
- "*-SNAPSHOT"
updated: "90 days"
downloaded: "60 days"rules:
- name: "cleanup-never-downloaded"
description: >
Remove components that have never been downloaded
and are older than 30 days
enabled: true
action: delete
filters:
repositories:
- "maven-releases"
formats:
- "maven2"
updated: "30 days ago"
downloaded: "never"The tool supports multiple authentication methods:
# Command line arguments
./gradlew run --args="--rules cleanup-rules.yml --url https://nexus.example.com --username admin --password yourpassword"
# Environment variables
export NEXUS_USERNAME=admin
export NEXUS_PASSWORD=yourpassword
./gradlew run --args="--rules cleanup-rules.yml --url https://nexus.example.com"# Command line argument
./gradlew run --args="--rules cleanup-rules.yml --url https://nexus.example.com --token your-auth-token"
# Environment variable
export NEXUS_TOKEN=your-auth-token
./gradlew run --args="--rules cleanup-rules.yml --url https://nexus.example.com"The tool supports proxy configuration through multiple methods:
# Command line proxy argument (highest priority)
./gradlew run --args="--rules cleanup-rules.yml --url https://nexus.example.com --proxy proxy.company.com:8080"
./gradlew run --args="--rules cleanup-rules.yml --url https://nexus.example.com --proxy http://user:pass@proxy.company.com:8080"
# Environment variables
export HTTP_PROXY=http://proxy.company.com:8080
export HTTPS_PROXY=http://proxy.company.com:8080
./gradlew run --args="--rules cleanup-rules.yml"
# Java system properties
./gradlew run -Dhttp.proxyHost=proxy.company.com -Dhttp.proxyPort=8080 --args="--rules cleanup-rules.yml"
# With non-proxy hosts
./gradlew run -Dhttp.proxyHost=proxy.company.com -Dhttp.proxyPort=8080 -Dhttp.nonProxyHosts="localhost|*.internal.com" --args="--rules cleanup-rules.yml"The proxy selection follows this priority order:
- Command line
--proxyargument (highest priority) - Java System Properties (
http.proxyHost,http.proxyPort,http.nonProxyHosts) - Uppercase environment variables (
HTTP_PROXY,HTTPS_PROXY) - Lowercase environment variables (
http_proxy,https_proxy)
The following environment variables are supported:
NEXUS_URL- Nexus Repository Manager URL (required)NEXUS_USERNAME- Username for authenticationNEXUS_PASSWORD- Password for authenticationNEXUS_TOKEN- Authentication token (alternative to username/password)HTTP_PROXY/http_proxy- HTTP proxy URL (uppercase takes precedence)HTTPS_PROXY/https_proxy- HTTPS proxy URL (uppercase takes precedence)
The tool provides comprehensive reporting capabilities that are especially important for --dry-run executions to preview and validate removal of data before performing actual cleanup operations.
Generate a detailed list of components that match your cleanup rules. This is particularly valuable when combined with --dry-run to preview what would be deleted:
# Preview components to be removed (dry-run mode)
./gradlew run --args="--rules cleanup-rules.yml --dry-run --output-component components-to-be-removed.json"
# Save filtered components list to file in JSON or CSV format
./gradlew run --args="--rules cleanup-rules.yml --output-component components.json"
./gradlew run --args="--rules cleanup-rules.yml --output-component components.csv"
# Combine with authentication for complete workflow
./gradlew run --args="--rules cleanup-rules.yml --url https://nexus.example.com --username admin --password yourpassword --dry-run --output-component preview.json"# Generate repository summary with component counts and sizes
./gradlew run --args="--rules cleanup-rules.yml --report-repositories-summary"
# Sort repositories by different criteria
./gradlew run --args="--rules cleanup-rules.yml --report-repositories-summary --repo-sort name"
./gradlew run --args="--rules cleanup-rules.yml --report-repositories-summary --repo-sort size"
./gradlew run --args="--rules cleanup-rules.yml --report-repositories-summary --repo-sort components"# Generate top groups report
./gradlew run --args="--rules cleanup-rules.yml --report-top-groups"
# Customize number of top groups and sorting
./gradlew run --args="--rules cleanup-rules.yml --report-top-groups --top-groups 20 --group-sort size"# Save report to JSON or CSV file
./gradlew run --args="--rules cleanup-rules.yml --report-repositories-summary --report-output-file report.json"
./gradlew run --args="--rules cleanup-rules.yml --report-repositories-summary --report-output-file report.csv"# Run cleanup with dry-run (no deletions) from this source directory
./gradlew run --args="--rules cleanup-rules.yml --url https://nexus.example.com --username admin --password yourpassword --dry-run"
# Execute actual cleanup
./gradlew run --args="--rules cleanup-rules.yml --url https://nexus.example.com --username admin --password yourpassword"
# Using environment variables
export NEXUS_URL=https://nexus.example.com
export NEXUS_USERNAME=admin
export NEXUS_PASSWORD=yourpassword
./gradlew run --args="--rules cleanup-rules.yml"
# or execute the downloaded JAR
java -jar nexus-repository-cleanup.jar --rules cleanup-rules.yml --url https://nexus.example.com --username admin --password yourpassword
# Using docker with environment variables
docker run --rm \
-v "$(pwd)/config:/app/config" \
-e NEXUS_URL=https://nexus.example.com \
-e NEXUS_USERNAME=admin \
-e NEXUS_PASSWORD=yourpassword \
ghcr.io/skarzhevskyy/nexus-repository-cleanup:latest \
--rules /app/config/cleanup-rules.ymlRepository Report Summary (Dry Run):
====================================================================================================================
Repository Format Removed # Removed Size Remaining # Remaining Size
------------------------------ ---------- ------------ --------------- --------------- ---------------
maven-central maven2 10 1.00 KB 5 512.00 B
maven-releases maven2 20 2.00 KB 15 1.50 KB
TOTAL - 30 3.00 KB 20 2.00 KB
Top Consuming Groups (by Components, Dry Run):
====================================================================================================================
Group Removed # Removed Size Remaining # Remaining Size
------------------------------ ------------ --------------- ------------- ---------------
com.example 20 2.00 KB 15 1.50 KB
org.springframework 10 1.00 KB 5 512.00 B
For production environments, you can deploy this application as a Kubernetes CronJob using the provided Helm chart. This approach offers better scheduling, resource management, and integration with your Kubernetes infrastructure.
A complete Helm chart is available for deploying the application as a Kubernetes CronJob:
π Helm Chart Documentation - Complete installation and configuration guide
kubectl create secret generic nexus-credentials \
--from-literal=username=your-nexus-username \
--from-literal=password=your-nexus-password
kubectl create configmap nexus-cleanup-rules \
--from-file=cleanup-rules.yml="examples/cleanup-rules.yml"
helm install nexus-cleanup oci://ghcr.io/skarzhevskyy/charts/nexus-repository-cleanup --version 0.0.1-SNAPSHOT \
--set nexusRepositoryCleanup.nexusUrl=https://nexus.example.com \
--set nexusRepositoryCleanup.credentialsSecretName=nexus-credentials \
--set nexusRepositoryCleanup.existingCleanupRulesConfigMapName=nexus-cleanup-rules \
--set nexusRepositoryCleanup.dryRun=true- π Automated scheduling with cron expressions
- π Security hardened containers with non-root execution
- π Resource management with limits and requests
- ποΈ ConfigMap integration for cleanup rules
- π Secret management for Nexus credentials
- π Comprehensive logging and monitoring support
- Fork the repository
- Create your feature branch (
git checkout -b feature/your-feature) - Commit your changes (
git commit -m "Add your feature") - Push to the branch (
git push origin feature/your-feature) - Open a Pull Request
This project is licensed under the Apache License 2.0.