-Entitlement Tokens, User Credentials and API-Keys should be treated as secrets, and you should ensure that you do not commit them in configurations files along with source code, or expose them in any logs.
+
+Entitlement Tokens and API-Keys should be treated as secrets. You should ensure that you do not commit them in configuration files along with source code, or expose them in any logs.
-To install Alpine packages from a private Cloudsmith repository, you can quickly set up the repository automatically:
+
+To install Alpine packages from a private Cloudsmith repository, you can set up the repository using the following:
```shell Entitlement Token Auth
curl -sLf 'https://dl.cloudsmith.io/TOKEN/OWNER/REPOSITORY/cfg/setup/bash.alpine.sh' \
| sudo bash
```
-```shell HTTP Basic Auth (User & Pass)
-sudo apk add --no-cache bash
-curl -u "USERNAME:PASSWORD" -sLf \
- 'https://dl.cloudsmith.io/basic/OWNER/REPOSITORY/cfg/setup/bash.alpine.sh' \
- | sudo bash
-```
+
```shell HTTP Basic Auth (API-Key)
sudo apk add --no-cache bash
curl -u "USERNAME:API-KEY" -sLf \
'https://dl.cloudsmith.io/basic/OWNER/REPOSITORY/cfg/setup/bash.alpine.sh' \
| sudo bash
```
+
```shell HTTP Basic Auth (Token)
sudo apk add --no-cache bash
curl -u "token:TOKEN" -sLf \
@@ -129,57 +154,62 @@ curl -u "token:TOKEN" -sLf \
| sudo bash
```
-If you need to force a specific distribution:
+If you need to force a specific distribution, set `distro` and `codename` (for Alpine):
-```shell Entitlement Token Auth
+```shell Alpine (Entitlement Token)
sudo apk add --no-cache bash
curl -sLf 'https://dl.cloudsmith.io/TOKEN/OWNER/REPOSITORY/cfg/setup/bash.alpine.sh' \
-| sudo distro=alpine codename=VERSION bash
-```
-```shell HTTP Basic Auth (User & Pass)
-sudo apk add --no-cache bash
-curl -u "USERNAME:PASSWORD" -sLf \
- 'https://dl.cloudsmith.io/basic/OWNER/REPOSITORY/cfg/setup/bash.alpine.sh' \
- | sudo distro=alpine codename=VERSION bash
-```
-```shell HTTP Basic Auth (API-Key)
-sudo apk add --no-cache bash
-curl -u "USERNAME:API-KEY" -sLf \
- 'https://dl.cloudsmith.io/basic/OWNER/REPOSITORY/cfg/setup/bash.alpine.sh' \
- | sudo distro=alpine codename=VERSION bash
-```
-```shell HTTP Basic Auth (Token)
-sudo apk add --no-cache bash
-curl -u "token:TOKEN" -sLf \
- 'https://dl.cloudsmith.io/basic/OWNER/REPOSITORY/cfg/setup/bash.alpine.sh' \
| sudo distro=alpine codename=VERSION bash
```
-Or, you can manually configure the repository:
+Or, you can manually configure the repository for Alpine:
```shell Entitlement Token Auth
-curl -sLf 'https://dl.cloudsmith.io/TOKEN/OWNER/REPOSITORY/cfg/rsa/rsa.FINGERPRINT.key' > /etc/apk/keys/REPOSITORY@OWNER-FINGERPRINT.rsa.pub
-curl -sLf 'https://dl.cloudsmith.io/TOKEN/OWNER/REPOSITORY/cfg/setup/config.alpine.txt?distro=alpine&codename=VERSION' >> /etc/apk/repositories
+curl -1sLf 'https://dl.cloudsmith.io/TOKEN/OWNER/REPOSITORY/rsa.FINGERPRINT.key' \
+ > /etc/apk/keys/REPOSITORY@OWNER-FINGERPRINT.rsa.pub
+echo "https://dl.cloudsmith.io/TOKEN/OWNER/REPOSITORY/alpine/VERSION/main" \
+ > /etc/apk/repositories
apk update
```
-```shell HTTP Basic Auth (User & Pass)
-curl -u "USERNAME:PASSWORD" -sLf 'https://dl.cloudsmith.io/basic/OWNER/REPOSITORY/cfg/rsa/rsa.FINGERPRINT.key' > /etc/apk/keys/REPOSITORY@OWNER-FINGERPRINT.rsa.pub
-curl -u "USERNAME:PASSWORD" -sLf 'https://dl.cloudsmith.io/basic/OWNER/REPOSITORY/cfg/setup/config.alpine.txt?distro=alpine&codename=VERSION' >> /etc/apk/repositories
-apk update
-```
-```shell HTTP Basic Auth (API-Key)
-curl -u "USERNAME:API-KEY" -sLf 'https://dl.cloudsmith.io/basic/OWNER/REPOSITORY/cfg/rsa/rsa.FINGERPRINT.key' > /etc/apk/keys/REPOSITORY@OWNER-FINGERPRINT.rsa.pub
-curl -u "USERNAME:API-KEY" -sLf 'https://dl.cloudsmith.io/basic/OWNER/REPOSITORY/cfg/setup/config.alpine.txt?distro=alpine&codename=VERSION' >> /etc/apk/repositories
+
+```shell HTTP Basic Auth
+curl -u "token:TOKEN" -1sLf 'https://dl.cloudsmith.io/basic/OWNER/REPOSITORY/rsa.FINGERPRINT.key' \
+ > /etc/apk/keys/REPOSITORY@OWNER-FINGERPRINT.rsa.pub
+echo "https://token:TOKEN@dl.cloudsmith.io/basic/OWNER/REPOSITORY/alpine/VERSION/main" \
+ > /etc/apk/repositories
apk update
```
-```shell HTTP Basic Auth (Token)
-curl -u "token:TOKEN" -sLf 'https://dl.cloudsmith.io/basic/OWNER/REPOSITORY/cfg/rsa/rsa.FINGERPRINT.key' > /etc/apk/keys/REPOSITORY@OWNER-FINGERPRINT.rsa.pub
-curl -u "token:TOKEN" -sLf 'https://dl.cloudsmith.io/basic/OWNER/REPOSITORY/cfg/setup/config.alpine.txt?distro=alpine&codename=VERSION' >> /etc/apk/repositories
-apk update
+
+Alternatively, for Wolfi distributions:
+
+```shell Manual Configuration
+apk add curl
+
+# Remove existing Wolfi/Chainguard keys and repository list
+rm -f /etc/apk/keys/chainguard-*
+rm -f /etc/apk/keys/wolfi-signing.rsa.pub
+rm -f /etc/apk/repositories
+
+# Download the Cloudsmith RSA key
+curl -L -o /etc/apk/keys/REPOSITORY@OWNER-FINGERPRINT.rsa.pub \
+ 'https://dl.cloudsmith.io/TOKEN/OWNER/REPOSITORY/rsa.FINGERPRINT.key'
+
+# Configure the repository
+echo "https://dl.cloudsmith.io/TOKEN/OWNER/REPOSITORY/alpine/os" \
+ > /etc/apk/repositories
+
+apk update -v --no-cache
+apk add -v --no-cache PACKAGE_NAME
```
-### Installing a package
-After you have set up the repository, to install a package you do:
+
+The automated setup script (`bash.alpine.sh`) does not support Wolfi. Use the manual setup for this distribution.
+
+
+
+### Installing a Package
+
+After setting up the repository, install a package with:
```shell
sudo apk add PACKAGE_NAME=PACKAGE_VERSION --update-cache
@@ -193,7 +223,7 @@ If you no longer want to install packages from your Cloudsmith repository, you c
$EDITOR /etc/apk/repositories
```
-Remove the `/alpine/VERSION/main` line, save then execute:
+Remove the cloudsmith repository line, save then execute:
```shell
rm -f /etc/apk/keys/REPOSITORY@cloudsmith-FINGERPRINT.rsa.pub
@@ -202,7 +232,26 @@ apk update
## Upstream Proxying / Caching
-Not Supported
+Supported
+
+The Alpine format supports upstream proxying and caching for both Alpine Linux and Wolfi repositories. When a package is requested, Cloudsmith checks for a local copy. If missing, it fetches the package from the upstream, caches it as a first-class local package, and serves it.
+
+The key difference between Alpine and Wolfi upstreams is in their URL structures — these paths only return packages for the given distribution:
+
+- **Alpine Linux** uses a versioned path structure: `/{version}/{branch}/{arch}/` (e.g., `/v3.23/main/x86_64/`)
+- **Wolfi** uses a flat structure with no version hierarchy: `/{arch}/` (e.g., `/x86_64/`)
+
+### Supported Upstream Sources
+
+| Distribution | Upstream URL | Notes |
+|:-------------|:-----------------------------------------|:---------------------------|
+| Alpine Linux | `https://dl-cdn.alpinelinux.org/alpine/` | Official Alpine CDN mirror |
+| Wolfi | `https://packages.wolfi.dev/os/` | Official Wolfi OS packages |
+
+
+### Configure an Upstream
+
+Please see our [Upstream Proxying](/repositories/upstreams#create-a-alpine-upstream) documentation for further instructions on form fields and configuration options.
## Key Signing Support
diff --git a/src/content/repositories/upstreams/images/alpine.png b/src/content/repositories/upstreams/images/alpine.png
new file mode 100644
index 00000000..ccfafd57
Binary files /dev/null and b/src/content/repositories/upstreams/images/alpine.png differ
diff --git a/src/content/repositories/upstreams/index.mdx b/src/content/repositories/upstreams/index.mdx
index 3207e350..a909433e 100644
--- a/src/content/repositories/upstreams/index.mdx
+++ b/src/content/repositories/upstreams/index.mdx
@@ -3,7 +3,7 @@ import { Note, BlockImage } from '@/components'
import quick_configure from './images/quick_configure.png'
import upstream_formats from './images/upstream_formats.png'
import edit_upstream from './images/edit_upstream.png'
-
+import alpine from './images/alpine.png'
import cargo from './images/cargo.png'
import conda from './images/conda.png'
import composer from './images/composer.png'
@@ -57,29 +57,31 @@ A good approach when determining what priority to apply to upstreams is to ensur
## Supported Formats
-|Format|Configurable Proxy
|Caching
|Indexing
|Indexing Type
|API Reference
|
-|:---|:---|:---|:---|:---|:---|
-|[Cargo (Rust)](/formats/cargo-registry) | ✅ | ✅ | ✅ |Ahead-of-Time
| [API](/api/repos/upstream/cargo/create) |
-|[Conda](/formats/conda-repository) | ✅ | ✅ | ✅ |Ahead-of-Time
| [API](/api/repos/upstream/conda/create) |
-|[Composer](/formats/composer-repository) | ✅ | ✅ | ✅ |Ahead-of-Time
| [API](/api/repos/upstream/composer/create) |
-|[CRAN](/formats/cran-repository) | ✅ | ✅ | ✅ |Ahead-of-Time
| [API](/api/repos/upstream/cran/create) |
-|[Dart](/formats/dart-repository) | ✅ | ✅ | ✅ |Ahead-of-Time
| [API](/api/repos/upstream/dart/create) |
-|[Debian](/formats/debian-repository) | ✅ | ✅ | ✅ |Ahead-of-Time
| [API](/api/repos/upstream/deb/create) |
-|[Docker](/formats/docker-registry) | ✅ | ✅ | ✅ |Just-in-Time
| [API](/api/repos/upstream/docker/create) |
-|[Generic](/formats/generic-repository) | ✅ | ✅ | ✅ |Ahead-of-Time / Just-in-Time
| [API](/api/repos/upstream/generic/create) |
-|[Golang ](/formats/go-registry) | ✅ | ✅ | ✅ |Ahead-of-Time
| [API](/api/repos/upstream/go/create) |
-|[Gradle ](/formats/gradle-repository) | ✅ | ✅ | ✅ |Just-in-Time
| [API](/api/repos/upstream/maven/create) |
-|[Helm](/formats/helm-chart-repository) | ✅ | ✅ | ✅ |Ahead-of-Time
| [API](/api/repos/upstream/helm/create) |
-|[Hex](/formats/hex-repository) | ✅ | ✅ | ✅ |Ahead-of-Time
| [API](/api/repos/upstream/hex/create) |
-|[Hugging Face](/formats/hugging-face-repository) | ✅ | ✅ | ✅ |Ahead-of-Time
| [API](/api/repos/upstream/huggingface/create) |
-|[Maven](/formats/maven-repository) | ✅ | ✅ | ✅ |Just-in-Time
| [API](/api/repos/upstream/maven/create) |
-|[npm](/formats/npm-registry) | ✅ | ✅ | ✅ |Just-in-Time
| [API](/api/repos/upstream/npm/create) |
-|[NuGet](/formats/nuget-feed) | ✅ | ✅ | ✅ |Ahead-of-Time
| [API](/api/repos/upstream/nuget/create) |
-|[Python](/formats/python-repository) | ✅ | ✅ | ✅ |Ahead-of-Time
| [API](/api/repos/upstream/python/create) |
-|[RedHat](/formats/redhat-repository) | ✅ | ✅ | ✅ |Ahead-of-Time
| [API](/api/repos/upstream/rpm/create) |
-|[Ruby](/formats/ruby-repository) | ✅ | ✅ | ✅ |Ahead-of-Time
| [API](/api/repos/upstream/ruby/create) |
-|[sbt ](/formats/sbt-repository) | ✅ | ✅ | ✅ |Just-in-Time
| [API](/api/repos/upstream/maven/create) |
-|[Swift](/formats/swift-registry) | ✅ | ✅ | ✅ |Just-in-Time
| [API](/api/repos/upstream/swift/create) |
+| Format | Configurable Proxy
| Caching
| Indexing
| Indexing Type
| API Reference
|
+| :------------------------------------------------- | :---------------------------------------------- | :----------------------------------- | :------------------------------------ | :----------------------------------------- | :------------------------------------------------------ |
+| [Alpine](/formats/alpine-repository) | ✅ | ✅ | ✅ | Ahead-of-Time
| [API](/api/repos/upstream/apk/create) |
+| [Cargo (Rust)](/formats/cargo-registry) | ✅ | ✅ | ✅ | Ahead-of-Time
| [API](/api/repos/upstream/cargo/create) |
+| [Conda](/formats/conda-repository) | ✅ | ✅ | ✅ | Ahead-of-Time
| [API](/api/repos/upstream/conda/create) |
+| [Composer](/formats/composer-repository) | ✅ | ✅ | ✅ | Ahead-of-Time
| [API](/api/repos/upstream/composer/create) |
+| [CRAN](/formats/cran-repository) | ✅ | ✅ | ✅ | Ahead-of-Time
| [API](/api/repos/upstream/cran/create) |
+| [Dart](/formats/dart-repository) | ✅ | ✅ | ✅ | Ahead-of-Time
| [API](/api/repos/upstream/dart/create) |
+| [Debian](/formats/debian-repository) | ✅ | ✅ | ✅ | Ahead-of-Time
| [API](/api/repos/upstream/deb/create) |
+| [Docker](/formats/docker-registry) | ✅ | ✅ | ✅ | Just-in-Time
| [API](/api/repos/upstream/docker/create) |
+| [Generic](/formats/generic-repository) | ✅ | ✅ | ✅ | Ahead-of-Time
| [API](/api/repos/upstream/generic/create) |
+| [Golang](/formats/go-registry) | ✅ | ✅ | ✅ | Ahead-of-Time
| [API](/api/repos/upstream/go/create) |
+| [Gradle](/formats/gradle-repository) | ✅ | ✅ | ✅ | Just-in-Time
| [API](/api/repos/upstream/maven/create) |
+| [Helm](/formats/helm-chart-repository) | ✅ | ✅ | ✅ | Ahead-of-Time
| [API](/api/repos/upstream/helm/create) |
+| [Hex](/formats/hex-repository) | ✅ | ✅ | ✅ | Ahead-of-Time
| [API](/api/repos/upstream/hex/create) |
+| [Hugging Face](/formats/hugging-face-repository) | ✅ | ✅ | ✅ | Ahead-of-Time
| [API](/api/repos/upstream/huggingface/create) |
+| [Maven](/formats/maven-repository) | ✅ | ✅ | ✅ | Just-in-Time
| [API](/api/repos/upstream/maven/create) |
+| [npm](/formats/npm-registry) | ✅ | ✅ | ✅ | Just-in-Time
| [API](/api/repos/upstream/npm/create) |
+| [NuGet](/formats/nuget-feed) | ✅ | ✅ | ✅ | Ahead-of-Time
| [API](/api/repos/upstream/nuget/create) |
+| [Python](/formats/python-repository) | ✅ | ✅ | ✅ | Ahead-of-Time
| [API](/api/repos/upstream/python/create) |
+| [RedHat](/formats/redhat-repository) | ✅ | ✅ | ✅ | Ahead-of-Time
| [API](/api/repos/upstream/rpm/create) |
+| [Ruby](/formats/ruby-repository) | ✅ | ✅ | ✅ | Ahead-of-Time
| [API](/api/repos/upstream/ruby/create) |
+| [sbt](/formats/sbt-repository) | ✅ | ✅ | ✅ | Just-in-Time
| [API](/api/repos/upstream/maven/create) |
+| [Swift](/formats/swift-registry) | ✅ | ✅ | ✅ | Just-in-Time
| [API](/api/repos/upstream/swift/create) |
+
You can can also create and manage upstreams via the [Cloudsmith API](/api).
@@ -127,6 +129,30 @@ Click the "+ Add Upstream Proxy" button, and then select the format you want to
+#### Create a Alpine Upstream
+
+
+
+
+| Form Field | Description |
+| :------------------------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| Name | A descriptive name for this upstream source. A shortened version of this name will be used for tagging cached packages retrieved from this upstream. |
+| Priority | The weighting of the Upstream source. Upstream sources are selected for resolving requests by sequential order (1..n), followed by creation date. |
+| Upstream URL | The URL for this upstream source. For Alpine Linux, use the mirror root (e.g., `https://dl-cdn.alpinelinux.org/alpine/`). For Wolfi, use `https://packages.wolfi.dev/os/`. The distribution type (Alpine or Wolfi) is automatically detected from the domain — you do not need to configure it separately. |
+| Proxy Only | Proxy requests through to upstream sources in order to match assets that are not present in this repository. |
+| Cache and Proxy | Proxy the initial request for an asset through to the upstream source and then store (cache) resolved assets in this repository for future requests. |
+| Verify SSL Certificates | If enabled, SSL certificates are verified when requests are made to this upstream. We recommend leaving this enabled for all public sources to help mitigate Man-In-The-Middle (MITM) attacks. |
+| Authentication (optional) | Optional credentials that can be provided if the upstream is not publicly accessible. |
+| Headers (optional) | Optional Key-Value headers that can be passed to upstreams with each request. |
+
+
+Cloudsmith automatically detects whether an upstream is Alpine Linux or Wolfi based on the URL domain. URLs containing `alpinelinux.org` are treated as Alpine Linux; URLs containing `wolfi.dev` are treated as Wolfi. For unrecognized domains, Alpine Linux is assumed by default.
+
+
+
+Alpine Linux and Wolfi both use the APK package format but are distinct, incompatible distributions. Do not mix Alpine and Wolfi packages in the same Cloudsmith repository — create separate repositories for each distribution.
+
+
#### Create a Cargo (Rust) Upstream
@@ -311,17 +337,19 @@ Click the "+ Add Upstream Proxy" button, and then select the format you want to
| Name | A descriptive name for this upstream source. A shortened version of this name will be used for tagging cached packages retrieved from this upstream. |
| Priority | The weighting of the Upstream source. Upstream sources are selected for resolving requests by sequential order (1..n), followed by creation date. |
| Upstream URL | The URL for this upstream source. This must be a fully qualified URL including any path elements required to reach the root of the repository. |
-| Upstream Prefix | The path prefix to prevent file collisions when using multiple upstreams. All files from this upstream will be grouped under this path (e.g., `node_distributions/`). |
+| Upstream Prefix (optional)| Optional path prefix to prevent file collisions when using multiple upstreams. All files from this upstream will be grouped under this path (e.g., `node_distributions/`). |
| Proxy Only | Proxy requests through to upstream sources in order to match assets that are not present in this repository. |
| Cache and Proxy | Proxy the initial request for an asset through to the upstream source and then store (cache) resolved assets in this repository for future requests. |
| Verify SSL Certificates | If enabled, SSL certificates are verified when requests are made to this upstream. We recommended leaving this enabled for all public sources to help mitigate Man-In-The-Middle (MITM) attacks. |
| Authentication (optional) | Optional credentials that can be provided if the upstream is not publicly accessible. |
| Headers (optional) | Optional Key-Value headers that can be passed to upstreams with each request. |
-**HTML-based upstreams**
+
Generic upstreams work with simple HTML-based sources. The upstream must consist of simple, unstyled HTML pages with no JavaScript. Each page should contain only links to package files or subdirectories. Examples include Gradle distributions, Apache releases, and Node distributions.
+
**Authentication requirements**
+
Some upstream sources require authentication to access packages or interact with their APIs. For example, GitHub package registries require token-based authentication for API access. Review the documentation for your upstream source to determine if credentials are needed and configure them accordingly in the upstream settings.