Artifact Repository Foundations, Package Supply Chains, Components, Assets, and Repository Managers: Guided Hands-On Workflow and Core Operations
Turn the Nexus mental model into a disposable, evidence-driven workflow: create a hosted repository, upload a synthetic asset, trace a proxy request, inspect state, and clean up safely.
Learning objectives
- Run a disposable Nexus workflow without touching production repositories or credentials.
- Create or identify a small hosted repository and prove the component/asset state before and after an upload.
- Trace a harmless external artifact through a Nexus proxy and distinguish cold versus warm proxy behavior.
- Use status, repository, component, asset, search, and HTTP evidence to prove causality.
- Keep package-client cache state separate from Nexus proxy cache state.
- Clean up only the synthetic repositories/files created for the lab.
Lab boundary. Use a disposable self-hosted Community instance on loopback/private networking. Chapter 02 covers supported installation patterns; this lesson assumes an instructor/prepared local instance or uses the fixture-only fallback below. Never point these write steps at an employer repository, public Nexus endpoint, or shared release namespace.
Shell note. The executable workflow is written for
POSIX/Bash. On Windows, use
curl.exe/Invoke-RestMethod,
New-Item/Remove-Item, and
Get-FileHash; keep authentication material in a
permission-restricted temporary file rather than a command-line
password.
1. Preflight: establish identity before mutation
The chapter baseline is Nexus Repository 3.95.2. Record what your actual training instance runs; do not pretend every lab has the same patch. Current Nexus requires Java 21, and official distributions include the recommended bundled Java runtime. If your instance differs, annotate the evidence rather than silently rewriting expected behavior.
mkdir -p nexus-ch01-lab/evidence
cd nexus-ch01-lab
export NX_URL="http://127.0.0.1:8081"
curl -i "$NX_URL/service/rest/v1/status" | tee evidence/status.txt
curl -fsS "$NX_URL/service/rest/v1/repositories" | tee evidence/repositories-before.json | python -m json.tool
# Optional read/write service state check. This does not prove disk/DB health.
curl -i "$NX_URL/service/rest/v1/status/writable" | tee evidence/writable.txt
A 200 from /status means Nexus can answer read
requests; Sonatype explicitly warns that status endpoints are not
hardware/database/disk health checks. That distinction prevents a
green HTTP probe from being misreported as “the repository is
healthy.”
2. Create one disposable Raw hosted repository
Use the Nexus UI so you can see the repository recipe and storage choice without memorizing an API payload. Navigate to Settings → Repository → Repositories → Create repository → raw (hosted). Names can differ slightly between Nexus One and Classic UI, but the repository recipe and semantics are the same.
Create academy-ch01-raw on a disposable/local blob
store. Do not reuse a production blob store for training. Keep the
default write policy unless you intentionally want a write-once
demonstration later. Record the repository name, format, type, URL,
and blob store in evidence/repository-created.txt.
Re-run the repositories API and verify a new object with
format: raw and type: hosted appears. This
is the first causality check: the UI action changed repository
configuration; it did not yet create a component or asset.
curl -fsS "$NX_URL/service/rest/v1/repositories" | tee evidence/repositories-after-create.json | python -m json.tool
# There should be no lab content yet.
curl -fsS "$NX_URL/service/rest/v1/components?repository=academy-ch01-raw" | tee evidence/raw-components-empty.json | python -m json.tool
3. Upload a synthetic asset and prove what changed
Create a file whose name, contents, and checksum make it obviously non-production. Upload only to the disposable hosted repository. The Components REST API supports Raw uploads with a directory plus one or more asset/file fields.
mkdir -p payload
printf '%s\n' 'DevOps Academy synthetic artifact - CH01 - DO NOT DEPLOY' > payload/academy-note-1.0.0.txt
sha256sum payload/academy-note-1.0.0.txt | tee evidence/local-note.sha256
# Supply disposable credentials interactively or via a local secret mechanism.
read -r -p 'Disposable Nexus username: ' NX_USER
read -r -s -p 'Disposable Nexus password: ' NX_PASS; echo
NX_AUTH_FILE="$(mktemp)"
chmod 600 "$NX_AUTH_FILE"
printf 'machine 127.0.0.1 login %s password %s
' "$NX_USER" "$NX_PASS" > "$NX_AUTH_FILE"
unset NX_PASS
curl --fail-with-body --netrc-file "$NX_AUTH_FILE" -X POST "$NX_URL/service/rest/v1/components?repository=academy-ch01-raw" -F 'raw.directory=/com/example/academy-note/1.0.0' -F 'raw.asset1=@payload/academy-note-1.0.0.txt' -F 'raw.asset1.filename=academy-note-1.0.0.txt'
rm -f "$NX_AUTH_FILE"
unset NX_USER NX_AUTH_FILE
A successful Components API upload returns HTTP 204. The important result is not the status code by itself: inspect repository state afterwards. Sonatype's current component definitions treat every Raw file as a separate component, so this single synthetic file should give you a simple one-component/one-asset case.
curl -fsS "$NX_URL/service/rest/v1/components?repository=academy-ch01-raw" | tee evidence/raw-components-after.json | python -m json.tool
curl -fsS "$NX_URL/service/rest/v1/assets?repository=academy-ch01-raw" | tee evidence/raw-assets-after.json | python -m json.tool
curl -fsS "$NX_URL/repository/academy-ch01-raw/com/example/academy-note/1.0.0/academy-note-1.0.0.txt" -o downloaded-note.txt
sha256sum downloaded-note.txt | tee evidence/downloaded-note.sha256
Compare the local and downloaded SHA-256 values. Equal values demonstrate the retrieved bytes match the uploaded bytes. They do not prove that the content is safe or trusted.
4. Trace a harmless external artifact through a proxy
If your training instance has a Maven Central proxy such as
maven-central, use it. If the repository is named
differently, substitute the actual name from the repositories API.
We use Apache Commons Lang 3.20.0 only as a small public example;
re-check the coordinate if your environment blocks public internet.
sequenceDiagram participant C as Client participant N as Nexus proxy participant U as Upstream C->>N: GET component asset alt Not cached or metadata requires revalidation N->>U: Fetch or revalidate U-->>N: Asset and metadata N-->>C: Asset else Cached and fresh N-->>C: Cached asset end
ART_PATH='org/apache/commons/commons-lang3/3.20.0/commons-lang3-3.20.0.jar'
PROXY_URL="$NX_URL/repository/maven-central/$ART_PATH"
UPSTREAM_URL="https://repo1.maven.org/maven2/$ART_PATH"
# Optional upstream reference. Skip if your lab has no outbound Internet.
curl -fsS "$UPSTREAM_URL" -o upstream.jar
sha256sum upstream.jar | tee evidence/upstream.sha256
# Request through Nexus.
curl -fsS "$PROXY_URL" -o via-nexus-first.jar
sha256sum via-nexus-first.jar | tee evidence/via-nexus-first.sha256
# Repeat. Compare HTTP timing/log evidence rather than claiming a cache hit
# merely because the second command felt faster.
curl -fsS -w 'http=%{http_code} total=%{time_total}\n' "$PROXY_URL" -o via-nexus-second.jar | tee evidence/via-nexus-second-http.txt
sha256sum via-nexus-second.jar | tee evidence/via-nexus-second.sha256
Inspect the proxy repository through the Components/Assets or Search API after the request. Seeing the component/asset in Nexus is stronger evidence that Nexus cached it than observing only the package client. If upstream and proxied byte checksums match, you have byte equality. Do not generalize that to “the upstream is trusted.”
If outbound network is unavailable, create a fixture record containing a synthetic “upstream response,” then walk the same state transition on paper: first request has no cached asset → Nexus obtains it from the remote → blob/metadata appear → second request can be served from local proxy state subject to cache/revalidation rules.
5. Nexus cache is not the package manager cache
| Layer | Location/owner | What a hit proves | How to isolate |
|---|---|---|---|
| Client package cache | Developer/CI agent filesystem | The client already has local bytes. Nexus might not be contacted. | Use a disposable client cache/home or direct HTTP request. |
| Nexus proxy cache | Nexus blob/database state | Nexus has previously obtained/retained proxied content. | Inspect Nexus component/asset state and controlled requests. |
| Hosted repository | Nexus authoritative managed content | An authorized producer/import placed content there. | Inspect publish evidence, repository type, coordinates, digest, and permissions. |
| Upstream repository | External organization/service | The origin currently serves the requested content. | Capture upstream URL, TLS/identity, response and policy; do not infer trust from reachability. |
A warm developer cache can hide a broken Nexus URL. A warm Nexus proxy can hide an upstream outage. Both are useful behavior, but they answer different operational questions. Always state which layer you are testing.
6. Build an evidence packet, not a screenshot collection
For each operation, capture enough state to answer what changed and why. A good packet for this lesson contains:
- status and writable endpoint HTTP responses;
- repository list before/after creating the Raw hosted repository;
- component and asset responses before/after upload;
- local/uploaded/downloaded SHA-256 values;
- proxy component/asset/search results after the external request;
- sanitized client URL configuration and whether its local cache was bypassed;
- a short note identifying credentials used only by scope, never the secret value.
Current Nexus uses SQL search as of 3.88.0; older Elasticsearch-specific assumptions and wildcard behavior can be stale. Use the instance Swagger UI/JSON and current Search API docs rather than relying on old blog examples.
7. Challenge: choose the correct repository control
A team wants to publish com.example:payments-api:2.0.0,
consume Maven Central, and give developers one Maven URL. Choose a
design before clicking anything.
- Which repository type receives the internal release?
- Which type obtains Maven Central content?
- Which type can expose both to Maven clients?
- Which member should generally be searched first if your internal namespace must not escape to public upstreams?
- What routing/namespace control should be planned before relying on group order as a security boundary?
A defensible answer is hosted + proxy + Maven group, with internal hosted content intentionally ordered/routed and routing rules used to keep private namespaces away from public proxies. Group order improves behavior; routing/namespace policy is the stronger explicit control.
8. Verification and cleanup
Verify: you can identify every repository by both format and type; the synthetic Raw upload appears as component/asset state; downloaded bytes match the local file; proxy evidence distinguishes first request from stored state; credentials are absent from evidence files.
Cleanup: in the UI, delete
academy-ch01-raw only if it was created solely for this
lab and no one else uses its blob store. Repository deletion removes
that repository configuration and its components; confirm the target
name before accepting the destructive dialog. Remove
nexus-ch01-lab/ and unset
NX_USER/NX_PASS. Do not delete shared blob
stores, normal package caches, Nexus data directories, or database
files.
Knowledge check
You create a hosted repository, then the Components API is still empty. Is that a failure?
No. Creating repository configuration does not create package content. The empty component list is expected until an upload/publish occurs.
The second proxy download is faster. Is that enough to prove Nexus served a cache hit?
No. Capture Nexus component/asset state, logs/metrics when appropriate, and controlled HTTP evidence. Network and OS/client caches can also change timing.
A Raw upload appears as one component and one asset. Should you assume Maven behaves the same?
No. Raw treats each file as a separate component; Maven commonly groups multiple assets under one component coordinate/version.
Why capture /status/writable separately from
/status?
Read serviceability and writable serviceability are different conditions. A system can respond to reads while being read-only.
A credential accidentally appears in
evidence/curl.txt. What should you do?
Treat it as exposed: remove it from retained artifacts/history, rotate/revoke the disposable credential if it could authenticate, and fix the capture method before continuing.
9. Summary
You moved from vocabulary to causality: repository creation changes configuration; hosted upload creates component/asset/blob/metadata state; proxy requests can create cached state derived from an upstream; client caches remain separate; REST/HTTP/checksum evidence lets you prove what happened; cleanup is scoped to disposable repositories and files.
Official references and version notes
- Nexus Repository 3.95.0–3.95.2 release notes — 3.95.2 was released August 21, 2026 and is the current self-hosted baseline used in this chapter.
- Nexus Repository system requirements — current Java, H2/PostgreSQL, storage, memory, operating-system, and deployment constraints.
- Repository Manager Concepts — components, assets, coordinates, repository formats, proxy behavior, routing, and repository-manager purpose.
- Repository Types — hosted, proxy, and group semantics and group ordering.
- Self-Hosted Nexus Repository Feature Matrix — Community-versus-Pro capability boundaries.
- Nexus Repository API Reference — current REST API surface and embedded Swagger model.
- Status API — readiness and writable-state HTTP checks.
- Search API — component/asset search and the SQL-search behavior used by current releases.
- Components API — listing and uploading components to hosted repositories.
- Assets API — listing and inspecting individual assets.
- Uploading Components — UI upload requirements, hosted-only constraint, and required privileges.
- Creating Repositories — current UI flow and destructive repository-delete behavior.
Version-sensitive statements were rechecked against Sonatype primary documentation on 2026-08-26. The mandatory path remains self-hosted, Community/free-compatible, and disposable; production credentials, production repositories, and paid-only capabilities are outside the lab boundary.
Keep the academy open
Support free, practical DevOps education.
Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0
Send only Ethereum/ERC-20 compatible assets to this
address.