mirror of
https://github.com/git-pkgs/proxy.git
synced 2026-11-09 15:49:16 -05:00
- Keep a gzip copy of each rewrite cache entry when it is smaller, made once
per rewrite and counted against metadata_rewrite_cache_size
- Serve it with Content-Encoding: gzip to clients that accept gzip, with an
ETag of its own ("<sha256>-gzip") and Vary: Accept-Encoding
- Rewrites made outside the cache (cache disabled, cooldown on) stay
uncompressed
- rewriteCache.get and rewrite return rewrittenMetadata
448 lines
16 KiB
YAML
448 lines
16 KiB
YAML
# Proxy server configuration
|
|
# Copy to config.yaml and modify as needed
|
|
|
|
# Server listen address
|
|
listen: ":8080"
|
|
|
|
# Public URL where package endpoints are reachable.
|
|
# Used for rewriting package metadata URLs and shown in install guide snippets
|
|
# so users know what to point their package manager at.
|
|
base_url: "http://localhost:8080"
|
|
|
|
# Timeout for individual upstream HTTP requests made by protocol handlers
|
|
# (metadata fetches, pass-through file requests). Uses Go duration syntax.
|
|
# Set to "0" to disable the timeout. Default: "30s".
|
|
# http_timeout: "30s"
|
|
|
|
# Largest upstream artifact to fetch (e.g. "2GB"). Larger ones are refused
|
|
# and not cached. Default: unlimited.
|
|
# artifact_max_size: ""
|
|
|
|
# Memory for rewritten npm and Composer metadata, so each upstream document is
|
|
# rewritten and gzip-compressed once rather than on every request. Set to "0"
|
|
# to rewrite on every request. Default: "256MB".
|
|
# metadata_rewrite_cache_size: "256MB"
|
|
|
|
# Public URL where the web UI is reached. Defaults to base_url when unset.
|
|
# Set this separately when the UI is served on a different hostname than the
|
|
# package endpoints — for example, the UI on a public domain behind auth while
|
|
# build machines hit a Docker network alias for the package endpoints.
|
|
# ui_base_url: "https://proxy.example.com/ui"
|
|
|
|
# Attribute requests to the leftmost X-Forwarded-For entry rather than the TCP
|
|
# peer address, in the structured log, the access log and the request-source
|
|
# table on /ui/analytics.
|
|
#
|
|
# Enable this only when the proxy sits behind a load balancer or ingress that
|
|
# sets the header. Any client can send it: behind one it is the only way to see
|
|
# past the hop, in front of one it lets a caller forge its own address.
|
|
# trust_forwarded_for: false
|
|
|
|
# Show the request-source table on /ui/analytics: caller addresses, the tool
|
|
# each ran and how much each pulled.
|
|
#
|
|
# Off by default. The proxy has no authentication of its own, so leave this off
|
|
# unless /ui is gated by a reverse proxy; anyone who can reach the page can
|
|
# otherwise read the addresses of your build fleet.
|
|
# ui_request_sources: false
|
|
|
|
# List the latest failures behind each failure count on /ui/analytics (upstream,
|
|
# storage, integrity, health probe and scan errors): the package, its upstream
|
|
# URL or storage path, and the error. URLs lose credentials and query strings.
|
|
#
|
|
# Off by default, for the same reason as ui_request_sources.
|
|
# ui_failure_details: false
|
|
|
|
# Artifact storage configuration
|
|
storage:
|
|
# Storage backend URL
|
|
# Supported schemes:
|
|
# - file:///path/to/dir - Local filesystem (default)
|
|
# - s3://bucket-name - Amazon S3
|
|
# - s3://bucket?endpoint=http://localhost:9000 - S3-compatible (MinIO)
|
|
# - gs://bucket-name - Google Cloud Storage
|
|
# - azblob://container-name - Azure Blob Storage
|
|
#
|
|
# For S3, configure credentials via environment variables:
|
|
# AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION
|
|
#
|
|
# For GCS, authentication uses Application Default Credentials. On GKE with
|
|
# Workload Identity, bind the Kubernetes service account to a Google service
|
|
# account that has roles/storage.objectAdmin on the bucket. No extra config
|
|
# is needed in this file. For local development, run:
|
|
# gcloud auth application-default login
|
|
# If direct_serve is enabled, the service account also needs
|
|
# roles/iam.serviceAccountTokenCreator on itself so the IAM Credentials
|
|
# signBlob API can sign URLs without a private key.
|
|
url: ""
|
|
|
|
# Local filesystem path (used when url is empty)
|
|
# Deprecated: Use url with file:// scheme instead
|
|
path: "./cache/artifacts"
|
|
|
|
# Maximum cache size (e.g., "10GB", "500MB")
|
|
# When exceeded, least recently used artifacts are evicted
|
|
# Empty or "0" means unlimited
|
|
max_size: ""
|
|
|
|
# Evict artifacts that have not been served for longer than a duration
|
|
# ("30d", "72h"), independent of max_size. Resolution order: package rule,
|
|
# then ecosystem rule, then default. "0" or empty means never evict by age.
|
|
# The default only applies to ecosystems that support retention; naming an
|
|
# ecosystem or package that does not is a configuration error. See
|
|
# docs/configuration.md for the supported ecosystems.
|
|
retention:
|
|
default: ""
|
|
# ecosystems:
|
|
# npm: "30d"
|
|
# packages:
|
|
# "pkg:npm/lodash": "0"
|
|
# How often to look for expired artifacts; at least "1m".
|
|
sweep_interval: "10m"
|
|
|
|
# Store fetched artifacts. Set to false to stream every download from
|
|
# upstream without storing it; metadata filtering, cooldown and the
|
|
# denylist still apply. Useful when another cache sits in front of the
|
|
# proxy. false is incompatible with direct_serve, scanning and mirror_api.
|
|
cache_artifacts: true
|
|
|
|
# Redirect cached artifact downloads to presigned storage URLs (HTTP 302)
|
|
# instead of streaming through the proxy. Only effective for S3, GCS, and Azure.
|
|
# Leave disabled if clients reach the proxy through an authenticating gateway,
|
|
# since presigned URLs bypass it.
|
|
direct_serve: false
|
|
|
|
# How long presigned URLs remain valid (e.g. "5m", "1h"). Default: "15m".
|
|
direct_serve_ttl: "15m"
|
|
|
|
# Public base URL to substitute into presigned URLs. Set this when the
|
|
# proxy reaches storage at an internal address (127.0.0.1, a Docker
|
|
# service name) but clients must use a public hostname. Only scheme and
|
|
# host are used; the signed path and query are preserved. For S3/MinIO
|
|
# the reverse proxy at this address must forward requests with the
|
|
# internal Host header or the SigV4 signature will not validate.
|
|
# direct_serve_base_url: "https://minio.example.com"
|
|
|
|
# Database configuration
|
|
database:
|
|
# Database driver: "sqlite" (default) or "postgres"
|
|
driver: "sqlite"
|
|
|
|
# SQLite database file path (used when driver is "sqlite")
|
|
path: "./cache/proxy.db"
|
|
|
|
# PostgreSQL connection URL (used when driver is "postgres")
|
|
# Example: "postgres://user:password@localhost:5432/proxy?sslmode=disable"
|
|
url: ""
|
|
|
|
# How often cache hit counts and last-access times are written, batched in
|
|
# one transaction. "0" writes each hit as it happens.
|
|
hit_flush_interval: "1s"
|
|
|
|
# Logging configuration
|
|
log:
|
|
# Minimum log level: "debug", "info", "warn", "error"
|
|
level: "info"
|
|
|
|
# Log format: "text" or "json"
|
|
format: "text"
|
|
|
|
# JSONL access log. Leave path empty to disable it.
|
|
access_log:
|
|
path: ""
|
|
|
|
# Upstream URLs for built-in routes and authentication
|
|
upstream:
|
|
# Hosts allowed to resolve to private, ULA, or CGNAT addresses
|
|
allow_private_hosts: []
|
|
|
|
# Permit upstream requests and redirects to loopback addresses
|
|
allow_loopback: false
|
|
|
|
# npm registry URL
|
|
npm: "https://registry.npmjs.org"
|
|
# Always request full npm packuments so served metadata carries publish
|
|
# times ("time" map) even when cooldown is disabled. Needed by clients that
|
|
# gate on publish age, e.g. Yarn's npmMinimalAgeGate. Default: false.
|
|
# npm_full_metadata: true
|
|
|
|
# npm packages served only from a private registry, by name pattern.
|
|
# Matching packages are never looked up on the npm registry above.
|
|
# npm_routes:
|
|
# "@example/*": "https://npm.example.com/registry"
|
|
|
|
# Cargo sparse index URL
|
|
cargo: "https://index.crates.io"
|
|
|
|
# Cargo crate download URL
|
|
cargo_download: "https://static.crates.io/crates"
|
|
|
|
# RubyGems registry URL
|
|
gem: "https://rubygems.org"
|
|
|
|
# Go module proxy URL
|
|
go: "https://proxy.golang.org"
|
|
|
|
# Hex repository URL
|
|
hex: "https://repo.hex.pm"
|
|
|
|
# Hex API URL used for package timestamps
|
|
hex_api: "https://hex.pm"
|
|
|
|
# pub registry URL
|
|
pub: "https://pub.dev"
|
|
|
|
# PyPI index and API URL
|
|
pypi: "https://pypi.org"
|
|
|
|
# PyPI package download URL
|
|
pypi_download: "https://files.pythonhosted.org"
|
|
|
|
# Maven repository URL (used by /maven endpoint)
|
|
maven: "https://repo1.maven.org/maven2"
|
|
|
|
# Gradle Plugin Portal Maven URL (fallback for plugin marker artifacts)
|
|
gradle_plugin_portal: "https://plugins.gradle.org/m2"
|
|
|
|
# NuGet API URL
|
|
nuget: "https://api.nuget.org"
|
|
|
|
# NuGet search API URL
|
|
nuget_search: "https://azuresearch-usnc.nuget.org"
|
|
|
|
# Packagist API URL
|
|
composer: "https://packagist.org"
|
|
|
|
# Packagist repository URL
|
|
composer_repository: "https://repo.packagist.org"
|
|
|
|
# Composer packages served only from a private repository, by name pattern.
|
|
# Matching packages are never looked up on composer_repository.
|
|
# composer_routes:
|
|
# "example/*": "https://composer.example.com/packages"
|
|
|
|
# Conan registry URL
|
|
conan: "https://center.conan.io"
|
|
|
|
# Conda channel base URL
|
|
conda: "https://conda.anaconda.org"
|
|
|
|
# CRAN mirror URL
|
|
cran: "https://cloud.r-project.org"
|
|
|
|
# Julia package server URL
|
|
julia: "https://pkg.julialang.org"
|
|
|
|
# Swift Package Registry URL (used by /swift endpoint)
|
|
swift: "https://tuist.dev/api/registry/swift"
|
|
|
|
# Default OCI registry URL for unprefixed /v2 requests
|
|
oci_default: "https://registry-1.docker.io"
|
|
|
|
# Debian/APT repository URL (used by /debian endpoint)
|
|
debian: "http://deb.debian.org/debian"
|
|
|
|
# Additional Debian/APT archives, served at /debian/{name}/.
|
|
# The names "pool" and "dists" are reserved for the main archive's own paths.
|
|
debian_repositories:
|
|
security: "https://security.debian.org/debian-security"
|
|
|
|
# RPM repository URL (used by /rpm endpoint)
|
|
rpm: "https://dl.fedoraproject.org/pub/fedora/linux"
|
|
|
|
# Homebrew JSON API URL (used by /homebrew endpoint)
|
|
homebrew_api: "https://formulae.brew.sh/api"
|
|
|
|
# Homebrew artifact registry URL (used for /v2/homebrew/core requests)
|
|
homebrew_artifact: "https://ghcr.io"
|
|
|
|
# Named HTTP Helm chart repositories (used by /helm/{name}/)
|
|
# helm:
|
|
# bitnami: "https://charts.bitnami.com/bitnami"
|
|
|
|
# Named OCI registries. Use the upstream/{name}/ repository prefix, e.g.
|
|
# oci://proxy.example.com/upstream/ghcr/owner/chart.
|
|
# oci:
|
|
# ghcr: "https://ghcr.io"
|
|
|
|
# Registries a named OCI upstream mirrors, e.g. when ghcr above points at
|
|
# an Artifactory remote of ghcr.io. containerd mirror requests whose ns
|
|
# parameter names one of these hosts are served by that upstream.
|
|
# oci_mirrors:
|
|
# ghcr: ["ghcr.io"]
|
|
|
|
# Named Alpine APK repositories (used by /apk/{name}/).
|
|
# Defaults to {"alpine": "https://dl-cdn.alpinelinux.org/alpine"} when empty;
|
|
# configuring any entry replaces that default.
|
|
# apk:
|
|
# alpine: "https://dl-cdn.alpinelinux.org/alpine"
|
|
# private: "https://apk.example.com"
|
|
|
|
# Named Arch Linux pacman mirrors (used by /arch/{name}/).
|
|
# Defaults to {"archlinux": "https://geo.mirror.pkgbuild.com"} when empty;
|
|
# configuring any entry replaces that default. Arch Linux ARM needs a
|
|
# regional HTTPS mirror of your choice, not the mirror.archlinuxarm.org
|
|
# redirector.
|
|
# arch:
|
|
# archlinux: "https://geo.mirror.pkgbuild.com"
|
|
# archlinuxarm: "https://<region>.mirror.archlinuxarm.org"
|
|
|
|
# Named generic HTTP upstreams (used by /generic/{name}/). The remaining
|
|
# request path and query are appended to the upstream URL. GitHub release
|
|
# assets ({owner}/{repo}/releases/download/{tag}/{asset}) are cached
|
|
# immutably; other paths use the metadata cache with stale-on-error.
|
|
# generic:
|
|
# github: "https://github.com"
|
|
# github-api: "https://api.github.com"
|
|
# apache: "https://archive.apache.org"
|
|
|
|
# Version-pinned paths of generic upstreams, cached immutably like GitHub
|
|
# release assets. Each pattern must match the whole path after
|
|
# /generic/{name}/ and have `version` and `file` named groups; an optional
|
|
# `name` group names the package.
|
|
# generic_artifacts:
|
|
# apache:
|
|
# - 'dist/(?P<name>maven)/maven-3/(?P<version>[^/]+)/binaries/(?P<file>[^/]+)'
|
|
|
|
# Authentication for upstream registries
|
|
# Keys are absolute URL scopes. Scheme, host, effective port, and path
|
|
# segment boundaries must match; the longest matching scope wins.
|
|
# Values can reference environment variables using ${VAR_NAME} syntax.
|
|
#
|
|
# Supported auth types:
|
|
# - bearer: Authorization header with Bearer token
|
|
# - basic: Authorization header with Basic auth (username:password)
|
|
# - header: Custom header name and value
|
|
# - ecr: AWS ECR auto-refreshing token via the AWS SDK credential chain
|
|
auth:
|
|
# Example: npm with bearer token
|
|
# "https://registry.npmjs.org":
|
|
# type: bearer
|
|
# token: "${NPM_TOKEN}"
|
|
|
|
# Example: GitHub npm registry
|
|
# "https://npm.pkg.github.com":
|
|
# type: bearer
|
|
# token: "${GITHUB_TOKEN}"
|
|
|
|
# Example: PyPI with basic auth
|
|
# "https://pypi.org":
|
|
# type: basic
|
|
# username: "__token__"
|
|
# password: "${PYPI_TOKEN}"
|
|
|
|
# Example: Custom header for private registry
|
|
# "https://maven.mycompany.com":
|
|
# type: header
|
|
# header_name: "X-Auth-Token"
|
|
# header_value: "${MAVEN_TOKEN}"
|
|
|
|
# Example: private AWS ECR registry (12h tokens auto-refreshed via
|
|
# ecr:GetAuthorizationToken; credentials come from the AWS SDK default
|
|
# chain, so IRSA / instance profiles / AWS_* env vars all work; the region
|
|
# is inferred from the private ECR hostname)
|
|
# "https://123456789012.dkr.ecr.eu-west-1.amazonaws.com":
|
|
# type: ecr
|
|
|
|
# Gradle HttpBuildCache configuration
|
|
gradle:
|
|
build_cache:
|
|
# Set to true to disable PUT uploads (read-only cache mode)
|
|
read_only: false
|
|
|
|
# Maximum accepted Gradle cache upload body size
|
|
# Required and must be > 0
|
|
max_upload_size: "100MB"
|
|
|
|
# Evict entries older than this age (set to "0" to disable age-based eviction)
|
|
max_age: "168h"
|
|
|
|
# Cap total Gradle cache size; oldest entries are deleted first
|
|
# ("0" disables size-based eviction)
|
|
# max_size: "20GB"
|
|
|
|
# How often eviction runs when max_age or max_size is set
|
|
sweep_interval: "10m"
|
|
|
|
# Pushing package archives to /api/hosted (disabled by default).
|
|
# A pushed version replaces the upstream one for every client, so a token is
|
|
# required to push and delete.
|
|
# hosted:
|
|
# enabled: true
|
|
# token: "${PROXY_HOSTED_TOKEN}"
|
|
# max_upload_size: "100MB"
|
|
# # Namespaces served from pushed packages only; the upstream is never asked
|
|
# # about them, so nobody can mix in versions by publishing the same name.
|
|
# npm_scopes: ["@acme"]
|
|
# composer_vendors: ["acme"]
|
|
|
|
# Health endpoint configuration.
|
|
health:
|
|
# Minimum time between storage backend probes.
|
|
# The /health endpoint runs a write/read/verify/delete round-trip
|
|
# against the configured storage backend and caches the result for
|
|
# this interval. Set to "0" to probe on every request.
|
|
# Default: "30s".
|
|
storage_probe_interval: "30s"
|
|
|
|
# Version cooldown configuration
|
|
# Hides package versions published too recently, giving the community time
|
|
# to spot malicious releases before they're pulled into projects.
|
|
# Supported durations: "7d" (days), "48h" (hours), "30m" (minutes), "0" (disabled)
|
|
cooldown:
|
|
# Global default cooldown for all ecosystems
|
|
# default: "3d"
|
|
|
|
# Per-ecosystem overrides
|
|
# ecosystems:
|
|
# npm: "7d"
|
|
# cargo: "0"
|
|
|
|
# Per-package overrides (keyed by PURL). Keys are normalized, so npm scopes
|
|
# may use either @scope or the canonical %40scope form.
|
|
# packages:
|
|
# "pkg:npm/lodash": "0"
|
|
# "pkg:npm/@babel/core": "14d"
|
|
|
|
# Per-package glob overrides, after exact packages and before ecosystems.
|
|
# package_patterns:
|
|
# "pkg:npm/@example/*": "0"
|
|
|
|
# Exact versions to deny, independently of cooldown and scanning.
|
|
# Metadata filtering: npm, PyPI and Cargo. Shared artifact downloads, including
|
|
# cache hits, are blocked with 403; signed APT metadata is left unchanged.
|
|
# Use versioned PURLs without qualifiers/subpaths. Restart after changes.
|
|
# denylist:
|
|
# packages:
|
|
# - "pkg:pypi/requests@2.31.0"
|
|
# - "pkg:cargo/some-crate@1.2.3"
|
|
# - "pkg:npm/%40scope/example@4.5.6"
|
|
|
|
# Pre-cache artifact scanning. When enabled, every artifact is staged into
|
|
# storage and scanned by the configured scanners before it is committed to
|
|
# the cache and served to clients. Scanners never receive artifact bytes
|
|
# directly — each notify call includes a short-lived signed URL that the
|
|
# scanner fetches itself, so the proxy stays agnostic to trivy/ClamAV/Wiz/
|
|
# any custom service. Scanners run concurrently; the first "block" verdict
|
|
# wins and cancels the rest.
|
|
# scanning:
|
|
# enabled: true
|
|
# fail_open: false
|
|
# timeout: 30s
|
|
#
|
|
# # Authenticates pull requests to the internal scan-fetch route.
|
|
# # Required whenever enabled is true. Supports ${VAR_NAME} expansion.
|
|
# signing_key: ${PROXY_SCANNING_SIGNING_KEY}
|
|
#
|
|
# # Address scanners use to reach this proxy to pull staged artifacts.
|
|
# # Defaults to base_url.
|
|
# # fetch_base_url: http://proxy.internal:8080
|
|
#
|
|
# scanners:
|
|
# - name: clamav
|
|
# url: http://clamav-adapter:8080/scan
|
|
# mode: block
|
|
# - name: trivy
|
|
# url: http://trivy-adapter:8081/scan
|
|
# mode: monitor
|
|
# ecosystems: [npm, pypi]
|