Содержание

Nexus Repository

https://www.sonatype.com/nexus/repository-oss
https://hub.docker.com/r/sonatype/nexus3
https://help.sonatype.com/repomanager3/product-information/system-requirements

Запуск:

docker run -d -p 8081:8081 -p 8082:8082 --name nexus sonatype/nexus3

При первом запуске, логин admin, посмотреть пароль:

docker exec $(docker ps -q -f name=nexus) cat /nexus-data/admin.password

docker-compose.yaml

docker-compose.yaml

version: '3.4'
volumes:
  data:
    driver_opts:
      type: none
      device: ${VOLPATH-/data/docker/nexus}/data
      o: bind

services:
  nexus:
    image: sonatype/nexus3
    volumes:
    - data:/nexus-data:rw
    ports:
      - 8081:8081
      - 8082:8082
    restart: on-failure:3
    deploy:
      replicas: 1
#      resources:
#        limits:
#          memory: 2g
      restart_policy:
        condition: any
    healthcheck:
      test: curl --silent --fail --show-error --output /dev/null -X GET http://127.0.0.1:8081 || exit 1
      interval: 60s
      timeout: 5s
      retries: 3
      start_period: 60s

Nexus Repository Microsoft Symbol Server Format

nexus-repository-microsoft-symbol-server поддерживает сервер только в виде proxy https://issues.sonatype.org/browse/NEXUS-6779

https://github.com/sonatype-nexus-community/nexus-repository-microsoft-symbol-server#more-permanent-install
https://search.maven.org/artifact/org.sonatype.nexus.plugins/nexus-repository-microsoft-symbol-server

NuGet

Тестировать nuget репозиторий:

dotnet nuget

dotnet nuget

docker run --rm -it -e NUGETHOST="$NUGETHOST" -e NUGETUSER="$NUGETUSER" -e NUGETPASS="$NUGETPASS" --name nugettest mcr.microsoft.com/dotnet/sdk:6.0
dotnet nuget disable source nuget.org; \
dotnet dotnet nuget add source ${NUGETHOST} -n IDScan.net -u ${NUGETUSER} -p ${NUGETPASS} --store-password-in-clear-text; \
dotnet new console -n test
dotnet add test/test.csproj package Newtonsoft.Json -v 13.0.2


Индексные файлы: https://${DOMAINNEXUS}/repository/${REPONAME}/v3/content/${PACKAGENAME}/index.json

Nginx

Как reverse proxy для Nexus (на порту 8081) и Docker (на порту 8082):

nginx.conf

nginx.conf

server {
  listen 443 ssl;
  server_name registry.domain.com;

  client_max_body_size 0;

  proxy_send_timeout 120;
  proxy_read_timeout 300;
  proxy_buffering    off;
  proxy_request_buffering off;
  keepalive_timeout  5 5;
  tcp_nodelay        on;

  location / {
    if ($http_user_agent ~ docker ) {
      proxy_pass http://nexus_docker:8082;
    }
    proxy_set_header Host                $http_host;
    proxy_set_header X-Real-IP           $remote_addr;
    proxy_set_header X-Forwarded-Ssl     on;
    proxy_set_header X-Forwarded-For     $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto   $scheme;

    proxy_pass http://nexus_host:8081;
  }

  ssl_protocols	SSLv3 TLSv1.2 TLSv1.3;
  ssl_certificate	/ssl/domain.com.crt;
  ssl_certificate_key	/ssl/domain.com.key;
  ssl_dhparam		/ssl/dhparam.pem;
  #add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; #hsts
}

https://help.sonatype.com/repomanager3/installation/run-behind-a-reverse-proxy
https://blog.sonatype.com/setting-up-a-docker-private-registry-with-authentication-using-nexus-and-nginx

Traefik

nexus.yaml

nexus.yaml

http:
  routers:
    registry.domain.com:
      rule: Host(`registry.domain.com`)
      entryPoints:
      - https
      middlewares:
      - secureHeader
      service: registry.domain.com
      priority: 1
      tls:
        certResolver: "domain.com"
        domains:
          - main: "registry.domain.com"
    registry.domain.com/v2:
      rule: Host(`registry.domain.com`) && (Path(`/v2`) || HeadersRegexp(`User-Agent`, `docker`))
      entryPoints:
      - https
      middlewares:
      - secureHeader
      service: registry.domain.com/v2
      priority: 2
      tls:
        certResolver: "domain.com"
        domains:
          - main: "registry.domain.com"
  services:
    registry.domain.com:
      loadBalancer:
        servers:
        - url: http://nexus_docker:8881/
    registry.domain.com/v2:
      loadBalancer:
        servers:
        - url: http://nexus_docker:8882/


