Aller au contenu

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 :

  1. Pull : telecharger les dependances depuis les dépôts group (proxy + hosted)
  2. Build : construire l'artefact
  3. 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 : AdministrationSystemCapabilitiesCreate capabilityWebhook: 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