Blob Stores, Storage Layout, Database Choices, Capacity Planning, and Data Separation: Guided Hands-On Workflow and Core Operations
Inspect blob stores and database mode, create disposable file blob stores and hosted repositories, measure deterministic growth, and move exact accepted bytes without touching Nexus internals.
Learning objectives
- Capture before-state for blob stores, repositories, database mode, and free disk.
- Create two disposable file blob stores and deliberately map Raw hosted repositories to them.
- Generate deterministic payloads and compare expected bytes with Nexus used-size/blob-count evidence.
- Transfer the exact Nexus-served bytes into another hosted repository while preserving SHA-256 identity.
- Distinguish the free Community workflow from the Pro-only Change Repository Blob Store task and clean up safely.
Current lab baseline (reviewed 2026-08-26): Nexus
Repository Community Edition 3.94.1-06, Java 21, loopback-only HTTP,
a dedicated non-root/non-administrator process identity, and
embedded H2 only for the disposable local instance. Sonatype
currently recommends external PostgreSQL for production deployments.
The lab never treats a blob store as a database backup or
manipulates $data-dir/blobs or database files directly.
Lab scope: use only the disposable loopback
instance. The names academy-ch05-fast,
academy-ch05-capacity, academy-ch05-hot,
and academy-ch05-archive are reserved for this lesson.
Never point these steps at a production data directory or valuable
repository.
1. Preflight: prove the instance is writable and has headroom
Storage work begins with evidence. Save the service writable state, existing blob stores, repositories, and free disk. If the lab host is close to the 4 GB emergency threshold, stop instead of using the lesson to “see what happens.”
# POSIX/Bash. Use only against the disposable loopback instance.
LAB="$HOME/nexus-ch05-lab"
NX_URL="http://127.0.0.1:8081"
mkdir -p "$LAB/evidence" "$LAB/payload" "$LAB/move"
umask 077
read -rsp "Disposable Nexus admin password: " NX_PASS; printf "\n"
printf 'machine 127.0.0.1 login admin password %s\n' "$NX_PASS" > "$LAB/nexus.netrc"
unset NX_PASS
NETRC="$LAB/nexus.netrc"
# Never print, commit, or reuse this temporary credential file.
curl -fsS "$NX_URL/service/rest/v1/status/writable" | tee "$LAB/evidence/01-writable.txt"
curl --fail-with-body --silent --show-error --netrc-file "$NETRC" "$NX_URL/service/rest/v1/blobstores" | tee "$LAB/evidence/02-blobstores-before.json"
curl --fail-with-body --silent --show-error --netrc-file "$NETRC" "$NX_URL/service/rest/v1/repositories" | tee "$LAB/evidence/03-repositories-before.json"
df -h "$HOME" | tee "$LAB/evidence/04-disk-before.txt"
Windows PowerShell: use the same loopback URLs
with curl.exe. Keep the disposable credential in a
user-only temporary credential mechanism rather than embedding a
password in command history. Use
Get-FileHash -Algorithm SHA256 for hashes and
Get-Volume/Get-PSDrive for free-space
evidence. Do not run Nexus as Administrator merely to bypass a
permissions problem.
From Settings → Support → System Information, record the database mode. The Chapter 02 disposable baseline is H2. This inspection is intentionally product-level; do not read or modify database internals.
2. Create two file blob stores through Nexus
Navigate to Settings → Repository → Blob Stores → Create Blob Store → File. Create these two stores with no soft quota yet:
| Blob store | File path | Reason |
|---|---|---|
academy-ch05-fast |
academy-ch05-fast (relative lab path) |
Hot/source content for measured writes. |
academy-ch05-capacity |
academy-ch05-capacity (relative lab path)
|
Separate destination so repository placement is observable. |
A relative file path is Nexus-managed under the configured data/blob area. The process account must have access. Do not pre-create internal blob files or fix a permission problem by switching Nexus to root.
curl --fail-with-body --silent --show-error --netrc-file "$NETRC" "$NX_URL/service/rest/v1/blobstores" | tee "$LAB/evidence/05-blobstores-created.json"
for b in academy-ch05-fast academy-ch05-capacity; do
curl --fail-with-body --silent --show-error --netrc-file "$NETRC" "$NX_URL/service/rest/v1/blobstores/file/$b" | tee "$LAB/evidence/06-$b-config.json"
done
The returned path/configuration is the supported source of truth for this exercise. There is no need to open blob-store property files.
3. Map repositories to blob stores
Create two raw (hosted) repositories through Settings → Repository → Repositories:
| Repository | Blob store | Write policy | Purpose |
|---|---|---|---|
academy-ch05-hot |
academy-ch05-fast |
Allow | Source of synthetic growth. |
academy-ch05-archive |
academy-ch05-capacity |
Allow once | Destination that models stricter release/archive placement. |
The mapping itself is database/configuration state. It does not copy content. The blob store grows when repository assets are written.
curl --fail-with-body --silent --show-error --netrc-file "$NETRC" "$NX_URL/service/rest/v1/repositorySettings" > "$LAB/evidence/07-repository-settings-after.json"
python3 - <<'PY'
import json, pathlib
p = pathlib.Path.home()/"nexus-ch05-lab/evidence/07-repository-settings-after.json"
for r in json.loads(p.read_text()):
if r.get("name") in {"academy-ch05-hot", "academy-ch05-archive"}:
print(json.dumps(r, indent=2, sort_keys=True))
PY
4. Generate deterministic measurable content
Create harmless files whose size and SHA-256 are known before publication. No package hooks or public upstreams are involved.
python3 - <<'PY'
from pathlib import Path
import hashlib
root = Path.home()/"nexus-ch05-lab/payload"
root.mkdir(parents=True, exist_ok=True)
for mib, byte in [(1,b"A"), (2,b"B"), (4,b"C")]:
p = root/f"payload-{mib}MiB.bin"
p.write_bytes(byte * (mib*1024*1024))
print(p.name, p.stat().st_size, hashlib.sha256(p.read_bytes()).hexdigest())
PY
sha256sum "$LAB"/payload/*.bin | tee "$LAB/evidence/08-local-sha256.txt"
wc -c "$LAB"/payload/*.bin | tee "$LAB/evidence/09-local-bytes.txt"
5. Measure blob stores before and after publication
Save the pre-write blob-store view, then publish all three files
only to the hosted academy-ch05-hot repository. Raw
hosted repositories support direct HTTP PUT.
curl --fail-with-body --silent --show-error --netrc-file "$NETRC" "$NX_URL/service/rest/v1/blobstores" | tee "$LAB/evidence/10-blobstores-pre-upload.json"
for f in "$LAB"/payload/*.bin; do
name="$(basename "$f")"
curl --fail-with-body --silent --show-error --netrc-file "$NETRC" --upload-file "$f" "$NX_URL/repository/academy-ch05-hot/growth/$name"
done
curl --fail-with-body --silent --show-error --netrc-file "$NETRC" "$NX_URL/service/rest/v1/blobstores" | tee "$LAB/evidence/11-blobstores-post-upload.json"
curl --fail-with-body --silent --show-error --netrc-file "$NETRC" "$NX_URL/service/rest/v1/assets?repository=academy-ch05-hot" | tee "$LAB/evidence/12-hot-assets.json"
Do not expect Used Size to increase by exactly 7 MiB.
Blob stores include per-blob properties/metadata and filesystem
allocation overhead. The important causal observation is that the
store assigned to academy-ch05-hot changes while the
untouched destination store does not acquire those assets.
6. Community-compatible relocation: move accepted bytes, not internals
The current Admin - Change repository blob store task is Pro-only. Community learners should not simulate it by copying obfuscated blob files. Instead, model a safe content transition at the repository interface: download the exact accepted object from the source repository, verify its SHA-256, and publish the same bytes to the intentionally mapped destination repository.
SRC="$NX_URL/repository/academy-ch05-hot/growth/payload-4MiB.bin"
DST="$NX_URL/repository/academy-ch05-archive/release/payload-4MiB.bin"
curl --fail-with-body --silent --show-error "$SRC" -o "$LAB/move/retrieved-4MiB.bin"
sha256sum "$LAB/payload/payload-4MiB.bin" "$LAB/move/retrieved-4MiB.bin" | tee "$LAB/evidence/13-before-transfer-sha256.txt"
cmp "$LAB/payload/payload-4MiB.bin" "$LAB/move/retrieved-4MiB.bin"
curl --fail-with-body --silent --show-error --netrc-file "$NETRC" --upload-file "$LAB/move/retrieved-4MiB.bin" "$DST"
curl --fail-with-body --silent --show-error "$DST" -o "$LAB/move/archive-4MiB.bin"
sha256sum "$LAB/move/retrieved-4MiB.bin" "$LAB/move/archive-4MiB.bin" | tee "$LAB/evidence/14-after-transfer-sha256.txt"
cmp "$LAB/move/retrieved-4MiB.bin" "$LAB/move/archive-4MiB.bin"
This is not the same operation as changing a repository’s backing blob store. It is a free-path teaching model for exact-byte content movement. A Pro operator performing a real repository backing-store change must use the documented task and its version/database prerequisites.
7. Observe storage and quota signals
Capture final blob counts/used size and the destination quota-status endpoint. With no quota configured, the endpoint should not report a violation. Lesson 4 deliberately introduces a soft-quota warning without exhausting disk.
curl --fail-with-body --silent --show-error --netrc-file "$NETRC" "$NX_URL/service/rest/v1/blobstores" | tee "$LAB/evidence/15-blobstores-final.json"
curl --fail-with-body --silent --show-error --netrc-file "$NETRC" "$NX_URL/service/rest/v1/blobstores/academy-ch05-capacity/quota-status" | tee "$LAB/evidence/16-destination-quota.json"
df -h "$HOME" | tee "$LAB/evidence/17-disk-after.txt"
8. Challenge: choose the control before changing state
Your hot store is projected to fill in six weeks, but the repository itself is healthy. Which control belongs to which edition?
- If you only need a Community learning path, create new storage/repository placement and move exact accepted content through supported repository endpoints.
- If production requires changing the backing blob store of an existing repository, evaluate the documented Pro-only Change Repository Blob Store task and its prerequisites.
- If the actual problem is merely early warning, use capacity monitoring/soft quota—not content movement—as the first control.
9. Pause or clean up
If you are continuing directly to Lesson 4, keep these four disposable objects because that lesson can use them. Otherwise delete the repositories first through Settings → Repository → Repositories, then delete the now-unused blob stores through Settings → Repository → Blob Stores. Nexus will not allow deletion of a blob store still in use. Never remove its files manually.
# Always remove the temporary credential file when you finish this session.
rm -f "$NETRC"
unset NETRC
Knowledge check
Why did only academy-ch05-fast grow after the first three uploads?
The hot repository was mapped to that blob store. Repository configuration determines which blob backend receives its new assets.
Why is the exact 7 MiB payload total not expected to equal the blob store Used Size delta?
Blob stores include additional properties/metadata and filesystem allocation overhead.
Can Community Edition use the Change Repository Blob Store task?
No. Current Sonatype documentation marks that task as Pro-only.
What evidence proves the transferred release object preserved identity?
The source/retrieved/destination SHA-256 values match and byte comparison succeeds.
Should a nearly full store be fixed by deleting files under its blob path?
No. Use supported Nexus cleanup/storage/repository operations and preserve evidence first.
10. Summary
You mapped repositories to independent stores, measured causal growth, and moved exact accepted bytes without touching internal storage. The next lesson turns those observations into production architecture tradeoffs.
Official references and version notes
- Nexus Repository Download and 2026 self-hosted release notes — current downloadable/GA baseline.
- System Requirements — Java 21, H2/PostgreSQL guidance, file handles, disk threshold, and filesystem support.
- Database Options — embedded H2 versus external PostgreSQL.
- Directories — application and persistent data directory responsibilities.
- Storage Guide and Storage Planning — blob-store layouts, sizing, and performance implications.
- Blob Stores — blob count, used size, path, state, soft quotas, and lifecycle constraints.
- Blob Store API and REST API Reference — supported inspection/configuration endpoints.
- Change Repository Blob Store — supported Pro-only repository relocation task.
- Self-Hosted Feature Matrix — edition boundaries for storage and database capabilities.
- AWS S3 Blob Store — object-storage deployment guidance.
- Raw Repositories — hosted Raw repositories and HTTP PUT publication.
Version-sensitive statements were rechecked against Sonatype primary documentation on 2026-08-26. The current Download, versions-status, and 2026 release-notes pages list 3.94.1 as the newest GA/downloadable self-hosted line. Mandatory labs therefore pin Nexus Repository Community Edition 3.94.1-06 on loopback with Java 21 and embedded H2 only as a disposable learning database. Current system requirements recommend external PostgreSQL for supported production-scale deployments and require at least 4 GB of free disk at all times. Learners should re-check the live pages before executing the lab because Nexus support matrices evolve.
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.