Backup/Restore

nexus.sh

nexus.sh

#!/bin/bash
 
DATE=$(date +%F)
 
NAME="nexus"
REMOTEHOST="deploy@nexus.domain.loc"
PATHB="/data/backups/$NAME/daily"
PATHM="/data/backups/$NAME/monthly"
 
NUMDAILY=7
NUMMONTHLY=2
 
FILENAME=$NAME\_$DATE
 
if ! [ -d $PATHB ]; then mkdir -p $PATHB; fi
if ! [ -d $PATHM ]; then mkdir -p $PATHM; fi
 
#Backup blobs
CONTAINER=$(ssh $REMOTEHOST "docker ps -q -f name=$NAME_$NAME")
ssh $REMOTEHOST docker exec $CONTAINER tar cf - /nexus-data/blobs/ > $PATHB/$FILENAME.tar
#Backup db
ssh $REMOTEHOST docker exec -w /backups $CONTAINER tar czf - . > $PATHB/$FILENAME.tgz
ssh $REMOTEHOST docker exec -w /backups $CONTAINER rm $(ssh $REMOTEHOST docker exec -w /backups $CONTAINER ls)
 
if [ $(echo $DATE | awk -F- '{print $3}') == 01 ]; then
  mv $PATHB/$FILENAME $PATHM/
fi
 
#db
#Clean backup daily
while [ `ls $PATHB/ | grep .tgz | wc -l` -gt $NUMDAILY ] ; do
    rm `ls $PATHB/*.tgz | head -1`
done
#Clean backup monthly
while [ `ls $PATHM/ | grep .tgz | wc -l` -gt $NUMMONTHLY ] ; do
    rm `ls $PATHM/*.tgz | head -1`
done
#blobs
#Clean backup daily
while [ `ls $PATHB/ | grep .sql.gz | wc -l` -gt $NUMDAILY ] ; do
    rm `ls $PATHB/*.tar | head -1`
done
#Clean backup monthly
while [ `ls $PATHM/ | grep .sql.gz | wc -l` -gt $NUMMONTHLY ] ; do
    rm `ls $PATHM/*.tar | head -1`
done
 
#Restore
##REMOTEHOST="deploy@nexus.domain.loc"
#ssh $REMOTEHOST "docker stack rm $NAME"
#ssh $REMOTEHOST "docker run --rm -v /data/docker/nexus/blobs:/nexus-data/blobs alpine rm -r /nexus-data/blobs"
#cat $PATHB/$FILENAME.tar | ssh $REMOTEHOST docker run --rm -i -v /data/docker/nexus/blobs:/nexus-data/blobs --user 200:200 alpine tar -x -C /
#ssh $REMOTEHOST "docker run --rm -v /data/docker/nexus/db:/nexus-data/db -v /data/docker/nexus/restore-from-backup:/nexus-data/restore-from-backup alpine rm -rf /nexus-data/db/component /nexus-data/db/config /nexus-data/db/security /nexus-data/restore-from-backup"
#cat $PATHB/$FILENAME.tgz | ssh $REMOTEHOST docker run --rm -i -v /data/docker/nexus/restore-from-backup:/nexus-data/restore-from-backup alpine tar -xz -C /nexus-data/restore-from-backup

https://help.sonatype.com/repomanager3/planning-your-implementation/backup-and-restore

Проблемы

Удаление не удаляемых soft-deleted файлов из блоб хранилища

  1. Добавить в файл metadata.properties корневой директории блоб хранилища:
    rebuildDeletedBlobIndex=true
  2. Запустить задачу Admin - Compact Blobstore, которая пройдёт по всем файлам свойств в blobstore в поисках атрибута deleted=true и перестроит индексный файл. После завершения задачи свойство rebuildDeletedBlobIndex из metadata.properties будет удалёно.

https://support.sonatype.com/hc/en-us/articles/360025325653-How-to-rebuild-the-Admin-Compact-blobstore-deletions-index-file-if-soft-deleted-blobs-are-orphaned