首页 > 解决方案 > Nexus 3 作为 Traefik v.2 背后的 Docker Registry - 推送失败

问题描述

在与 docker v.19.03.11 相同的 linux VM 上,我正在运行:

关系:

version: '3.7'

services:
  nexus:
    container_name: nexus
    image: sonatype/nexus3
    volumes:
      - nexus-data:/nexus-data
    networks:
      - web
    ports:
      - 8081
      - 8082
      - 8083
    restart: always
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=web"
      # admin.nexus.xxx.intern
      - "traefik.http.routers.nexus.rule=Host(`admin.nexus.xxx.intern`, `maven.nexus.itools.intern`)"
      - "traefik.http.services.nexus.loadbalancer.server.port=8081"
      - "traefik.http.routers.nexus.service=nexus"
      - "traefik.http.routers.nexus.entrypoints=web"
      # docker.nexus.xxx.intern
      - "traefik.http.routers.docker.rule=Host(`docker.nexus.xxx.intern`)"
      - "traefik.http.services.docker.loadbalancer.server.port=8083"
      - "traefik.http.routers.docker.service=docker"
      - "traefik.http.routers.docker.entrypoints=web"

networks:
  web:
    external: true
volumes:
  nexus-data:
    external: true

在 Nexus Repository Manager Dashboard 中,我创建了一个托管 docker 存储库并为其分配了端口 8083。

和特拉菲克:

version: '3.7'

services:
  traefik:
    container_name: traefik
    image: traefik
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./conf:/conf
      - ../ssl:/ssl:ro
    networks:
      - web
    ports:
      - 80:80
      - 443:443
    restart: always
    command:
      # Enabling docker provider
      - "--providers.docker=true"
      # Do not expose containers unless explicitly told so
      - "--providers.docker.exposedbydefault=false"
      # Enable API (listening on port 8080)
      - "--api.insecure=true"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      # Enable the file provider to define routers / middlewares / services in file
      # EMPTY AT THE TIME!
      - "--providers.file.directory=/conf"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.traefik.service=api@internal"
      - "traefik.http.routers.traefik.rule=Host(`traefik.xxx.intern`)"
      - "traefik.http.routers.traefik.entrypoints=web"
      - "traefik.http.routers.traefik_tls.tls=true"
      - "traefik.http.routers.traefik_tls.rule=Host(`traefik.xxx.intern`)"
      - "traefik.http.routers.traefik_tls.entrypoints=websecure"
      - "traefik.http.routers.traefik_tls.service=api@internal"
networks:
  web:
    external: true

我可以在任何地方登录 docker 存储库表单:

docker login -u user -p password1234 docker.nexus.xxx.intern
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
Login Succeeded

但我无法推入注册表:

docker push docker.nexus.xxx.intern/hello-world
The push refers to repository [docker.nexus.xxx.intern/hello-world]
af0b15c8625b: Preparing
error parsing HTTP 404 response body: invalid character 'p' after top-level value: "404 page not found\n"

当我暴露端口 8083 并绕过 Traefik 时,一切正常,我可以推送到 Nexus Registry。问题是我只能公开端口 80 和 443。

有没有人遇到过类似的问题并知道如何解决?

更新 1

也尝试过使用 Harbour - 结果相同 - 无法推动 traefik。

标签: dockerdocker-composetraefikdocker-registrynexus3

解决方案


对我来说同样的问题。我已经尝试过选项 1:在 v2 的路径上添加前缀,因为 Docker 正在放置 /v2 前缀

  • traefik.http.routers.docker.rule=Host(`docker.nexus.xxx.intern`) && PathPrefix(`/{version:(v1|v2)}/`)

选项 2:为请求添加前缀并使用中间件 replacepathregex 将其删除

  • traefik.http.middlewares.replace-path.replacepathregex.regex=^/(v1|v2)/(push|pull)/(.*)
  • traefik.http.middlewares.replace-path.replacepathregex.replacement=/$$1/$$3
  • traefik.http.routers.docker.rule=Host(`docker.nexus.xxx.intern`) && PathPrefix(`/{version:(v1|v2)}/push/`)
  • traefik.http.routers.nexus-registry-push.middlewares=replace-path

推荐阅读