Chapter 01Lesson 05~150 minutes

Checkpoint Lab — Artifact Repository Foundations, Package Supply Chains, Components, Assets, and Repository Managers

Complete an integrated multi-ecosystem checkpoint: publish synthetic Maven and npm artifacts, prove coordinates and bytes, map trust boundaries, inject a safe failure, and clean up.

Checkpoint labMaven & npmEvidence packetChecksumsCleanup

Learning objectives

  • Map a small multi-ecosystem supply chain from producer to hosted repository to consumer.
  • Publish only synthetic Maven and npm artifacts to disposable hosted repositories.
  • Record component coordinates, assets, metadata, checksums, repository type, and trust boundaries.
  • Predict repository and blob/metadata state changes before executing them.
  • Produce an evidence packet that distinguishes Nexus state from client-local state.
  • Clean up the entire lab without touching shared repositories, blob stores, databases, or production credentials.

Checkpoint safety. This lab creates and deletes repository content. Use only a disposable local Community instance or a dedicated training namespace explicitly approved for deletion. The artifact names contain academy-ch01 and DO_NOT_DEPLOY by design. If you cannot obtain an isolated Nexus instance, complete the fixture/simulation path and mark execution evidence as simulated rather than using a production server.

Shell note. Executable examples use POSIX/Bash. On Windows, use equivalent PowerShell filesystem/hash commands plus curl.exe or Invoke-RestMethod; store temporary credentials in a private file and delete it immediately after each authenticated request.

1. Scenario and success criteria

You are onboarding a small service team that produces a Java library and a JavaScript utility. The team must understand what Nexus stores, how two package ecosystems differ, and why release evidence needs both logical coordinates and exact byte identity. You will create one disposable Maven hosted repository and one disposable npm hosted repository, upload synthetic packages, consume/inspect them through controlled endpoints, and then remove only the lab state.

Checkpoint supply chain
flowchart LR
JM[Java producer] --> MH[Maven hosted repository]
NP[JavaScript producer] --> NH[npm hosted repository]
MH --> NX[Nexus Repository service]
NH --> NX
NX --> JC[Java consumer]
NX --> NC[npm consumer]
NX --> DB[(Database metadata)]
NX --> BLOB[(Blob store bytes)]
CI[Future CI publisher] -. scoped credentials .-> NX

Pass conditions: exact repository format/type is recorded; both synthetic packages are visible as components/assets; locally calculated and downloaded package checksums match; no production secret/URL appears; client caches are identified separately; the evidence packet can explain every mutation; cleanup removes only the two lab repositories and local files.

2. Preflight and environment record

The content baseline is Nexus 3.95.2, released August 21, 2026. Your instance may be another supported version, so record it. Current Nexus requires Java 21; official installers/images normally include the recommended Java runtime. The lab itself does not require Pro features.

mkdir -p nexus-ch01-checkpoint/{evidence,maven,npm,downloads}
cd nexus-ch01-checkpoint
export NX_URL="http://127.0.0.1:8081"

curl -i "$NX_URL/service/rest/v1/status"   | tee evidence/01-status.txt
curl -i "$NX_URL/service/rest/v1/status/writable"   | tee evidence/02-writable.txt
curl -fsS "$NX_URL/service/rest/v1/repositories"   | tee evidence/03-repositories-before.json   | python -m json.tool

printf 'Nexus baseline checked: 3.95.2 / 2026-08-26\n'   > evidence/00-version-assumptions.txt

Before creating anything, predict and write down these state changes:

  1. Creating two repositories will change repository configuration but create no package components yet.
  2. Uploading a Maven component may create multiple assets for one logical component; uploading an npm tarball creates an npm component with format metadata indexed by Nexus.
  3. Downloading from Nexus should not change the authoritative hosted package bytes, although access metadata/logs may change and the client may create local cache state.

3. Create two disposable hosted repositories

In the training UI, navigate to Settings → Repository → Repositories → Create repository. Create:

  • academy-ch01-maven using maven2 (hosted).
  • academy-ch01-npm using npm (hosted).

Use only a disposable/local blob store. Do not enable a Pro-only workflow merely for the lab. After creation, inspect the repositories API and confirm the two entries are hosted and have the intended formats.

curl -fsS "$NX_URL/service/rest/v1/repositories"   | tee evidence/04-repositories-after.json   | python -m json.tool

curl -fsS "$NX_URL/service/rest/v1/components?repository=academy-ch01-maven"   | tee evidence/05-maven-empty.json   | python -m json.tool
curl -fsS "$NX_URL/service/rest/v1/components?repository=academy-ch01-npm"   | tee evidence/06-npm-empty.json   | python -m json.tool

4. Build and upload a synthetic Maven component

No Maven build is required to learn repository semantics. Create a tiny JAR-shaped archive with the JDK jar tool and an explicit POM, then upload both as one Maven component through the Components API. The content is non-executable training data.

cd maven
mkdir -p payload/META-INF
printf '%s\n' 'DevOps Academy CH01 synthetic Maven payload - DO_NOT_DEPLOY'   > payload/README.txt
jar --create --file academy-ledger-1.0.0.jar -C payload .

