Skip to content

Nexus Repository — Artifact Storage & Proxy Repositories Guide

DodaTech Updated 2026-06-24 6 min read

In this tutorial, you'll learn about Nexus Repository. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.

Nexus Repository is a binary Repository manager that stores, caches, and serves software artifacts (Maven, npm, Docker, PyPI, raw files) with proxy, hosted, and group Repository types.

What You'll Learn

Why It Matters

Downloading dependencies from public registries for every build is slow, unreliable, and exposes your CI pipeline to external outages. Nexus caches proxied artifacts locally, hosts private artifacts, and provides a single source of truth for all build dependencies. DodaTech runs Nexus in high-availability mode, serving 50,000+ artifact requests per day with 99.99% availability.

Real-World Use

DodaZIP's build pipeline resolves all Maven dependencies through Nexus proxy repositories, which cache artifacts from Maven Central after the first request. Internal libraries are published to Nexus hosted repositories, versioned, and consumed by all teams. CI builds that used to take 12 minutes (downloading from Maven Central) now take 3 minutes (from Nexus cache).

flowchart TD
    A[Developer Build] --> B[Nexus Group Repo]
    B --> C[Nexus Hosted Repo]
    B --> D[Nexus Proxy Repo]
    D --> E[Maven Central]
    D --> F[npmjs.org]
    D --> G[Docker Hub]
    D --> H[PyPI.org]
    C --> I[Internal Libraries]
    C --> J[Team Artifacts]
    C --> K[Release Candidates]
    style B fill:#00A2D3,color:#fff
â„šī¸ Info

Prerequisites: Java Runtime (Nexus requires JDK 17+). Understanding of build tools like Maven or npm.

Installation

# Download Nexus Repository OSS
wget https://download.sonatype.com/nexus/3/latest-unix.tar.gz
tar xzf latest-unix.tar.gz
sudo mv nexus-3.70.0-01 /opt/nexus

# Create nexus user
sudo useradd --no-create-home --shell /bin/false nexus
sudo chown -R nexus:nexus /opt/nexus

# Start Nexus
sudo -u nexus /opt/nexus/bin/nexus start

# Expected output:
# Starting nexus
# ......

# Check status
sudo -u nexus /opt/nexus/bin/nexus status

# Expected output:
# nexus is running (pid: 12345)

# Access at http://localhost:8081 (admin user password in /opt/nexus/sonatype-work/nexus3/admin.password)

Repository Types

Proxy Repository

# Create a Maven Central proxy repository
# Via UI: Administration > Repository > Repositories > Create repository > maven2 proxy

# Configuration via REST API
curl -u admin:admin -X POST \
  http://localhost:8081/service/rest/v1/repositories/maven/proxy \
  -H "Content-Type: application/json" \
  -d '{
    "name": "maven-central-proxy",
    "online": true,
    "storage": {
      "blobStoreName": "default",
      "strictContentTypeValidation": true
    },
    "proxy": {
      "remoteUrl": "https://repo1.maven.org/maven2/",
      "contentMaxAge": -1,
      "metadataMaxAge": 1440
    },
    "httpClient": {
      "blocked": false,
      "autoBlock": true
    },
    "negativeCache": {
      "enabled": true,
      "timeToLive": 1440
    }
  }'

# Create npm proxy
curl -u admin:admin -X POST \
  http://localhost:8081/service/rest/v1/repositories/npm/proxy \
  -H "Content-Type: application/json" \
  -d '{
    "name": "npmjs-proxy",
    "online": true,
    "storage": {
      "blobStoreName": "default",
      "strictContentTypeValidation": true
    },
    "proxy": {
      "remoteUrl": "https://registry.npmjs.org/",
      "contentMaxAge": 1440,
      "metadataMaxAge": 1440
    },
    "httpClient": {
      "blocked": false,
      "autoBlock": true
    }
  }'

Hosted Repository

# Create a hosted Maven repository for releases
curl -u admin:admin -X POST \
  http://localhost:8081/service/rest/v1/repositories/maven/hosted \
  -H "Content-Type: application/json" \
  -d '{
    "name": "dodatech-releases",
    "online": true,
    "storage": {
      "blobStoreName": "default",
      "strictContentTypeValidation": true,
      "writePolicy": "ALLOW_ONCE"
    },
    "maven": {
      "versionPolicy": "RELEASE",
      "layoutPolicy": "STRICT"
    }
  }'

# Create a hosted repository for snapshots
curl -u admin:admin -X POST \
  http://localhost:8081/service/rest/v1/repositories/maven/hosted \
  -H "Content-Type: application/json" \
  -d '{
    "name": "dodatech-snapshots",
    "online": true,
    "storage": {
      "blobStoreName": "default",
      "strictContentTypeValidation": true,
      "writePolicy": "ALLOW_ONCE"
    },
    "maven": {
      "versionPolicy": "SNAPSHOT",
      "layoutPolicy": "STRICT"
    }
  }'

Group Repository

# Create a group repository combining multiple repos
curl -u admin:admin -X POST \
  http://localhost:8081/service/rest/v1/repositories/maven/group \
  -H "Content-Type: application/json" \
  -d '{
    "name": "dodatech-all",
    "online": true,
    "storage": {
      "blobStoreName": "default",
      "strictContentTypeValidation": true
    },
    "group": {
      "memberNames": [
        "dodatech-releases",
        "dodatech-snapshots",
        "maven-central-proxy]
      ]
    }
  }'

Docker Registry Setup

# Create Docker hosted repository (port 5000)
# Via UI: Create repository > docker (hosted)

