Builds get slower, internal jars travel by chat or shared drives, and one network blip becomes company-wide Could not transfer artifact—usually Maven is fine and the private repository is not wired: service down, wrong repo types, settings.xml / pom.xml ids mismatch, or the token is not in the password field.
This article walks through AngusRepo Community self-hosted in order: install → repos and token → settings.xml for resolve → pom.xml for deploy → verify. Examples use repo.example.com—swap your domain. Deeper 401/409: Maven deploy failure troubleshooting.
1. Install (get a working console)
Prerequisites: Docker Engine + Compose v2; about 2 CPU / 4 GB; open 80; resolve gm.example.com and repo.example.com (labs can use /etc/hosts). Full steps: quickstart.
curl --fail --location --progress-bar -o AngusRepo-Community-1.0.0.zip \
https://repo.anguskit.com/raw/raw-public/AngusKit/repo/AngusRepo-Community-1.0.0.zip
unzip AngusRepo-Community-1.0.0.zip
cd AngusRepo-1.0.0
./install.sh
Wizard aligned with quickstart: Compose; Access → 2 (bundled proxy); TLS → 4 (HTTP :80); Database → Compose MySQL; Public DNS name → suffix such as example.com. After Install finished.:
./bin/angusctl.sh doctor # wait for doctor: OK
Open http://gm.example.com/, then http://repo.example.com/. Windows: curl.exe + .\install.bat. For HTTPS see Installation.
The rest assumes HTTP self-hosted with URLs like http://repo.example.com/.... After trusted TLS, switch to https://. Once the console opens, create repos and a token before client config.
2. Repos, token, and topology
mvn deploy only goes to HOSTED; PROXY and GROUP are read-only. On http://repo.example.com/, create (names are examples—keep them consistent):
| Example name | Type | Role |
|---|---|---|
maven-releases |
HOSTED | Releases; disable overwrite |
maven-snapshots |
HOSTED | SNAPSHOTs; allow same-version overwrite |
maven-central-proxy |
PROXY | Proxy Maven Central (https://repo1.maven.org/maven2/) |
maven-group |
GROUP | Unified pull entry; member order release → snapshot → proxy |
Prefer GROUP member order releases → snapshots → proxy: artifact binaries use first-match; maven-metadata.xml version lists merge versions already registered on each member. Developers configure one pull URL; keep Release and SNAPSHOT in separate HOSTED repos for immutability and cleanup.
Also prepare:
- [ ] Access token (shown once—save it)
- [ ] CI has Write on both HOSTED repos; developers have Read on
maven-group - [ ] GROUP member order is releases → snapshots → central-proxy
export REPO_USER="admin" # console username, not the token name
export REPO_TOKEN="your_access_token" # every password field uses the token
export REPO_HOST="repo.example.com" # your repo.<domain>
Prefer console “connection config”; field detail: Maven format manual.
3. Resolve: settings.xml
Point dependency traffic at GROUP with a mirror. Save as a project-local settings.xml, or merge into ~/.m2/settings.xml <servers> / <mirrors>—do not overwrite the whole file.
<settings>
<mirrors>
<mirror>
<id>angus-maven-group</id>
<mirrorOf>*</mirrorOf>
<url>http://repo.example.com/maven/maven-group/</url>
</mirror>
</mirrors>
<servers>
<server>
<id>angus-maven-group</id>
<username>${env.REPO_USER}</username>
<password>${env.REPO_TOKEN}</password>
</server>
<server>
<id>angus-maven-releases</id>
<username>${env.REPO_USER}</username>
<password>${env.REPO_TOKEN}</password>
</server>
<server>
<id>angus-maven-snapshots</id>
<username>${env.REPO_USER}</username>
<password>${env.REPO_TOKEN}</password>
</server>
</servers>
</settings>
Password field = token. <server> ids must exactly match the ids used in pom.xml / the mirror (case-sensitive), or you get 401.
4. Deploy: pom.xml
Publish targets must be HOSTED—not GROUP or PROXY.
<distributionManagement>
<repository>
<id>angus-maven-releases</id>
<url>http://repo.example.com/maven/maven-releases/</url>
</repository>
<snapshotRepository>
<id>angus-maven-snapshots</id>
<url>http://repo.example.com/maven/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
5. Verify the loop
# Resolve via GROUP; first hit may go upstream, second should hit PROXY cache
mvn -s settings.xml dependency:resolve
# Deploy into the matching HOSTED repo
mvn -s settings.xml clean deploy
The console artifact list should show the new version; resolving the same coordinates via GROUP should succeed. In CI, inject REPO_USER / REPO_TOKEN and reuse the same settings.xml. Pipelines: Jenkins build, test, publish. Gradle against the same repos is a separate post.
6. Day-two ops (after resolve / deploy works)
SNAPSHOT cleanup — keep the last N versions per artifact; Dry Run first—cleanup. Keep Release immutable; redeploying the same release yields 409.
Cold PROXY — first Central pulls are slow; warm frequently used dependencies if needed.
Ingest checks — uploads get a light admission gate; deeper vuln/license work can use an external scanner. Clear false positives before enabling block—admission gates and SBOM.
Error cheat sheet
| Symptom | Likely cause | Fix |
|---|---|---|
401 Unauthorized |
server id mismatch or expired token | Align ids; token in password field; deploy troubleshooting |
409 Conflict |
Redeploying a release | Bump the version |
Central has it but 404
|
Wrong GROUP order or PROXY failure | Check members and PROXY health |
| Stale SNAPSHOT | Local ~/.m2 cache |
mvn -U or delete the local path |
| First resolve very slow | Cold PROXY | Expected; warm hot dependencies |
Field detail: Maven format manual. More ops issues: troubleshooting manual.
FAQ
Can I deploy to a GROUP?
No. GROUP / PROXY are read-only; deploy only to HOSTED.
Why split Release and SNAPSHOT?
Releases should be immutable; SNAPSHOTs allow same-version overwrite and different cleanup. Mixing them complicates both.
Must the mirror id match a server id?
Yes. Mirror, distributionManagement, and the matching <server> ids must align for Maven to attach credentials.
Takeaways
- Install and open the console → two HOSTED + PROXY + GROUP → issue a token.
- Resolve via GROUP (
settings.xmlmirror); deploy via HOSTED (pom.xmldistributionManagement). - Id alignment + token in the password field prevent most 401s; never overwrite a Release.
- After the path works, set SNAPSHOT cleanup and PROXY warm-up.
Top comments (0)