Aller au contenu

Bonnes pratiques

Cleanup policies

Stratégie de nettoyage par type de dépôt

Les dépôts proxy accumulent des paquets au fil du temps. Sans nettoyage, le stockage croit indéfiniment.

Type de dépôt Stratégie recommandee Fréquence
Proxy (tous) Supprimer les composants non telecharges depuis 90 jours Quotidienne
Hosted snapshots Supprimer les snapshots de plus de 30 jours Quotidienne
Hosted releases Conserver indéfiniment (pas de cleanup automatique) Manuelle
Docker proxy Supprimer les layers non referencees depuis 60 jours Quotidienne
Docker hosted Garder les N derniers tags par image Hebdomadaire

Configuration des cleanup policies

# Politique pour les depots proxy — composants non utilises depuis 90 jours
curl -u admin:PASSWORD -X POST \
  'https://nexus.internal.company.io/service/rest/v1/cleanup-policies' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "proxy-90-days-unused",
    "format": "ALL_FORMATS",
    "notes": "Supprime les composants proxy non telecharges depuis 90 jours",
    "criteria": {
      "lastDownloaded": 90
    }
  }'

# Politique pour les snapshots Maven — plus de 30 jours
curl -u admin:PASSWORD -X POST \
  'https://nexus.internal.company.io/service/rest/v1/cleanup-policies' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "snapshots-30-days",
    "format": "maven2",
    "notes": "Supprime les snapshots Maven de plus de 30 jours",
    "criteria": {
      "lastBlobUpdated": 30,
      "isPrerelease": "true"
    }
  }'

Tâches planifiees associees

Apres avoir cree les cleanup policies, planifier les tâches d'execution :

Tâche Cron Description
Cleanup : marquer 0 2 * * * Identifie les composants a supprimer
Cleanup : supprimer 0 3 * * * Supprime les composants marques
Compact blob store 0 4 * * 0 Récupère l'espace disque (dimanche)
Rebuild Docker index 0 5 * * 0 Reconstruit les metadonnees Docker (dimanche)
Purge unused snapshots 0 2 * * * Supprime les snapshots non références

Toujours compacter apres le cleanup

La suppression de composants marque les blobs comme supprimes, mais l'espace n'est pas récupère tant que la tâche de compaction n'a pas ete exécutée. Planifier la compaction apres le cleanup.


Gestion du stockage

Monitoring de l'espace disque

# Script de monitoring — a executer par cron ou integrer dans Prometheus
#!/bin/bash
NEXUS_URL="https://nexus.internal.company.io"
NEXUS_USER="admin"
NEXUS_PASS="PASSWORD"

# Taille des blob stores
curl -s -u "${NEXUS_USER}:${NEXUS_PASS}" \
  "${NEXUS_URL}/service/rest/v1/blobstores" \
  | jq '.[] | {name, totalSizeInBytes, availableSpaceInBytes}'

Regles de lifecycle S3

Si le blob store utilise S3, configurer des regles de lifecycle pour optimiser les coûts :

{
  "Rules": [
    {
      "ID": "nexus-blob-lifecycle",
      "Status": "Enabled",
      "Filter": {
        "Prefix": "nexus-blobs/"
      },
      "Transitions": [
        {
          "Days": 90,
          "StorageClass": "STANDARD_IA"
        },
        {
          "Days": 365,
          "StorageClass": "GLACIER_IR"
        }
      ]
    }
  ]
}
Classe de stockage Delai Cas d'usage Economie
S3 Standard 0-90 j Blobs fréquemment accedes
S3 Standard-IA 90-365 j Blobs rarement accedes ~45%
Glacier IR > 365 j Archives (anciennes versions, snapshots) ~70%

Ne pas archiver les metadonnees

Les regles de lifecycle S3 s'appliquent uniquement aux blobs (artefacts). Les metadonnees (PostgreSQL) doivent rester sur du stockage rapide en permanence.

Alertes sur l'espace disque

Seuil Action
Blob store > 80% du quota Alerte WARNING — vérifier les cleanup policies
Blob store > 90% du quota Alerte CRITICAL — cleanup manuel ou extension du volume
Volume système /opt/nexus > 85% Alerte CRITICAL — risque d'arrêt de Nexus

Haute disponibilité

Nexus OSS : actif-passif

La version OSS de Nexus ne supporte pas le clustering. La seule option HA est un déploiement actif-passif avec stockage partage.

