Múlt hónapban jött az Artifactory megújítás: 40%-kal drágább, mint tavaly. Semmi új feature amit használnánk, csak a szokásos “enterprise tier” szorítás. Vulnerability scanning? Fizess többet. Replikáció? Fizess többet. SSO ami nem csak SAML? Na, találd ki.

Két hetet szántam rá, hogy lecseréljem. Ez lett belőle — mi működött, mi nem, és milyen csapdák vannak amiket senki nem említ.

Amit Futtatunk

Az Artifactory-nk ezt kezelte:

  • Docker image-ek (~800 image, ~12TB összesen)
  • npm csomagok (privát registry, ~200 belső csomag)
  • Helm chartok
  • Generikus binárisok (build outputok, firmware blob-ok)

A fő követelmények: vulnerability scan push-ra, OIDC SSO, és cross-region replikáció a DR site-ra.

A Stack Amire Jutottunk

Egy hét értékelés után ez maradt:

Szerep Eszköz Miért
Docker + Helm Harbor 2.12 Trivy beépítve, OIDC natív, replikáció megy
npm Verdaccio 6 Könnyűsúlyú, proxy + privát, egyszerűen működik
Generikus blob-ok Minio S3-kompatibilis, Harbor backend is
Reverse proxy Caddy Auto TLS, egyszerűbb mint nginx erre

Harbor Telepítés

A Harbor volt a kézenfekvő választás konténerekhez. A telepítés egyértelmű, de vannak éles sarkok:

# Offline installert tölts le - az online installer telepítés közben húz
# ami pont az, amit prodban nem akarsz
curl -LO https://github.com/goharbor/harbor/releases/download/v2.12.0/harbor-offline-installer-v2.12.0.tgz
tar xzf harbor-offline-installer-v2.12.0.tgz
cd harbor

cp harbor.yml.tmpl harbor.yml

A harbor.yml konfigból ami számít:

hostname: registry.internal.example.com
https:
  port: 443
  certificate: /etc/harbor/certs/registry.crt
  private_key: /etc/harbor/certs/registry.key

# Minio mint storage backend
storage_service:
  s3:
    accesskey: ${MINIO_ACCESS_KEY}
    secretkey: ${MINIO_SECRET_KEY}
    region: us-east-1
    regionendpoint: http://minio.internal:9000
    bucket: harbor-registry
    secure: false

proxy:
  http_proxy:
  https_proxy:
  no_proxy: 127.0.0.1,minio.internal
  components:
    - core
    - jobservice
    - trivy

1. csapda: A Harbor alapértelmezett storage drivere 5GB-os layer limitet használ. Ha vannak ML image-eid hatalmas layerekkel (nálunk volt egy CUDA image 7.8GB-os layerrel), patchelned kell a registry configot telepítés után:

# Az ./install.sh után szerkeszd ezt
vim /data/harbor/registry/config.yml

# Add hozzá a storage.s3 alá:
#   chunksize: 10485760
#   multipartcopymaxconcurrency: 8
#   multipartcopythresholdsize: 67108864

Utána registry konténer újraindítás. Négy órám ment el erre.

2. csapda: A Trivy vulnerability adatbázisát frissíteni kell, és air-gapped setupon a Harbor nem csinálja magától. Cronból futtatjuk:

# Trivy DB frissítés - naponta hajnali 3-kor
0 3 * * * docker exec harbor-trivy trivy image --download-db-only 2>&1 | logger -t trivy-update

Verdaccio npm-hez

A Verdaccio bűnösen alulértékelt. Öt perc felállítani, kezeli a privát csomagokat és proxyként az npmjs.org-ot:

# /opt/verdaccio/config.yaml
storage: /verdaccio/storage
auth:
  htpasswd:
    file: /verdaccio/htpasswd
    max_users: -1  # Regisztráció kikapcsolva

# OIDC plugin SSO-hoz
middlewares:
  openid-connect:
    issuer: https://auth.example.com/realms/devops
    client-id: verdaccio
    client-secret: ${VERDACCIO_OIDC_SECRET}

uplinks:
  npmjs:
    url: https://registry.npmjs.org/
    cache: true
    maxage: 30m

packages:
  '@internal/*':
    access: $authenticated
    publish: $authenticated
    unpublish: $authenticated

  '**':
    access: $all
    publish: $authenticated
    proxy: npmjs
docker run -d \
  --name verdaccio \
  -p 4873:4873 \
  -v /opt/verdaccio:/verdaccio \
  -e VERDACCIO_OIDC_SECRET="${OIDC_SECRET}" \
  verdaccio/verdaccio:6

Amire nem számítottam: a Verdaccio proxy cache tényleg jó. Az első pull után a CI-ban az npm install ~45 másodpercről ~8 másodpercre csökkent, mert minden lokálisan volt kiszolgálva.

Minio mint Backend

A Minio a ragasztó. A Harbor ezt használja S3 storage-ként, mi meg közvetlenül a generikus binárisokhoz:

# docker compose-szal
services:
  minio:
    image: minio/minio:latest
    command: server /data --console-address ":9001"
    environment:
      MINIO_ROOT_USER: ${MINIO_ROOT_USER}
      MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD}
      MINIO_IDENTITY_OPENID_CONFIG_URL: https://auth.example.com/realms/devops/.well-known/openid-configuration
      MINIO_IDENTITY_OPENID_CLIENT_ID: minio
    volumes:
      - /data/minio:/data
    ports:
      - "9000:9000"
      - "9001:9001"

