Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,8 @@ cooldown:
default: "3d"
```

See the [configuration reference](docs/configuration.md#upstream-registries) for every upstream key, environment variable, and default URL.

Run with config file:

```bash
Expand Down
58 changes: 53 additions & 5 deletions config.example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -82,26 +82,74 @@ log:
access_log:
path: ""

# Upstream registry URLs and authentication
# Upstream URLs for built-in routes and authentication
upstream:
# npm registry URL
npm: "https://registry.npmjs.org"

# 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"

# Cargo sparse index URL
cargo: "https://index.crates.io"
# NuGet API URL
nuget: "https://api.nuget.org"

# Cargo crate download URL
cargo_download: "https://static.crates.io/crates"
# 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"

# 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"

# Debian/APT repository URL (used by /debian endpoint)
debian: "http://deb.debian.org/debian"

# RPM repository URL (used by /rpm endpoint)
rpm: "https://dl.fedoraproject.org/pub/fedora/linux"

# Named HTTP Helm chart repositories (used by /helm/{name}/)
# helm:
# bitnami: "https://charts.bitnami.com/bitnami"
Expand Down
47 changes: 41 additions & 6 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,16 +134,51 @@ Upstream retries and OCI authentication calls are separate `upstream` records, s

## Upstream Registries

Override default upstream registry URLs:
Each upstream used by a built-in package route can be set in YAML or JSON under `upstream`, or with its matching environment variable. Existing installations keep the same public upstreams by default. Trailing slashes are ignored.

| Config | Environment | Default |
|--------|-------------|---------|
| `upstream.npm` | `PROXY_UPSTREAM_NPM` | `https://registry.npmjs.org` |
| `upstream.cargo` | `PROXY_UPSTREAM_CARGO` | `https://index.crates.io` |
| `upstream.cargo_download` | `PROXY_UPSTREAM_CARGO_DOWNLOAD` | `https://static.crates.io/crates` |
| `upstream.gem` | `PROXY_UPSTREAM_GEM` | `https://rubygems.org` |
| `upstream.go` | `PROXY_UPSTREAM_GO` | `https://proxy.golang.org` |
| `upstream.hex` | `PROXY_UPSTREAM_HEX` | `https://repo.hex.pm` |
| `upstream.hex_api` | `PROXY_UPSTREAM_HEX_API` | `https://hex.pm` |
| `upstream.pub` | `PROXY_UPSTREAM_PUB` | `https://pub.dev` |
| `upstream.pypi` | `PROXY_UPSTREAM_PYPI` | `https://pypi.org` |
| `upstream.pypi_download` | `PROXY_UPSTREAM_PYPI_DOWNLOAD` | `https://files.pythonhosted.org` |
| `upstream.maven` | `PROXY_UPSTREAM_MAVEN` | `https://repo1.maven.org/maven2` |
| `upstream.gradle_plugin_portal` | `PROXY_UPSTREAM_GRADLE_PLUGIN_PORTAL` | `https://plugins.gradle.org/m2` |
| `upstream.nuget` | `PROXY_UPSTREAM_NUGET` | `https://api.nuget.org` |
| `upstream.nuget_search` | `PROXY_UPSTREAM_NUGET_SEARCH` | `https://azuresearch-usnc.nuget.org` |
| `upstream.composer` | `PROXY_UPSTREAM_COMPOSER` | `https://packagist.org` |
| `upstream.composer_repository` | `PROXY_UPSTREAM_COMPOSER_REPOSITORY` | `https://repo.packagist.org` |
| `upstream.conan` | `PROXY_UPSTREAM_CONAN` | `https://center.conan.io` |
| `upstream.conda` | `PROXY_UPSTREAM_CONDA` | `https://conda.anaconda.org` |
| `upstream.cran` | `PROXY_UPSTREAM_CRAN` | `https://cloud.r-project.org` |
| `upstream.julia` | `PROXY_UPSTREAM_JULIA` | `https://pkg.julialang.org` |
| `upstream.debian` | `PROXY_UPSTREAM_DEBIAN` | `http://deb.debian.org/debian` |
| `upstream.rpm` | `PROXY_UPSTREAM_RPM` | `https://dl.fedoraproject.org/pub/fedora/linux` |

For protocols that use separate metadata and download services, configure both values. They may point to the same endpoint when chaining proxies:

```yaml
upstream:
npm: "https://registry.npmjs.org"
maven: "https://repo1.maven.org/maven2"
gradle_plugin_portal: "https://plugins.gradle.org/m2"
cargo: "https://index.crates.io"
cargo_download: "https://static.crates.io/crates"
pypi: "https://upstream-proxy.example.com/pypi"
pypi_download: "https://upstream-proxy.example.com/pypi"
nuget: "https://upstream-proxy.example.com/nuget"
nuget_search: "https://upstream-proxy.example.com/nuget"
composer: "https://upstream-proxy.example.com/composer"
composer_repository: "https://upstream-proxy.example.com/composer"
```