┌──────────────────┐          ┌──────────────────┐
│    Nexus actif   │          │   Nexus passif   │
│   (en service)   │          │   (en attente)   │
│   10.30.3.10     │          │   10.30.3.11     │
└────────┬─────────┘          └────────┬─────────┘
         │                             │
         └──────────┬──────────────────┘
         ┌──────────▼──────────┐
         │   Stockage partage  │
         │   (NFS / S3 / Ceph) │
         │   + PostgreSQL HA   │
         └─────────────────────┘

Procedure de bascule :

  1. Arreter l'instance active
  2. Monter le volume partage sur l'instance passive
  3. Démarrer l'instance passive
  4. Mettre a jour le DNS ou le load balancer

Nexus Pro pour le clustering actif-actif

La version Nexus Pro (commerciale) offre le clustering actif-actif avec réplication. Si la haute disponibilité est un requis dur, évaluer le coût de la licence Pro par rapport à la complexité de l'actif-passif.

Sauvegarde et restauration

# Sauvegarde de la base de metadonnees (PostgreSQL)
pg_dump -h postgres.internal -U nexus -d nexus \
  --format=custom \
  --file="/opt/nexus/backup/nexus-db-$(date +%Y%m%d).dump"

# Sauvegarde des blob stores (si fichier local)
rsync -av --delete \
  /opt/nexus/data/blobs/ \
  /mnt/backup/nexus-blobs/

# Sauvegarde de la configuration Nexus
tar czf "/opt/nexus/backup/nexus-config-$(date +%Y%m%d).tar.gz" \
  /opt/nexus/data/etc/ \
  /opt/nexus/data/keystores/
Composant Méthode Fréquence Retention
Base PostgreSQL pg_dump Quotidienne 30 jours
Blob stores (fichier) rsync Quotidienne 7 jours
Blob stores (S3) Versioning S3 Continue 30 jours
Configuration Nexus tar + Git À chaque modif Illimité

Monitoring

Metriques Prometheus

Nexus expose des metriques via l'endpoint /service/metrics/prometheus :

# prometheus.yml
scrape_configs:
  - job_name: 'nexus'
    metrics_path: '/service/metrics/prometheus'
    basic_auth:
      username: 'prometheus'
      password: 'PASSWORD'
    static_configs:
      - targets: ['nexus.internal.company.io:8081']

Metriques cles a surveiller

Metrique Description Alerte si
nexus_repository_total_components Nombre de composants par dépôt Croissance anormale
jvm_memory_used_bytes Mémoire JVM utilisee > 85% du max heap
jvm_gc_pause_seconds Duree des pauses GC > 5 secondes
http_server_requests_seconds Latence des requêtes HTTP p95 > 2 secondes
nexus_blobstore_total_size_bytes Taille totale du blob store > 80% du quota

Dashboard Grafana

Les panels essentiels pour un dashboard Nexus :

Panel Type Requête PromQL
Requêtes par seconde Graph rate(http_server_requests_seconds_count[5m])
Latence p95 Graph histogram_quantile(0.95, rate(http_server_requests_seconds_bucket[5m]))
Mémoire JVM Gauge jvm_memory_used_bytes / jvm_memory_max_bytes * 100
Taille des blob stores Table nexus_blobstore_total_size_bytes
Cache hit ratio (estimation) Graph Ratio requêtes servies localement vs forwarded upstream
Espace disque disponible Gauge node_filesystem_avail_bytes{mountpoint="/opt/nexus"}

Healthcheck

# Verifier que Nexus est operationnel
curl -sf https://nexus.internal.company.io/service/rest/v1/status/writable
# HTTP 200 = OK, HTTP 503 = Nexus en lecture seule ou en demarrage

Migration entre registres

Depuis Verdaccio vers Nexus (npm)

# 1. Exporter les paquets de Verdaccio
find /var/lib/verdaccio/storage -name "*.tgz" -type f > /tmp/npm-packages.txt

# 2. Publier chaque paquet dans Nexus hosted
while read -r PKG; do
  npm publish "${PKG}" \
    --registry=https://nexus.internal.company.io/repository/npm-hosted/
done < /tmp/npm-packages.txt

# 3. Mettre a jour les .npmrc des projets
# (voir chapitre Integration)

# 4. Verifier que tout fonctionne
npm install --registry=https://nexus.internal.company.io/repository/npm-group/

# 5. Decomissionner Verdaccio

Depuis un registre Docker (Harbor, Registry v2) vers Nexus