cat > academy-ledger-1.0.0.pom <<'EOF'
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example.academy</groupId>
  <artifactId>academy-ledger</artifactId>
  <version>1.0.0</version>
  <packaging>jar</packaging>
  <name>DevOps Academy synthetic checkpoint</name>
</project>
EOF

sha256sum academy-ledger-1.0.0.jar academy-ledger-1.0.0.pom   | tee ../evidence/07-maven-local.sha256
cd ..

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-maven"   -F 'maven2.groupId=com.example.academy'   -F 'maven2.artifactId=academy-ledger'   -F 'maven2.version=1.0.0'   -F 'maven2.asset1=@maven/academy-ledger-1.0.0.jar'   -F 'maven2.asset1.extension=jar'   -F 'maven2.asset2=@maven/academy-ledger-1.0.0.pom'   -F 'maven2.asset2.extension=pom'

rm -f "$NX_AUTH_FILE"
unset NX_USER NX_AUTH_FILE

Expected REST result is HTTP 204 for a successful component upload. Then list the component and assets. Predict that one Maven component at GAV com.example.academy:academy-ledger:1.0.0 owns at least the uploaded JAR and POM assets; additional generated checksum/metadata behavior depends on format/version and should be observed rather than invented.

curl -fsS "$NX_URL/service/rest/v1/components?repository=academy-ch01-maven"   | tee evidence/08-maven-components.json | python -m json.tool
curl -fsS "$NX_URL/service/rest/v1/assets?repository=academy-ch01-maven"   | tee evidence/09-maven-assets.json | python -m json.tool

curl -fsS   "$NX_URL/repository/academy-ch01-maven/com/example/academy/academy-ledger/1.0.0/academy-ledger-1.0.0.jar"   -o downloads/academy-ledger-1.0.0.jar
sha256sum downloads/academy-ledger-1.0.0.jar   | tee evidence/10-maven-downloaded.sha256

5. Build and upload a synthetic npm component

The npm path demonstrates a different coordinate model: package name + version rather than Maven GAV. Use the free npm CLI only to pack the synthetic tarball; upload it through the same Nexus Components API so no npm login/token workflow is required in this chapter.

cd npm
cat > package.json <<'EOF'
{
  "name": "academy-ch01-widget",
  "version": "1.0.0",
  "description": "DevOps Academy synthetic Nexus checkpoint - DO_NOT_DEPLOY",
  "main": "index.js",
  "license": "UNLICENSED",
  "private": false
}
EOF
printf '%s\n' 'module.exports = "DO_NOT_DEPLOY";' > index.js

# npm pack is free/local; it creates academy-ch01-widget-1.0.0.tgz.
npm pack
sha256sum academy-ch01-widget-1.0.0.tgz   | tee ../evidence/11-npm-local.sha256
cd ..

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-npm"   -F 'npm.asset=@npm/academy-ch01-widget-1.0.0.tgz'
rm -f "$NX_AUTH_FILE"
unset NX_USER NX_AUTH_FILE

curl -fsS "$NX_URL/service/rest/v1/components?repository=academy-ch01-npm"   | tee evidence/12-npm-components.json | python -m json.tool
curl -fsS "$NX_URL/service/rest/v1/assets?repository=academy-ch01-npm"   | tee evidence/13-npm-assets.json | python -m json.tool

If Node/npm is unavailable, do not install random tooling solely to make the checkbox green. Use an instructor-provided synthetic .tgz fixture or complete the npm half as a clearly marked simulation: inspect the Components API documentation showing npm.asset, predict the state, and retain “not executed — npm unavailable” in the evidence packet.

6. Compare the two ecosystems without forcing one model onto the other

Question Maven example npm example
Coordinate com.example.academy:academy-ledger:1.0.0 academy-ch01-widget@1.0.0
Primary upload JAR + POM uploaded as assets of one Maven component Package .tgz uploaded as npm component asset; Nexus indexes package metadata.
Client protocol Maven repository path + POM/metadata conventions npm registry protocol/metadata.
Hosted authority academy-ch01-maven academy-ch01-npm
Byte identity SHA-256 of JAR/POM assets SHA-256 of package tarball
Do not infer JAR checksum does not prove trusted build/provenance Tarball checksum does not prove trusted publisher/package safety

The common Nexus abstraction helps operations: repositories have format/type, components have logical identity, assets have files/checksums, and APIs expose state. The ecosystem-specific coordinate and metadata rules still matter. This is the right balance between a universal repository mental model and protocol-specific correctness.

7. Controlled consumption and independent verification

For Maven, direct HTTP retrieval gives a deterministic checkpoint without requiring a full Maven project. For npm, you can either download the asset URL returned by the Assets API or, if your disposable account/realm/client configuration is already prepared, use the npm registry URL. In either case, calculate the downloaded SHA-256 and compare it to the producer-side record.