`upstream.hex_api` is used for cooldown timestamps and must expose Hex's `/api/packages/{name}` JSON endpoint.

Helm HTTP repositories and additional OCI registries are configured as named maps rather than single URLs:

```yaml
upstream:
# Named HTTP Helm chart repositories, served at /helm/{name}/.
helm:
bitnami: "https://charts.bitnami.com/bitnami"
Expand Down
117 changes: 108 additions & 9 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,13 +289,49 @@ type AccessLogConfig struct {
Path string `json:"path" yaml:"path"`
}

// UpstreamConfig configures upstream registry URLs and authentication.
// UpstreamConfig configures upstream URLs for built-in routes and authentication.
// Leave empty to use defaults.
type UpstreamConfig struct {
// NPM is the upstream npm registry URL.
// Default: https://registry.npmjs.org
NPM string `json:"npm" yaml:"npm"`

// Cargo is the upstream cargo index URL.
// Default: https://index.crates.io
Cargo string `json:"cargo" yaml:"cargo"`

// CargoDownload is the upstream cargo download URL.
// Default: https://static.crates.io/crates
CargoDownload string `json:"cargo_download" yaml:"cargo_download"`

// Gem is the upstream RubyGems registry URL.
// Default: https://rubygems.org
Gem string `json:"gem" yaml:"gem"`

// Go is the upstream Go module proxy URL.
// Default: https://proxy.golang.org
Go string `json:"go" yaml:"go"`

// Hex is the upstream Hex repository URL.
// Default: https://repo.hex.pm
Hex string `json:"hex" yaml:"hex"`

// HexAPI is the upstream Hex API URL used for package timestamps.
// Default: https://hex.pm
HexAPI string `json:"hex_api" yaml:"hex_api"`

// Pub is the upstream pub registry URL.
// Default: https://pub.dev
Pub string `json:"pub" yaml:"pub"`

// PyPI is the upstream PyPI index and API URL.
// Default: https://pypi.org
PyPI string `json:"pypi" yaml:"pypi"`

// PyPIDownload is the upstream PyPI package download URL.
// Default: https://files.pythonhosted.org
PyPIDownload string `json:"pypi_download" yaml:"pypi_download"`

// Maven is the upstream Maven repository URL.
// Default: https://repo1.maven.org/maven2
Maven string `json:"maven" yaml:"maven"`
Expand All @@ -305,19 +341,47 @@ type UpstreamConfig struct {
// Default: https://plugins.gradle.org/m2
GradlePluginPortal string `json:"gradle_plugin_portal" yaml:"gradle_plugin_portal"`

// Cargo is the upstream cargo index URL.
// Default: https://index.crates.io
Cargo string `json:"cargo" yaml:"cargo"`
// NuGet is the upstream NuGet API URL.
// Default: https://api.nuget.org
NuGet string `json:"nuget" yaml:"nuget"`

// CargoDownload is the upstream cargo download URL.
// Default: https://static.crates.io/crates
CargoDownload string `json:"cargo_download" yaml:"cargo_download"`
// NuGetSearch is the upstream NuGet search API URL.
// Default: https://azuresearch-usnc.nuget.org
NuGetSearch string `json:"nuget_search" yaml:"nuget_search"`

// Composer is the upstream Packagist API URL.
// Default: https://packagist.org
Composer string `json:"composer" yaml:"composer"`

// ComposerRepository is the upstream Packagist repository URL.
// Default: https://repo.packagist.org
ComposerRepository string `json:"composer_repository" yaml:"composer_repository"`

// Conan is the upstream Conan registry URL.
// Default: https://center.conan.io
Conan string `json:"conan" yaml:"conan"`

// Conda is the upstream Conda channel base URL.
// Default: https://conda.anaconda.org
Conda string `json:"conda" yaml:"conda"`

// CRAN is the upstream CRAN mirror URL.
// Default: https://cloud.r-project.org
CRAN string `json:"cran" yaml:"cran"`

// Julia is the upstream Julia package server URL.
// Default: https://pkg.julialang.org
Julia string `json:"julia" yaml:"julia"`

// Debian is the upstream APT repository base URL.
// Example: http://archive.ubuntu.com/ubuntu would get Ubuntu.
// Default: http://deb.debian.org/debian
Debian string `json:"debian" yaml:"debian"`

// RPM is the upstream RPM repository base URL.
// Default: https://dl.fedoraproject.org/pub/fedora/linux
RPM string `json:"rpm" yaml:"rpm"`

// Helm maps repository names to HTTP Helm chart repository URLs.
// Requests use /helm/{name}/index.yaml and chart URLs in the index are
// rewritten to the same named proxy endpoint.
Expand Down Expand Up @@ -471,11 +535,27 @@ func Default() *Config {
},
Upstream: UpstreamConfig{
NPM: "https://registry.npmjs.org",
Maven: "https://repo1.maven.org/maven2",
GradlePluginPortal: "https://plugins.gradle.org/m2",
Cargo: "https://index.crates.io",
CargoDownload: "https://static.crates.io/crates",
Gem: "https://rubygems.org",
Go: "https://proxy.golang.org",
Hex: "https://repo.hex.pm",
HexAPI: "https://hex.pm",
Pub: "https://pub.dev",
PyPI: "https://pypi.org",
PyPIDownload: "https://files.pythonhosted.org",
Maven: "https://repo1.maven.org/maven2",
GradlePluginPortal: "https://plugins.gradle.org/m2",
NuGet: "https://api.nuget.org",
NuGetSearch: "https://azuresearch-usnc.nuget.org",
Composer: "https://packagist.org",
ComposerRepository: "https://repo.packagist.org",
Conan: "https://center.conan.io",
Conda: "https://conda.anaconda.org",
CRAN: "https://cloud.r-project.org",
Julia: "https://pkg.julialang.org",
Debian: "http://deb.debian.org/debian",
RPM: "https://dl.fedoraproject.org/pub/fedora/linux",
},
Gradle: GradleConfig{
BuildCache: GradleBuildCacheConfig{
Expand Down Expand Up @@ -563,9 +643,28 @@ func (c *Config) LoadFromEnv() {
setEnvString(&c.Log.Level, "PROXY_LOG_LEVEL")
setEnvString(&c.Log.Format, "PROXY_LOG_FORMAT")
setEnvString(&c.AccessLog.Path, "PROXY_ACCESS_LOG_PATH")
setEnvString(&c.Upstream.NPM, "PROXY_UPSTREAM_NPM")
setEnvString(&c.Upstream.Cargo, "PROXY_UPSTREAM_CARGO")
setEnvString(&c.Upstream.CargoDownload, "PROXY_UPSTREAM_CARGO_DOWNLOAD")
setEnvString(&c.Upstream.Gem, "PROXY_UPSTREAM_GEM")
setEnvString(&c.Upstream.Go, "PROXY_UPSTREAM_GO")
setEnvString(&c.Upstream.Hex, "PROXY_UPSTREAM_HEX")
setEnvString(&c.Upstream.HexAPI, "PROXY_UPSTREAM_HEX_API")
setEnvString(&c.Upstream.Pub, "PROXY_UPSTREAM_PUB")
setEnvString(&c.Upstream.PyPI, "PROXY_UPSTREAM_PYPI")
setEnvString(&c.Upstream.PyPIDownload, "PROXY_UPSTREAM_PYPI_DOWNLOAD")
setEnvString(&c.Upstream.Maven, "PROXY_UPSTREAM_MAVEN")
setEnvString(&c.Upstream.GradlePluginPortal, "PROXY_UPSTREAM_GRADLE_PLUGIN_PORTAL")
setEnvString(&c.Upstream.NuGet, "PROXY_UPSTREAM_NUGET")
setEnvString(&c.Upstream.NuGetSearch, "PROXY_UPSTREAM_NUGET_SEARCH")
setEnvString(&c.Upstream.Composer, "PROXY_UPSTREAM_COMPOSER")
setEnvString(&c.Upstream.ComposerRepository, "PROXY_UPSTREAM_COMPOSER_REPOSITORY")
setEnvString(&c.Upstream.Conan, "PROXY_UPSTREAM_CONAN")
setEnvString(&c.Upstream.Conda, "PROXY_UPSTREAM_CONDA")
setEnvString(&c.Upstream.CRAN, "PROXY_UPSTREAM_CRAN")
setEnvString(&c.Upstream.Julia, "PROXY_UPSTREAM_JULIA")
setEnvString(&c.Upstream.Debian, "PROXY_UPSTREAM_DEBIAN")
setEnvString(&c.Upstream.RPM, "PROXY_UPSTREAM_RPM")
setEnvString(&c.Cooldown.Default, "PROXY_COOLDOWN_DEFAULT")
setEnvBool(&c.CacheMetadata, "PROXY_CACHE_METADATA")
setEnvBool(&c.MirrorAPI, "PROXY_MIRROR_API")
Expand Down
Loading