DEV Community

Cover image for How to set up a Maven private repository: from install to settings.xml, HOSTED, PROXY, and GROUP
Wen Ping
Wen Ping

Posted on Originally published at anguskit.com

How to set up a Maven private repository: from install to settings.xml, HOSTED, PROXY, and GROUP

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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.xml mirror); deploy via HOSTED (pom.xml distributionManagement).
  • 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.

Reference articles

Top comments (0)