# Extract download URLs without assuming exact server-generated paths.
python - <<'PY2'
import json
for fn in ['evidence/09-maven-assets.json','evidence/13-npm-assets.json']:
    data=json.load(open(fn, encoding='utf-8'))
    print(fn)
    for item in data.get('items',[]):
        print(' ', item.get('path'), item.get('downloadUrl'), item.get('checksum'))
PY2

# Keep the evidence packet secret-free.
grep -RniE '(password|token-FAKE_DO_NOT_USE|Authorization:|_auth=)' evidence   && echo 'Review matches before retaining evidence' || true

The best verification is independent: compare producer-side digest, Nexus-reported checksum when available, and digest of bytes downloaded from Nexus. If they disagree, stop and diagnose; do not rewrite the expected checksum.

8. Trust-boundary map and evidence packet

Create evidence/14-trust-boundaries.md with these rows:

Boundary Credential / identity Evidence Failure question
Producer → Maven hosted Disposable publisher HTTP upload response + component/assets + digest Was the publisher authorized for this repository/coordinate?
Producer → npm hosted Disposable publisher Upload response + component/assets + tarball digest Did the uploaded package metadata identify the expected name/version?
Consumer → Nexus Anonymous or scoped reader Download URL/status + downloaded digest Did the consumer reach Nexus rather than a local cache/direct upstream?
Nexus → database/blob Nexus service identity Conceptual state map; no direct edits Can metadata and bytes be recovered consistently?
Future CI → Nexus Scoped non-human identity Design note only in Ch01 How would secret rotation and least privilege be enforced?

The packet should include repository lists before/after, component/assets JSON, producer and consumer checksums, environment/version assumptions, and a short decision note. Screenshots may supplement, but machine-readable API evidence is easier to compare and sanitize.

9. Failure injection: predict first, then observe

Pick one safe failure. Recommended: change the Maven download URL from academy-ch01-maven to academy-ch01-mavne (intentional typo). Predict: no repository with that name exists; hosted component/blob state should not change; the client request should fail at routing/not-found before authorization or component lookup matters.

curl -sS -D evidence/15-typo-headers.txt   -o evidence/15-typo-body.txt   -w 'http=%{http_code}\n'   "$NX_URL/repository/academy-ch01-mavne/com/example/academy/academy-ledger/1.0.0/academy-ledger-1.0.0.jar"   | tee evidence/15-typo-summary.txt

# Correct only the repository name and verify again.
curl -fsS   "$NX_URL/repository/academy-ch01-maven/com/example/academy/academy-ledger/1.0.0/academy-ledger-1.0.0.jar"   -o downloads/academy-ledger-retry.jar
sha256sum downloads/academy-ledger-retry.jar   | tee evidence/16-retry.sha256

If your observation differs from the prediction, preserve it and explain the actual layer reached. The exercise is about causal reasoning, not forcing a predetermined HTTP code.

10. Cleanup and rollback

Before deleting anything, list repositories again and confirm the exact two lab names. In the UI, delete only academy-ch01-maven and academy-ch01-npm if they were created solely for this checkpoint. Repository deletion is destructive; never select a similarly named shared repository. Do not delete or compact the blob store as part of Chapter 01.

unset NX_USER NX_PASS
cd ..
# Retain evidence if desired; otherwise remove only the checkpoint directory.
# rm -rf nexus-ch01-checkpoint

# Never substitute commands that delete Nexus data directories,
# database files, shared blob stores, or normal package-manager caches.

Rollback verification: the two lab repository names no longer appear in the repository list; no unrelated repository disappeared; the Nexus status endpoint remains serviceable; all retained evidence is sanitized.

11. What Chapter 01 adds to the operating model

You can now reason about Nexus without hiding behind UI clicks. You know what is authoritative, what is cached, how logical component identity differs from asset bytes, why protocols remain format-specific, which state changes when a repository/package is created, and how to prove those changes through APIs/checksums. That model is the prerequisite for installing and operating Nexus correctly rather than treating it as a generic file server.

Knowledge check

The Maven and npm components both have version 1.0.0. Are they the same coordinate?

After deleting the two hosted repositories, should you manually remove their blob files to “finish cleanup”?

Your downloaded JAR digest matches the producer digest, but the source commit is unknown. Is provenance complete?

The npm CLI is unavailable. What is better: install an unverified binary from a random URL or mark the npm execution simulated using the official API schema?

Why did the typo failure not require cache deletion?

Which chapter comes next, and why?

12. Summary

The checkpoint joined two ecosystems behind one repository-management discipline: hosted authorities, format-specific coordinates, component/assets evidence, exact byte digests, scoped publisher/consumer trust boundaries, API-based verification, predicted failure behavior, and controlled cleanup. You are ready to move from logical repository behavior to supported Nexus deployment architecture.

Next chapter

Nexus Repository Editions, Deployment Models, Architecture, Installation, and Java Runtime Planning: Concepts, Architecture, and Mental Model

Chapter 02 turns this logical model into a supported runtime: editions, deployment models, process architecture, Java 21, database/blob planning, installation boundaries, and version-aware operations.

Official references and version notes

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.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.