Integration¶
Le miroir Nexus ne sert à rien si les clients ne l'utilisent pas. Ce chapitre detaille la configuration de chaque ecosysteme pour pointer vers le miroir interne, l'integration dans les pipelines CI/CD et la mise en place des notifications.
Configuration des clients¶
Docker / Podman¶
Configuration du daemon Docker¶
Le daemon Docker peut etre configure pour utiliser un registre miroir au lieu de Docker Hub :
// /etc/docker/daemon.json
{
"registry-mirrors": [
"https://docker-group.internal.company.io"
],
"insecure-registries": []
}
# Recharger le daemon
systemctl restart docker
# Verifier la configuration
docker info | grep -A 5 "Registry Mirrors"
Authentification¶
# Se connecter au registre interne
docker login docker.internal.company.io
# Username: <compte-service-ou-personnel>
# Password: <mot-de-passe-nexus>
# Le fichier ~/.docker/config.json est mis a jour automatiquement
Pull via le miroir¶
# Pull standard (passe par le miroir grace a registry-mirrors)
docker pull alpine:latest
# Pull explicite depuis le miroir
docker pull docker-group.internal.company.io/library/alpine:latest
# Push vers le depot hosted
docker tag myapp:v1.0.0 docker.internal.company.io/myapp:v1.0.0
docker push docker.internal.company.io/myapp:v1.0.0
Configuration Podman¶
# /etc/containers/registries.conf
unqualified-search-registries = ["docker.internal.company.io"]
[[registry]]
location = "docker.io"
[[registry.mirror]]
location = "docker-group.internal.company.io"
insecure = false
npm / yarn / pnpm¶
Configuration globale .npmrc¶
# ~/.npmrc
registry=https://nexus.internal.company.io/repository/npm-group/
//nexus.internal.company.io/repository/npm-group/:_authToken=NpmToken.XXXXXXXX
//nexus.internal.company.io/repository/npm-hosted/:_authToken=NpmToken.XXXXXXXX
always-auth=true
Configuration par projet .npmrc¶
# .npmrc (a la racine du projet, commite dans Git)
registry=https://nexus.internal.company.io/repository/npm-group/
@company:registry=https://nexus.internal.company.io/repository/npm-hosted/
Scope @company pour les paquets internes
Utiliser un scope npm (@company/) pour tous les paquets internes. Cela permet de router les paquets scopes vers le dépôt hosted et les autres vers le group (qui inclut le proxy).
Yarn¶
# .yarnrc.yml (Yarn Berry / v3+)
npmRegistryServer: "https://nexus.internal.company.io/repository/npm-group/"
npmAlwaysAuth: true
npmAuthToken: "NpmToken.XXXXXXXX"
npmScopes:
company:
npmRegistryServer: "https://nexus.internal.company.io/repository/npm-hosted/"
pnpm¶
# .npmrc (pnpm utilise le meme fichier que npm)
registry=https://nexus.internal.company.io/repository/npm-group/
@company:registry=https://nexus.internal.company.io/repository/npm-hosted/
Publication d'un paquet interne¶
# Publier sur le depot hosted
npm publish --registry=https://nexus.internal.company.io/repository/npm-hosted/
pip / Poetry / uv¶
Configuration pip¶
# ~/.config/pip/pip.conf (Linux)
# %APPDATA%\pip\pip.ini (Windows)
[global]
index-url = https://nexus.internal.company.io/repository/pypi-group/simple/
trusted-host = nexus.internal.company.io
[install]
extra-index-url =
Supprimer extra-index-url
Si extra-index-url est configuré (par exemple vers pypi.org), pip continuera a interroger le registre public directement, contournant le miroir. Le supprimer force tout le trafic a passer par Nexus.
Configuration Poetry¶
# Configurer la source par defaut
poetry config repositories.company \
https://nexus.internal.company.io/repository/pypi-hosted/simple/
# Ajouter les credentials
poetry config http-basic.company deployer PASSWORD
# pyproject.toml
[[tool.poetry.source]]
name = "company"
url = "https://nexus.internal.company.io/repository/pypi-group/simple/"
priority = "primary"
Configuration uv¶
# Variable d'environnement
export UV_INDEX_URL="https://nexus.internal.company.io/repository/pypi-group/simple/"
Publication d'un paquet interne¶
# Avec twine
twine upload \
--repository-url https://nexus.internal.company.io/repository/pypi-hosted/ \
-u deployer -p PASSWORD \
dist/*
Maven / Gradle¶
Configuration Maven (settings.xml)¶
<!-- ~/.m2/settings.xml -->
<settings>
<mirrors>
<mirror>
<id>nexus</id>
<name>Nexus Mirror</name>
<url>https://nexus.internal.company.io/repository/maven-group/</url>
<mirrorOf>*</mirrorOf>
</mirror>
</mirrors>
<servers>
<server>
<id>nexus</id>
<username>deployer</username>
<password>PASSWORD</password>
</server>
<server>
<id>nexus-releases</id>
<username>deployer</username>
<password>PASSWORD</password>
</server>
<server>
<id>nexus-snapshots</id>
<username>deployer</username>
<password>PASSWORD</password>
</server>
</servers>
</settings>
Publication Maven (pom.xml)¶
<!-- pom.xml — section distributionManagement -->
<distributionManagement>
<repository>
<id>nexus-releases</id>
<url>https://nexus.internal.company.io/repository/maven-hosted-releases/</url>
</repository>
<snapshotRepository>
<id>nexus-snapshots</id>
<url>https://nexus.internal.company.io/repository/maven-hosted-snapshots/</url>
</snapshotRepository>
</distributionManagement>
Configuration Gradle¶
// build.gradle.kts
repositories {
maven {
url = uri("https://nexus.internal.company.io/repository/maven-group/")
credentials {
username = project.findProperty("nexusUser") as String? ?: "deployer"
password = project.findProperty("nexusPassword") as String? ?: ""
}
}
}
publishing {
repositories {
maven {
val releasesUrl = uri("https://nexus.internal.company.io/repository/maven-hosted-releases/")
val snapshotsUrl = uri("https://nexus.internal.company.io/repository/maven-hosted-snapshots/")
url = if (version.toString().endsWith("SNAPSHOT")) snapshotsUrl else releasesUrl
credentials {
username = project.findProperty("nexusUser") as String? ?: "deployer"
password = project.findProperty("nexusPassword") as String? ?: ""
}
}
}
}
Go modules¶
Configuration GOPROXY¶
# Variable d'environnement
export GOPROXY="https://nexus.internal.company.io/repository/go-proxy/,direct"
export GONOSUMDB="company.io/*"
export GONOSUMCHECK="company.io/*"
export GONOPROXY="company.io/*"
Le suffixe ,direct permet un fallback vers le telechargement direct si le proxy ne répond pas. Pour un environnement strictement contrôle, retirer ,direct :
# Mode strict — tout passe par Nexus, pas de fallback
export GOPROXY="https://nexus.internal.company.io/repository/go-proxy/"
Authentification Go¶
# Configurer les credentials pour le proxy Go
export GOFLAGS="-modcacherw"
# Fichier .netrc pour l'authentification HTTP basique
cat >> ~/.netrc << 'EOF'
machine nexus.internal.company.io
login deployer
password PASSWORD
EOF
chmod 600 ~/.netrc
apt (Debian / Ubuntu)¶
# /etc/apt/sources.list.d/nexus.list
deb https://nexus.internal.company.io/repository/apt-ubuntu-proxy/ noble main restricted universe multiverse
# Authentification si l'acces anonyme est desactive
cat > /etc/apt/auth.conf.d/nexus.conf << 'EOF'
machine nexus.internal.company.io
login deployer
password PASSWORD
EOF
chmod 600 /etc/apt/auth.conf.d/nexus.conf
# Ajouter le certificat CA si auto-signe
cp company-ca.crt /usr/local/share/ca-certificates/
update-ca-certificates
# Mettre a jour les index
apt-get update
Helm¶
# Ajouter le depot Helm
helm repo add company \
https://nexus.internal.company.io/repository/helm-hosted/ \
--username deployer --password PASSWORD
# Ajouter un depot proxy (charts publics via Nexus)
helm repo add stable-proxy \
https://nexus.internal.company.io/repository/helm-proxy/ \
--username deployer --password PASSWORD
# Mettre a jour les index
helm repo update
# Installer un chart
helm install my-release stable-proxy/grafana
Integration CI/CD¶
Principe général¶
Le pipeline CI/CD doit :
- Pull : telecharger les dependances depuis les dépôts group (proxy + hosted)
- Build : construire l'artefact
- Push : publier l'artefact dans le dépôt hosted
┌─────────────────────────────────────────────────────────┐
│ Pipeline CI/CD │
│ │
│ 1. Pull deps 2. Build 3. Push artifact │
│ (group repo) (compile/test) (hosted repo) │
│ │ │ │
│ ▼ ▼ │
│ npm-group ◄── ──▶ npm-hosted │
│ pypi-group ◄── ──▶ pypi-hosted │
│ maven-group ◄── ──▶ maven-hosted-releases │
│ docker-group ◄── ──▶ docker-hosted │
└─────────────────────────────────────────────────────────┘
Exemple Gitea Actions¶
# .gitea/workflows/build.yaml
name: Build and Publish
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Login to Docker Registry
run: |
echo "${{ secrets.NEXUS_PASSWORD }}" | \
docker login docker.internal.company.io \
-u "${{ secrets.NEXUS_USER }}" --password-stdin
- name: Build Docker image
run: |
docker build -t docker.internal.company.io/myapp:${{ github.sha }} .
- name: Push to Nexus
run: |
docker push docker.internal.company.io/myapp:${{ github.sha }}
- name: Tag latest
if: github.ref == 'refs/heads/main'
run: |
docker tag docker.internal.company.io/myapp:${{ github.sha }} \
docker.internal.company.io/myapp:latest
docker push docker.internal.company.io/myapp:latest
Variables d'environnement CI/CD¶
| Variable | Valeur | Usage |
|---|---|---|
NPM_REGISTRY | https://nexus.internal.company.io/repository/npm-group/ | Telechargement npm |
PIP_INDEX_URL | https://nexus.internal.company.io/repository/pypi-group/simple/ | Telechargement pip |
MAVEN_MIRROR | https://nexus.internal.company.io/repository/maven-group/ | Telechargement Maven |
GOPROXY | https://nexus.internal.company.io/repository/go-proxy/ | Telechargement Go |
DOCKER_REGISTRY | docker.internal.company.io | Push/pull Docker |
NEXUS_USER | deployer | Compte de service CI/CD |
NEXUS_PASSWORD | (secret) | Mot de passe du compte |
Ne jamais coder les credentials en dur
Toujours utiliser les secrets du système CI/CD (Gitea Secrets, Vault, etc.) pour les credentials Nexus. Ne jamais les écrire dans les fichiers de pipeline commites dans Git.
Webhook notifications¶
Nexus peut envoyer des notifications webhook lorsque des événements se produisent sur les dépôts.
Configuration d'un webhook¶
Via l'interface web : Administration → System → Capabilities → Create capability → Webhook: Repository.
| Parametre | Valeur | Description |
|---|---|---|
| URL | https://monitoring.internal/webhook | Endpoint récepteur |
| Event types | COMPONENT_CREATED, AUDIT | Événements déclencheurs |
| Secret header | X-Nexus-Webhook-Secret: <token> | Authentification du webhook |
| Repository | (tous ou selection) | Dépôts concernes |
Exemple de payload webhook¶
{
"timestamp": "2026-04-16T10:30:00.000+00:00",
"nodeId": "nexus-01",
"initiator": "deployer",
"repositoryName": "docker-hosted",
"action": "CREATED",
"component": {
"name": "myapp",
"version": "v1.2.3",
"format": "docker"
}
}
Integration avec le monitoring¶
Les webhooks peuvent alimenter :
| Destination | Usage |
|---|---|
| Prometheus Alertmanager | Alertes sur des événements spécifiques |
| Grafana Loki | Ingestion de logs d'activité des dépôts |
| Mattermost / Slack | Notifications dans un canal d'équipe |
| Scripts d'audit | Journal des publications pour conformite |