English
Using R2 to Build a Private Software Mirror Site: From Path Planning to File Upload

Background and Requirements
In daily development and operations work, we often need to distribute various large software packages, ISO images, or internal team artifacts. Whether for cross-team collaboration, multi-location offices, or providing a stable dependency source for CI/CD pipelines, a Standardized, fast, and stable the internal download sites are all crucial.
Directly using official sources or public cloud drives often faces the following problems:
❌Slow speed Official sources are abroad, so downloading large files takes a long time.
❌Version chaos Different versions of the same software are scattered everywhere, making them difficult to trace.
❌Link expired: Cloud drive link expired; official old version has been taken down.
❌No verification: Missing integrity verification file, making download corruption hard to detect
This article uses the VMware ESXi 8.0 ISO as an example., demonstrating how to use Cloudflare R2 + rclone to build a standardized, scalable private mirror site. This approach is also applicable to any software distribution scenario, such as Ubuntu ISOs, JDK installation packages, Docker image backups, etc.
Why choose Cloudflare R2?
No outbound traffic charges: This is the biggest advantage of R2 over AWS S3, especially for distributing large files.
S3-compatible API: can be used
rclone,awsclimanagement of mature tools, etc.Built-in CDN acceleration After binding a custom domain, global access speed is guaranteed.
Objective of this paper: Provide standardized, stable, and verifiable software download sources for internal team or public users, and record the complete path planning rationale and operational steps.
Directory Structure Design (Core Experience)
Final directory tree
dl.fishfinal.com
└── vmware/
└── esxi/
└── 8.0/
├── VMware-VMvisor-Installer-8.0U3e-24677879.x86_64.iso
└── VMware-VMvisor-Installer-8.0U3e-24677879.x86_64.iso.sha256The corresponding R2 bucket path is:
cloudflare-r2:fishfinal-dl/vmware/esxi/8.0/Interpretation of Design Principles
| Hierarchy | Example | Design rationale |
|---|---|---|
| Domain name | dl.fishfinal.com | dl. Semantic subdomain naming that clearly indicates Download, separate from the main site's business. |
| Manufacturer | vmware/ | Tier 1 category, facilitating future expansion to other vendors (e.g.,centos/,microsoft/) |
| Product | esxi/ | The same vendor may have multiple product lines (vCenter, NSX, Workstation); isolate them in advance. |
| Major version | 8.0/ | ESXi major version number; minor version (U3e) goes in the filename, keeping the directory clean. |
| File naming | VMware-VMvisor-Installer-8.0U3e-... | Retain the official full filename, including the minor version and Build Number, for easy manual identification. |
Why not repeat the version number in the path?
Initially considered /vmware/8.0/ structure, but there are two problems:
Poor scalability: If VMware Tools or patch packages need to be stored in the future, there will be no place to categorize them.
Data redundancy: The file name already contains
8.0U3e, write it again in the path8.0It will cause trouble during script processing.
The final plan is at Script-friendly and human-readable achieved a balance between
Practical operation steps
Preparations
1. R2 bucket creation and domain binding
In the Cloudflare Dashboard:
Create an R2 bucket (e.g., named
fishfinal-dl)Bind a custom domain in "R2 → Bucket → Settings".
dl.fishfinal.comConfigure the storage bucket as "Public Access" (if public download is required).
2. rclone Installation and Configuration
bash
# macOS / Linux installation
brew install rclone # macOS
sudo apt install rclone # Ubuntu/Debian
# Configure R2
rclone configrclone config For interactive configuration, refer to R2 Official Documentation, the key configuration items are:
Type:
s3Provider:
CloudflareAccess Key ID / Secret Access Key: Generated on the R2 management page
Endpoint:
https://<account-id>.r2.cloudflarestorage.com
File upload
Use rclone copy Command to upload the ISO file to the target path:
bash
rclone copy VMware-VMvisor-Installer-8.0U3e-24677879.x86_64.iso \
cloudflare-r2:fishfinal-dl/vmware/esxi/8.0 --progressParameter Description:
copy: Copy file (overwrite if the target already exists, andsyncbehavior is different)--progressDisplay real-time transfer progress
Example output during the upload process:
Transferred: 1.2 GiB / 1.2 GiB, 100%, 45 MiB/s, ETA 0s
Transferred: 1 / 1, 100%
Elapsed time: 27.3sGenerate checksum file
To ensure that downloaders can verify file integrity, it is necessary to generate .sha256 Verify the file.
Linux terminal:
bash
sha256sum VMware-VMvisor-Installer-8.0U3e-24677879.x86_64.iso > \
VMware-VMvisor-Installer-8.0U3e-24677879.x86_64.iso.sha256macOS Terminal:
bash
shasum -a 256 VMware-VMvisor-Installer-8.0U3e-24677879.x86_64.iso > \
VMware-VMvisor-Installer-8.0U3e-24677879.x86_64.iso.sha256Windows PowerShell:
powershell
(Get-FileHash -Path "VMware-VMvisor-Installer-8.0U3e-24677879.x86_64.iso" -Algorithm SHA256).Hash + " VMware-VMvisor-Installer-8.0U3e-24677879.x86_64.iso" | Out-File -FilePath "VMware-VMvisor-Installer-8.0U3e-24677879.x86_64.iso.sha256"After generation .sha256 File content example:
a1b2c3d4e5f6... (64-bit hash value) VMware-VMvisor-Installer-8.0U3e-24677879.x86_64.isoUpload the verification file and verify public access.
Upload the verification file to the same directory:
bash
rclone copy VMware-VMvisor-Installer-8.0U3e-24677879.x86_64.iso.sha256 \
cloudflare-r2:fishfinal-dl/vmware/esxi/8.0 --progressOutput example (file is very small, transfer is fast):
Transferred: 118 B / 118 B, 100%, 58 B/s, ETA 0s
Transferred: 1 / 1, 100%
Elapsed time: 2.0sPublic network access test: Open the verification file link in a browser and confirm that the content can be read normally:
https://dl.fishfinal.com/vmware/esxi/8.0/VMware-VMvisor-Installer-8.0U3e-24677879.x86_64.iso.sha256Verification method for downloaders:
bash
# Download verification file
wget https://dl.fishfinal.com/vmware/esxi/8.0/VMware-VMvisor-Installer-8.0U3e-24677879.x86_64.iso.sha256
# Verify ISO integrity (output "OK" means the file is intact)
sha256sum -c VMware-VMvisor-Installer-8.0U3e-24677879.x86_64.iso.sha256Pitfalls and Optimization
The iterative process of path planning
| version | Path example | Question |
|---|---|---|
| v1 (first edition) | /vmware/8.0/ | Lacks a product layer (ESXi/vCenter) and has poor scalability; version numbers are duplicated in paths and file names. |
| v2 (Final Version) | /vmware/esxi/8.0/ | Introduce a product layer, clear naming, script-friendly |
Reflection: in the domain name dl Although the semantics are clear, this limits the possibility of storing non-download data in this bucket in the future. If backup needs arise later, it is recommended to create a separate bucket rather than mixing them.
R2 Usage Precautions
Public access permission: In the R2 console, explicitly set the bucket to "Public" or "Private" to avoid accidentally exposing sensitive data.
Request fee: Although R2 waives egress traffic fees, but Class B operations (read requests) It is a paid service. If files are downloaded heavily, it is recommended to set up usage alerts in the Cloudflare dashboard.
Anti-hotlinking: To prevent others from misusing the link, you can configure it in Cloudflare Referer whitelist or use Signed URL with expiration
Large file upload optimization: For very large files (>10GB), you can
rclone copyadd in--multi-thread-streams 8Parameter enables multithreaded upload
Automation script example
If you need to frequently upload ISO files and generate checksum files, you can use the following script:
bash
#!/bin/bash
# upload-iso.sh - One-click upload ISO and generate checksum file
ISO_FILE="$1"
R2_PATH="cloudflare-r2:fishfinal-dl/vmware/esxi/8.0/"
if [ -z "$ISO_FILE" ]; then
echo "Usage: $0 <ISO filename>"
exit 1
fi
# Generate checksum file
sha256sum "$ISO_FILE" > "${ISO_FILE}.sha256"
# Upload ISO
rclone copy "$ISO_FILE" "$R2_PATH" --progress
# Upload verification file
rclone copy "${ISO_FILE}.sha256" "$R2_PATH" --progress
echo "Upload complete!"
echo "ISO: https://dl.fishfinal.com/vmware/esxi/8.0/$ISO_FILE"
echo "校验文件: https://dl.fishfinal.com/vmware/esxi/8.0/${ISO_FILE}.sha256"Summary and Extension
Current results
Through the operations in this article, we have completed a A standardized, scalable prototype of a VMware mirror site:
✅ Clear directory structure (vendor → product → major version → file)
✅ Complete file verification (ISO + accompanying .sha256)
✅ Publicly accessible download link (via Cloudflare R2 + custom domain)
Future plans
Multi-product support: Add products such as vCenter, NSX, Workstation, etc. following the same structure.
Automated synchronization: Use GitHub Actions to periodically check for official new versions and automatically upload
Index page construction: at
/vmware/esxi/8.0/Generate belowindex.htmlList all available filesMonitoring and Alerting: Configure R2 usage monitoring to avoid unexpected overages
Inspiration for readers
The same methodology can be applied to any software distribution scenario:
Linux distribution ISO (such as Ubuntu, CentOS, Debian)
Development tool installation packages (such as JDK, Python, Node.js)
Container image backup (e.g., Docker image export file)
Team-internal artifacts (such as build outputs, test data)
Reference resources
Changelog: This article's operations are based on Cloudflare R2 (August 2026) and rclone v1.65. If there are any changes, please refer to the official documentation.