dirBrowse rendered a single directory level but paid for a full recursive listing of the repo — on CephFS-backed LocalFS that is a walk of the entire storage root plus a sidecar read per object, which took Ceph down on large repos. Storage grows a ListDir primitive (os.ReadDir on localfs, Delimiter on S3) and the UI and the debian dists fallback use it; the recursive List stays for the docker page and now starts its walk at the requested prefix. The per-vrepo storage gauges on /metrics did the same full listing on every scrape; they are removed — the backend's own accounting (du, bucket metrics) covers capacity. Co-Authored-By: Claude Code <noreply@anthropic.com>
221 lines
8.3 KiB
YAML
221 lines
8.3 KiB
YAML
listen: ":8080"
|
|
|
|
storage:
|
|
# localfs | s3 | none. "none" disables caching entirely: every request is
|
|
# proxied straight through to the upstream and nothing is stored.
|
|
type: localfs
|
|
localfs:
|
|
root: ./data
|
|
# s3:
|
|
# bucket: my-cache
|
|
# region: us-east-1
|
|
# endpoint: http://localhost:9000 # optional, for MinIO etc.
|
|
# access_key: minioadmin
|
|
# secret_key: minioadmin
|
|
# prefix: cache
|
|
|
|
# GET /metrics serves Prometheus text exposition: per-vrepo request counts,
|
|
# durations and cache hit/miss/error counters; per-upstream attempts, response
|
|
# statuses, byte totals (payload and real socket bytes) and timings (connect,
|
|
# TLS handshake, time-to-first-byte, body); and Go runtime stats. Storage
|
|
# sizes are deliberately absent: listing a large store on every scrape is too
|
|
# expensive — use the backend's own accounting (`du`, bucket metrics) instead.
|
|
# Empty token (the default) leaves the endpoint open; set one to require
|
|
# `Authorization: Bearer <token>` or a `?token=<token>` query param.
|
|
# metrics:
|
|
# token: ""
|
|
|
|
# Every request is given a trace id (adopted from the caller's X-Request-Id or
|
|
# traceparent when it sent one), echoed back in X-Request-Id, attached to every
|
|
# log line the request produces, and passed on to the upstreams it calls — so
|
|
# one grep follows a request end to end, across chained proxies included.
|
|
# log:
|
|
# level: info # debug | info | warn | error
|
|
# format: text # text | json
|
|
# requests: true # one line when a client request arrives and one when it ends
|
|
# upstream: true # one line per outbound attempt against an upstream
|
|
|
|
vrepos:
|
|
# docker pull localhost:8080/dockerhub/library/nginx:1.27
|
|
- name: dockerhub
|
|
type: docker
|
|
upstream:
|
|
url: https://registry-1.docker.io
|
|
# username: myuser # optional Docker Hub credentials
|
|
# password: mytoken
|
|
# proxy: socks5://127.0.0.1:1080
|
|
auth:
|
|
mode: public # public | password | users
|
|
cache:
|
|
manifest_ttl: 5m
|
|
|
|
# docker pull localhost:8080/ghcr/org/image:tag (authenticated repo example)
|
|
- name: ghcr
|
|
type: docker
|
|
upstream:
|
|
url: https://ghcr.io
|
|
username: github-user
|
|
password: ghp_token
|
|
auth:
|
|
mode: password # any login + this password
|
|
password: s3cret
|
|
cache:
|
|
manifest_ttl: 1m
|
|
|
|
# https://localhost:8080/maven/central/com/google/guava/guava/33.0.0-jre/guava-33.0.0-jre.jar
|
|
- name: central
|
|
type: maven
|
|
upstream:
|
|
url: https://repo1.maven.org/maven2
|
|
auth:
|
|
mode: users
|
|
users:
|
|
alice: pw1
|
|
bob: pw2
|
|
cache:
|
|
metadata_ttl: 5m
|
|
|
|
# Maven with multiple upstreams (also supported for debian and pacman,
|
|
# without filters). Upstreams are tried in order: a 404, 401, 403 or
|
|
# connection error falls through to the next
|
|
# one, any other status is returned as-is. Each upstream may restrict what it
|
|
# serves with allowlist filters:
|
|
# groups: wildcard group prefixes; "com.google.*" covers the
|
|
# whole com/google tree ('*' crosses dots/slashes)
|
|
# artifacts: wildcard artifact names, e.g. "my-lib-*"
|
|
# snapshots_only: only -SNAPSHOT paths are requested from it
|
|
# An upstream with no filters matches everything. Per-upstream
|
|
# credentials and egress proxy work the same as the single-upstream form.
|
|
# Any upstream (of any type, single or listed) may set `cache: false` to
|
|
# be proxied through without being stored here — see the chained example
|
|
# below.
|
|
- name: maven-all
|
|
type: maven
|
|
upstreams:
|
|
- url: https://corp.example.com/maven-snapshots
|
|
username: deploy
|
|
password: s3cret
|
|
snapshots_only: true
|
|
- url: https://maven.google.com
|
|
groups: ["com.google.*"]
|
|
- url: https://repo1.maven.org/maven2
|
|
# `attempts` covers three failures, each waiting the upstream's
|
|
# Retry-After or a backoff when it sends none, at most max_wait per
|
|
# wait: a 429 (Too Many Requests), a connection that fails before any
|
|
# response arrives, and a transfer that dies mid-body (re-requested
|
|
# with a byte range and continued where it stopped). Once the attempts
|
|
# are spent the request falls through to the next upstream.
|
|
# Defaults: attempts 2, max_wait 5s; attempts 0 disables.
|
|
retry:
|
|
attempts: 3
|
|
max_wait: 10s
|
|
auth:
|
|
mode: public
|
|
cache:
|
|
metadata_ttl: 5m
|
|
|
|
# Chaining: a vrepo may use another vrepo of this proxy as an upstream.
|
|
# `cache: false` keeps the aggregator from storing a second copy of what
|
|
# the target vrepo already caches — the bytes live in `central` only, and
|
|
# `deps` just routes. Reads still hit `deps`'s own cache if something was
|
|
# stored there earlier by a cacheable upstream. Chained upstreams are
|
|
# ordinary HTTP requests: add username/password if the target vrepo is
|
|
# not `auth.mode: public`, and never let a chain loop back on itself.
|
|
- name: deps
|
|
type: maven
|
|
upstreams:
|
|
- url: https://mvn.example.com # cached here as usual
|
|
- url: http://localhost:8080/maven/central
|
|
cache: false # cached in the central vrepo
|
|
auth:
|
|
mode: public
|
|
cache:
|
|
metadata_ttl: 5m
|
|
|
|
# curl -LO http://localhost:8080/github/gh/golang/go/latest.json
|
|
# curl -LO http://localhost:8080/github/gh/golang/go/latest/go1.23.0.linux-amd64.tar.gz
|
|
- name: gh
|
|
type: github
|
|
# upstream.url defaults to https://github.com (API: api.github.com).
|
|
# For GitHub Enterprise set your instance URL (API: <url>/api/v3).
|
|
upstream:
|
|
url: https://github.com
|
|
# username: github-user # optional; PAT raises API rate limits
|
|
# password: ghp_token # and unlocks private repos
|
|
auth:
|
|
mode: public
|
|
# allow restricts which owner/repo pairs may be proxied (path.Match
|
|
# globs). Omit or leave empty to allow everything.
|
|
allow:
|
|
- "golang/*"
|
|
- "myorg/mytool"
|
|
# redirect: true (default) sends /latest and /snapshot to the resolved
|
|
# tag path with a 302; false serves content under the alias URL.
|
|
# redirect: false
|
|
cache:
|
|
metadata_ttl: 5m # release metadata + alias resolution
|
|
|
|
# Same, but with per-vhost users and an authenticated upstream (private
|
|
# repos), serving aliases in place instead of redirecting.
|
|
- name: gh-private
|
|
type: github
|
|
upstream:
|
|
url: https://github.com
|
|
username: github-user
|
|
password: ghp_token
|
|
auth:
|
|
mode: users
|
|
users:
|
|
carol: pw3
|
|
redirect: false
|
|
cache:
|
|
metadata_ttl: 1m
|
|
|
|
# Gitea releases: same URL grammar as the github type under /gitea/.
|
|
# There is no default upstream — point url at your instance (its API is
|
|
# served at <url>/api/v1).
|
|
# curl -LO http://localhost:8080/gitea/gt/myorg/mytool/latest/mytool_linux-amd64
|
|
- name: gt
|
|
type: gitea
|
|
upstream:
|
|
url: https://gitea.example.com
|
|
# username: gitea-user # optional; token unlocks private repos
|
|
# password: gitea_token
|
|
auth:
|
|
mode: public
|
|
# allow: ["myorg/*"]
|
|
# redirect: false
|
|
cache:
|
|
metadata_ttl: 5m
|
|
|
|
# Debian / APT repo. apt sources.list: deb http://localhost:8080/debian/deb bookworm main
|
|
# Open /ui/debian/deb/ for a generated sources.list line per distro version
|
|
# (bookworm, trixie, noble, ...) with each suite's components and
|
|
# architectures, probed from the mirror and memoized for metadata_ttl.
|
|
# Metadata under dists/** (Release, InRelease, Packages.*, ...) is cached
|
|
# for metadata_ttl; pool/** and by-hash/** are content-addressed and
|
|
# cached forever. Multiple upstreams act as mirrors: a 404, 401, 403 or
|
|
# connection error falls through to the next one (they must serve the
|
|
# same archive layout).
|
|
- name: deb
|
|
type: debian
|
|
upstreams:
|
|
- url: https://deb.debian.org/debian
|
|
- url: http://ftp.us.debian.org/debian
|
|
auth:
|
|
mode: public
|
|
cache:
|
|
metadata_ttl: 5m # dists/** freshness; packages immutable
|
|
|
|
# Pacman (Arch) mirror. pacman.conf: Server = http://localhost:8080/pacman/arch/$repo/os/$arch
|
|
# <repo>.db / <repo>.files (any compression, plus .sig) and lastupdate
|
|
# are cached for metadata_ttl; *.pkg.tar.* packages are immutable.
|
|
- name: arch
|
|
type: pacman
|
|
upstream:
|
|
url: https://geo.mirror.pkgbuild.com
|
|
auth:
|
|
mode: public # pacman has no native HTTP-auth support
|
|
cache:
|
|
metadata_ttl: 5m
|