curl -u admin:admin -X POST \
  http://localhost:8081/service/rest/v1/repositories/docker/hosted \
  -H "Content-Type: application/json" \
  -d '{
    "name": "docker-hosted",
    "online": true,
    "storage": {
      "blobStoreName": "default",
      "strictContentTypeValidation": true,
      "writePolicy": "ALLOW_ONCE"
    },
    "docker": {
      "httpPort": 5000,
      "v1Enabled": false,
      "forceBasicAuth": true
    }
  }'
# Configure Docker client
echo '{"insecure-registries": ["nexus.dodatech.com:5000"]}' | sudo tee /etc/docker/daemon.json
sudo systemctl restart docker

# Login and push
docker login nexus.dodatech.com:5000
docker tag myapp:latest nexus.dodatech.com:5000/myapp:1.0.0
docker push nexus.dodatech.com:5000/myapp:1.0.0

# Expected output:
# The push refers to repository [nexus.dodatech.com:5000/myapp]
# 2a3b5c7d8e9f: Pushed
# 1.0.0: digest: sha256:abc123... size: 1784

CI/CD Integration

<!-- Maven settings.xml for Nexus -->
<settings>
  <servers>
    <server>
      <id>dodatech-releases</id>
      <username>${env.nexus_user}</username>
      <password>${env.nexus_password}</password>
    </server>
    <server>
      <id>dodatech-snapshots</id>
      <username>${env.nexus_user}</username>
      <password>${env.nexus_password}</password>
    </server>
  </servers>
  <mirrors>
    <mirror>
      <id>nexus-all</id>
      <name>DodaTech Nexus Group</name>
      <url>https://nexus.dodatech.com/repository/dodatech-all/</url>
      <mirrorOf>*</mirrorOf>
    </mirror>
  </mirrors>
</settings>
# GitHub Actions publish to Nexus
jobs:
  publish:
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v3
        with:
          distribution: temurin
          java-version: 21
      - run: mvn deploy
        env:
          nexus_user: ${{ secrets.NEXUS_USER }}
          nexus_password: ${{ secrets.NEXUS_PASSWORD }}
# .npmrc for npm registry
registry=https://nexus.dodatech.com/repository/npmjs-proxy/
//nexus.dodatech.com/repository/dodatech-npm/:_authToken=${NPM_TOKEN}
email=devops@dodatech.com
always-auth=true

Cleanup Policies

# Create cleanup policy via UI: Administration > Repository > Cleanup Policies
cleanupPolicy:
  name: Remove Old Snapshots
  notes: Removes snapshot artifacts older than 30 days
  format: maven2
  criteria:
    lastDownloaded: 30
    lastBlobUpdated: 60
    regex: ".*-SNAPSHOT"
# Create cleanup policy via REST API
curl -u admin:admin -X POST \
  http://localhost:8081/service/rest/v1/repositorySettings/cleanupPolicies \
  -H "Content-Type: application/json" \
  -d '{
    "name": "remove-old-snapshots",
    "notes": "Remove snapshots not downloaded in 30 days",
    "format": "maven2",
    "mode": "delete",
    "criteria": {
      "lastDownloaded": 30,
      "regex": ".*-SNAPSHOT"
    }
  }'

# Apply policy to a repository
curl -u admin:admin -X PUT \
  http://localhost:8081/service/rest/v1/repositories/maven/hosted/dodatech-snapshots \
  -H "Content-Type: application/json" \
  -d '{
    "cleanup": {
      "policyNames": ["remove-old-snapshots"]
    }
  }'

Common Configuration Mistakes

  1. Not configuring cleanup policies: Without cleanup, snapshot artifacts accumulate indefinitely, filling disk space. Set cleanup policies on all snapshot and proxy repositories.

  2. Using ALLOW_ONCE for snapshot repositories: Snapshot repositories need ALLOW_ONCE write policy. Use ALLOW for development repositories where artifacts are re-deployed frequently.

  3. Missing Docker insecure registry configuration: Docker enforces HTTPS by default. Configure insecure-registries in /etc/docker/daemon.json for internal Nexus registries.

  4. Not enabling anonymous read access: Developers and CI systems need read access without authentication for proxy repos. Enable anonymous access in Nexus security settings.

  5. Forgetting to set up blob stores on separate volumes: Default blob store lives on the system disk. Create blob stores on dedicated data volumes for performance and capacity management.

Practice Questions

  1. What is the difference between proxy, hosted, and group repositories? Answer: Proxy caches remote artifacts, hosted stores your own artifacts, group combines multiple repositories into a single endpoint.

  2. How does Nexus improve build speed? Answer: Nexus caches proxied artifacts locally after the first request. Subsequent builds retrieve from the local cache instead of downloading from the internet.

  3. What is a blob store and why is it important? Answer: A blob store is the physical storage backend for artifacts. Separate blob stores on dedicated volumes prevent the system disk from filling up and improve I/O performance.

  4. How do cleanup policies manage disk space? Answer: Cleanup policies automatically delete artifacts based on criteria like age, last download date, or version pattern, preventing unbounded storage growth.

Challenge

Set up a complete Nexus Repository infrastructure: create blob stores on a dedicated data volume, configure Maven Central and npmjs proxy repositories, create hosted repositories for team releases and snapshots, combine them into group repositories, set up a Docker hosted registry on port 5000, configure cleanup policies to remove snapshots older than 30 days, create user accounts with role-based access, integrate Maven builds with Nexus mirroring, and publish npm packages to the hosted Repository.

Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro