Package Repositories Without a Server

Cloudflare Tunnel relies on cloudflared, a lightweight daemon that connects private networks and services through Cloudflare's global network without exposing public IPs. Because cloudflared must run anywhere—from Raspberry Pis to data center servers—it has to be distributed through standard system package managers. The apt and yum repositories behind pkg.cloudflare.com are themselves hosted on Cloudflare R2, with no dedicated server required. The same approach works for any binary or distributable.

What an apt Repository Actually Is

When a user runs apt-get install cloudflared, the package manager performs a series of lookups against a structured file system of plaintext metadata files. Given an apt source pointing at pkg.cloudflare.com/cloudflared, the process unfolds as follows:

  1. apt fetches a Release file from the dists/buster directory. That file lists supported architectures along with their md5, sha1 and sha256 checksums.
  2. Based on the system's architecture (for example, amd64), apt fetches a Packages file. That file contains metadata about the binary, including its filename and checksum.
  3. apt downloads the actual .deb file from the path given in the Filename field and runs dpkg on it.

Yum repositories follow the same conceptual model: a structured file system of metadata and package files. In both cases, the "repository" is something you can construct by hand.

Building the Repository from a Binary

Create the Package File

The fpm tool builds both .deb and .rpm files from a single command, making it a practical choice for cross-distribution packaging. Given a compiled cloudflared binary, fpm produces a Debian package containing both the installable binary and its metadata.

Signing the packages is optional but recommended for secure distribution.

$ fpm -s <dir> -t deb -C /path/to/project -name <project_name> –version <version>

Generate the Metadata Files

Several tools generate the plaintext metadata files apt expects. Cloudflare uses reprepro:

$ reprepro buster includedeb <path/to/the/deb>

reprepro creates the nested directory structure that mirrors what apt expects to find.

Host the Files on R2

Once the repository structure exists, uploading it to Cloudflare R2 makes the package files available over HTTP. The object storage bucket simply mirrors the hierarchy reprepro generated. A copyable example of the script Cloudflare uses is available in the cloudflared repository.

Serve with a Worker

For fine-grained control over how clients interact with the bucket, a lightweight Cloudflare Worker acts as the front-end API. An apt repository only requires GET requests, so the worker can be minimal. A demo worker example is available in the Cloudflare documentation.

A Scripted Release Pipeline

The release packaging script in the cloudflared repository ties the whole process together: it builds packages, signs them, publishes the public key, and uploads the resulting repository structure to R2. That script runs as part of the release process, and the live repositories at pkg.cloudflare.com are the result.

Hosting an apt/yum repository on R2 eliminates the need to maintain a dedicated package server. Downloads incur no egress fees, and serving through Cloudflare's global network absorbs high request volumes without additional infrastructure.