Bináris artifactokhoz a mc (Minio client) megy CI-ban:

# GitLab CI-ban
upload_firmware:
  stage: publish
  script:
    - mc alias set artifacts http://minio.internal:9000 ${MINIO_KEY} ${MINIO_SECRET}
    - mc cp build/firmware-${CI_COMMIT_TAG}.bin artifacts/firmware/${CI_COMMIT_TAG}/
    - mc tag set artifacts/firmware/${CI_COMMIT_TAG}/firmware-${CI_COMMIT_TAG}.bin "commit=${CI_COMMIT_SHA}" "pipeline=${CI_PIPELINE_ID}"

A Migráció

Ez volt az ijesztő rész. 800 image, nulla downtime tolerancia.

1. lépés: Párhuzamos futtatás

Két hétig mindkét registryt futtattuk. A CI mindkettőbe pusholt:

docker tag ${IMAGE}:${TAG} artifactory.old.example.com/${IMAGE}:${TAG}
docker tag ${IMAGE}:${TAG} registry.internal.example.com/${IMAGE}:${TAG}
docker push artifactory.old.example.com/${IMAGE}:${TAG}
docker push registry.internal.example.com/${IMAGE}:${TAG}

2. lépés: Tömeges másolás skopeo-val

A régi image-ekhez a skopeo a megfelelő eszköz:

#!/bin/bash
# migrate-images.sh
set -euo pipefail

IMAGES=$(curl -s -u "${ARTIFACTORY_USER}:${ARTIFACTORY_TOKEN}" \
  "https://artifactory.old.example.com/v2/_catalog" | jq -r '.repositories[]')

for image in ${IMAGES}; do
  TAGS=$(curl -s -u "${ARTIFACTORY_USER}:${ARTIFACTORY_TOKEN}" \
    "https://artifactory.old.example.com/v2/${image}/tags/list" | jq -r '.tags[]')

  for tag in ${TAGS}; do
    echo "Migrating ${image}:${tag}"
    skopeo copy \
      --src-creds "${ARTIFACTORY_USER}:${ARTIFACTORY_TOKEN}" \
      --dest-creds "${HARBOR_USER}:${HARBOR_TOKEN}" \
      "docker://artifactory.old.example.com/${image}:${tag}" \
      "docker://registry.internal.example.com/${image}:${tag}" || echo "FAILED: ${image}:${tag}" >> failed.log
  done
done

18 órát vett igénybe a 12TB-unkra. A || echo pattern megmentett — kb. 30 image elbukott (korrupt manifestek az Artifactoryban amiket senki nem vett észre), és utána nyugodtan átnéztük őket.

3. lépés: DNS Átállás

Miután mindent ellenőriztünk:

# Belső DNS frissítés
# artifactory.old.example.com → marad a régi IP-n (később leszereljük)
# registry.example.com → új Harbor IP

Biztonsági hálóként beállítottunk egy pull-through cache-t a Harbor-ban ami a régi Artifactoryra mutatott, hátha lemaradtunk valamiről. Egy hónap után töröltük, az access logban nulla találat volt.

Replikáció

A Harbor beépített replikációja a DR site-ra majdnem túl egyszerű volt:

  1. Harbor telepítés a DR hostra
  2. A fő Harbor UI-ban: Registries → New Endpoint → DR Harbor hozzáadása
  3. Replication → New Rule → event-based, push-ra replikáljon

Működött. Az egyetlen bökkenő: mindkét Harbor instanceon ugyanazt a Minio bucket elnevezési sémát használd, különben dupla storage-ot kapsz.

Mit Csinálnék Máshogy

  1. Harbor Helm chart installal kezdenék, nem az offline installerrel. Az offline installer működik, de a frissítések fájdalmasak. A Helm chart Kubernetesen sokkal tisztább.

  2. Minio replikációt állítsd be először. Mi a Harbor replikációt és a Minio replikációt külön csináltuk, ami azt jelentette, hogy egyes artifactok kétszer lettek replikálva. Hagyd, hogy a Minio kezelje az adat replikációt.

  3. Teszteld a Trivy scanning terhelést. Az első napon a Harbor megpróbálta mind a 800 image-et egyszerre scanelni. A Trivy konténer elérte a 32GB RAM-ot és OOMKill-t kapott. Állítsd a trivy.scanners concurrency-t 2-3-ra a harbor.yml-ben.

A Számok

Egy hónap után:

  • Költség: ~$48k/év (Artifactory) → ~$2k/év (3 VM + storage)
  • CI sebesség: Docker push 20%-kal gyorsabb (helyi hálózat vs. SaaS)
  • npm install: 45s → 8s CI-ban (Verdaccio proxy cache)
  • Scanning: A Trivy ugyanazokat a CVE-ket találja, sőt gyorsabban fut
  • Karbantartás: ~2 óra/hónap (frissítések, certificate rotation)

A trade-off egyértelmű: mostantól a tiéd az infra. Amikor a Minio-nak hajnali 2-kor lemezhibája volt, az a mi problémánk volt. De rendesen monitorozva és a DR replikával nem volt dráma — másnap reggel cseréltük a lemezt.

Megéri?

Ha kis csapat vagy és ingyenes tieren mész, az Artifactory rendben van. Ha enterprise árat fizetsz és talán a funkciók 30%-át használod, nézd meg a számlát és kérdezd meg magadtól, mit kapsz valójában.

Nálunk a kéthetes migráció az első számlázási ciklusban megtérült. És most mi irányítjuk a stacket. Nincs több meglepetés a megújítási emailben.