# 1. Lister les images du registre source
IMAGES=$(curl -s https://old-registry.internal/v2/_catalog | jq -r '.repositories[]')

# 2. Pour chaque image, lister les tags et les migrer
for IMAGE in ${IMAGES}; do
  TAGS=$(curl -s "https://old-registry.internal/v2/${IMAGE}/tags/list" | jq -r '.tags[]')
  for TAG in ${TAGS}; do
    # Pull depuis l'ancien registre
    docker pull "old-registry.internal/${IMAGE}:${TAG}"
    # Tag pour le nouveau registre
    docker tag "old-registry.internal/${IMAGE}:${TAG}" \
      "docker.internal.company.io/${IMAGE}:${TAG}"
    # Push vers Nexus
    docker push "docker.internal.company.io/${IMAGE}:${TAG}"
  done
done

# 3. Mettre a jour les references dans les manifestes Kubernetes, docker-compose, etc.

Depuis Pulp vers Nexus (rpm)

# 1. Exporter la publication Pulp
pulp rpm publication create --repository=rocky-baseos
pulp exporter pulp create --name=migration \
  --path=/tmp/pulp-export/ \
  --repository=rocky-baseos
pulp export pulp run --exporter=migration

# 2. Configurer Nexus avec un proxy vers le meme upstream
# (Nexus re-telecharge a la demande — pas besoin de migrer les blobs)

# 3. Mettre a jour les fichiers /etc/yum.repos.d/ des serveurs

Migration progressive

Plutôt que de migrer tout d'un coup, configurer Nexus en parallele et basculer les clients projet par projet. L'ancien registre reste disponible en fallback le temps de valider.


Troubleshooting

Cache miss systematique

Symptome Cause probable Solution
Tous les pulls passent par l'upstream metadataMaxAge trop court Augmenter a 1440 (24h)
Le proxy retourne 404 pour un paquet Negative cache actif Purger le negative cache ou attendre le TTL
Le proxy retourne 502 Bad Gateway Upstream bloque (rate limit, IP ban) Vérifier autoBlock, ajouter credentials
Le proxy ne rafraichit pas les metadonnees Cache des metadonnees trop long Invalider le cache manuellement

Timeout upstream

# Verifier la connectivite vers l'upstream depuis le conteneur Nexus
podman exec nexus curl -v https://registry.npmjs.org/ --connect-timeout 5

# Si timeout : verifier le proxy HTTP sortant
podman exec nexus env | grep -i proxy

# Configurer le proxy HTTP dans Nexus :
# Administration → HTTP → HTTP proxy settings

Blobs corrompus

# Identifier les blobs orphelins
# Administration → System → Tasks → Repair - Reconcile component database from blob store

# Si une image Docker est corrompue
# 1. Supprimer le composant via l'UI ou l'API
curl -u admin:PASSWORD -X DELETE \
  'https://nexus.internal.company.io/service/rest/v1/components/COMPONENT_ID'

# 2. Forcer un re-telechargement
docker pull docker-group.internal.company.io/library/alpine:latest

Blob store trop volumineux

# 1. Verifier quels depots consomment le plus d'espace
curl -s -u admin:PASSWORD \
  'https://nexus.internal.company.io/service/rest/v1/blobstores' \
  | jq '.[] | {name, totalSizeInBytes: (.totalSizeInBytes / 1073741824 | tostring + " Go")}'

# 2. Verifier les cleanup policies actives
curl -s -u admin:PASSWORD \
  'https://nexus.internal.company.io/service/rest/v1/cleanup-policies' \
  | jq '.[] | {name, format, criteria}'

# 3. Executer un cleanup manuel
# Administration → System → Tasks → Run "Cleanup service"

# 4. Compacter le blob store
# Administration → System → Tasks → Run "Compact blob store"

Performance degradee

Symptome Cause probable Solution
Interface web lente Heap JVM insuffisant Augmenter -Xmx (min 4 Go, idéal 8 Go)
Pauses GC fréquentes Heap trop petit ou trop de blobs Augmenter la heap, activer G1GC
Temps de réponse API > 5s Base de metadonnees saturee Migrer vers PostgreSQL dedie
Uploads Docker lents Bande passante disque saturee Migrer le blob store vers S3 ou SSD
Nexus ne demarre plus Corruption base OrientDB (legacy) Migrer vers PostgreSQL, restaurer la backup
# Verifier les parametres JVM
podman exec nexus cat /nexus-data/etc/jvm.options

# Parametres recommandes pour 8 Go de RAM
# -Xms4g
# -Xmx4g
# -XX:MaxDirectMemorySize=4g
# -XX:+UseG1GC
# -XX:MaxGCPauseMillis=200