mirror of
https://github.com/jamiepine/voicebox.git
synced 2026-09-16 13:20:39 -07:00
Integrate Cloudflare R2 for CUDA binary hosting
- Update CI workflow to upload CUDA binary to R2 instead of GitHub - Use custom domain: downloads.voicebox.sh - Update release notes with R2 download link - Add R2 setup documentation with GitHub secrets instructions - Add local test script for R2 uploads - Fixes GitHub 2GB release asset limit issue Required GitHub secrets: - R2_ACCESS_KEY_ID - R2_SECRET_ACCESS_KEY - R2_ENDPOINT Cost: ~$0.04/month (free bandwidth with R2)
This commit is contained in:
@@ -177,9 +177,9 @@ jobs:
|
||||
|
||||
### NVIDIA GPU Acceleration (Windows)
|
||||
Windows users with NVIDIA GPUs can enable CUDA for 4-5x faster inference:
|
||||
1. Install the app normally (CPU version)
|
||||
2. The app will detect your GPU and offer to download CUDA support
|
||||
3. Or manually download `voicebox-server-cuda-*.exe` (~3GB) from the assets below
|
||||
1. Install the app normally (CPU version included in installer)
|
||||
2. The app will detect your GPU and offer to download CUDA support automatically
|
||||
3. Or manually download: [voicebox-server-cuda-x86_64-pc-windows-msvc.exe](https://downloads.voicebox.sh/cuda/__VERSION__/voicebox-server-cuda-x86_64-pc-windows-msvc.exe) (~2.4GB)
|
||||
|
||||
The app includes automatic updates - future updates will be installed automatically.
|
||||
releaseDraft: true
|
||||
@@ -187,11 +187,26 @@ jobs:
|
||||
args: ${{ matrix.args }}
|
||||
includeUpdaterJson: true
|
||||
|
||||
- name: Upload CUDA server binary (Windows only)
|
||||
- name: Upload CUDA server to Cloudflare R2 (Windows only)
|
||||
if: matrix.platform == 'windows-latest'
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
files: backend/cuda-release/voicebox-server-cuda-*.exe
|
||||
draft: true
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
|
||||
R2_ENDPOINT: ${{ secrets.R2_ENDPOINT }}
|
||||
run: |
|
||||
# Install AWS CLI if not available
|
||||
pip install awscli
|
||||
|
||||
# Get version from tag
|
||||
VERSION=${GITHUB_REF#refs/tags/}
|
||||
|
||||
# Get platform tuple
|
||||
PLATFORM=$(rustc --print host-tuple)
|
||||
|
||||
# Upload to R2
|
||||
aws s3 cp backend/cuda-release/voicebox-server-cuda-${PLATFORM}.exe \
|
||||
s3://voicebox-releases/cuda/${VERSION}/voicebox-server-cuda-${PLATFORM}.exe \
|
||||
--endpoint-url $R2_ENDPOINT \
|
||||
--acl public-read
|
||||
|
||||
echo "CUDA binary uploaded to: https://downloads.voicebox.sh/cuda/${VERSION}/voicebox-server-cuda-${PLATFORM}.exe"
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
#!/bin/bash
|
||||
# Test R2 upload locally before running in CI
|
||||
|
||||
set -e
|
||||
|
||||
echo "============================================================"
|
||||
echo "Cloudflare R2 Upload Test"
|
||||
echo "============================================================"
|
||||
|
||||
# Check for required environment variables
|
||||
if [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] || [ -z "$R2_ENDPOINT" ]; then
|
||||
echo "ERROR: Missing required environment variables"
|
||||
echo ""
|
||||
echo "Please set:"
|
||||
echo " export AWS_ACCESS_KEY_ID='your-r2-access-key-id'"
|
||||
echo " export AWS_SECRET_ACCESS_KEY='your-r2-secret-access-key'"
|
||||
echo " export R2_ENDPOINT='https://your-account-id.r2.cloudflarestorage.com'"
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check for AWS CLI
|
||||
if ! command -v aws &> /dev/null; then
|
||||
echo "Installing AWS CLI..."
|
||||
pip install awscli
|
||||
fi
|
||||
|
||||
# Find CUDA binary
|
||||
CUDA_BINARY=$(ls dist/voicebox-server-cuda*.exe 2>/dev/null | head -1)
|
||||
|
||||
if [ -z "$CUDA_BINARY" ]; then
|
||||
echo "ERROR: CUDA binary not found in dist/"
|
||||
echo "Run: bash build_cuda.bat"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Found CUDA binary: $CUDA_BINARY"
|
||||
echo "Size: $(du -h "$CUDA_BINARY" | cut -f1)"
|
||||
echo ""
|
||||
|
||||
# Test version
|
||||
VERSION="v0.1.12-test"
|
||||
PLATFORM="x86_64-pc-windows-msvc"
|
||||
FILENAME="voicebox-server-cuda-${PLATFORM}.exe"
|
||||
|
||||
echo "Test upload configuration:"
|
||||
echo " Version: $VERSION"
|
||||
echo " Platform: $PLATFORM"
|
||||
echo " Endpoint: $R2_ENDPOINT"
|
||||
echo " Bucket: voicebox-releases"
|
||||
echo " Path: cuda/$VERSION/$FILENAME"
|
||||
echo ""
|
||||
|
||||
read -p "Proceed with upload? (y/n) " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo "Aborted."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Uploading to R2..."
|
||||
|
||||
aws s3 cp "$CUDA_BINARY" \
|
||||
"s3://voicebox-releases/cuda/${VERSION}/${FILENAME}" \
|
||||
--endpoint-url "$R2_ENDPOINT" \
|
||||
--acl public-read
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo ""
|
||||
echo "============================================================"
|
||||
echo "Upload successful!"
|
||||
echo "============================================================"
|
||||
echo ""
|
||||
echo "Download URL:"
|
||||
echo "https://downloads.voicebox.sh/cuda/${VERSION}/${FILENAME}"
|
||||
echo ""
|
||||
echo "Test with:"
|
||||
echo "curl -I https://downloads.voicebox.sh/cuda/${VERSION}/${FILENAME}"
|
||||
echo ""
|
||||
else
|
||||
echo ""
|
||||
echo "Upload failed!"
|
||||
exit 1
|
||||
fi
|
||||
@@ -0,0 +1,274 @@
|
||||
# Cloudflare R2 Setup Guide
|
||||
|
||||
## Overview
|
||||
|
||||
The CUDA binary (2.4GB) is hosted on Cloudflare R2 at `downloads.voicebox.sh` instead of GitHub Releases (which has a 2GB limit).
|
||||
|
||||
## R2 Bucket Configuration
|
||||
|
||||
✅ **Completed:**
|
||||
- Bucket created: `voicebox-releases`
|
||||
- Custom domain configured: `downloads.voicebox.sh`
|
||||
|
||||
## GitHub Secrets Required
|
||||
|
||||
Add these secrets to your GitHub repository:
|
||||
|
||||
### 1. R2_ACCESS_KEY_ID
|
||||
|
||||
Your Cloudflare R2 API Access Key ID
|
||||
|
||||
**How to get it:**
|
||||
1. Go to Cloudflare Dashboard → R2
|
||||
2. Click "Manage R2 API Tokens"
|
||||
3. Create API Token with "Object Read & Write" permissions
|
||||
4. Copy the "Access Key ID"
|
||||
|
||||
**Add to GitHub:**
|
||||
```
|
||||
Repository Settings → Secrets and variables → Actions → New repository secret
|
||||
Name: R2_ACCESS_KEY_ID
|
||||
Value: <your-access-key-id>
|
||||
```
|
||||
|
||||
### 2. R2_SECRET_ACCESS_KEY
|
||||
|
||||
Your Cloudflare R2 Secret Access Key
|
||||
|
||||
**How to get it:**
|
||||
- Same process as above
|
||||
- Copy the "Secret Access Key" (shown only once!)
|
||||
- Store it securely
|
||||
|
||||
**Add to GitHub:**
|
||||
```
|
||||
Name: R2_SECRET_ACCESS_KEY
|
||||
Value: <your-secret-access-key>
|
||||
```
|
||||
|
||||
### 3. R2_ENDPOINT
|
||||
|
||||
Your Cloudflare R2 endpoint URL
|
||||
|
||||
**Format:**
|
||||
```
|
||||
https://<account-id>.r2.cloudflarestorage.com
|
||||
```
|
||||
|
||||
**How to find your account ID:**
|
||||
- Cloudflare Dashboard → R2
|
||||
- Look at the URL or bucket settings
|
||||
- Should be a string of letters/numbers
|
||||
|
||||
**Add to GitHub:**
|
||||
```
|
||||
Name: R2_ENDPOINT
|
||||
Value: https://<your-account-id>.r2.cloudflarestorage.com
|
||||
```
|
||||
|
||||
## Bucket Structure
|
||||
|
||||
After CI uploads, the bucket will have this structure:
|
||||
|
||||
```
|
||||
voicebox-releases/
|
||||
└── cuda/
|
||||
├── v0.1.12/
|
||||
│ └── voicebox-server-cuda-x86_64-pc-windows-msvc.exe
|
||||
├── v0.1.13/
|
||||
│ └── voicebox-server-cuda-x86_64-pc-windows-msvc.exe
|
||||
└── v0.2.0/
|
||||
└── voicebox-server-cuda-x86_64-pc-windows-msvc.exe
|
||||
```
|
||||
|
||||
## Public Access
|
||||
|
||||
Files are uploaded with `--acl public-read`, making them accessible at:
|
||||
|
||||
```
|
||||
https://downloads.voicebox.sh/cuda/v{VERSION}/voicebox-server-cuda-x86_64-pc-windows-msvc.exe
|
||||
```
|
||||
|
||||
**Example:**
|
||||
```
|
||||
https://downloads.voicebox.sh/cuda/v0.1.12/voicebox-server-cuda-x86_64-pc-windows-msvc.exe
|
||||
```
|
||||
|
||||
## Testing the Setup
|
||||
|
||||
### Local Test Upload
|
||||
|
||||
Before running the CI, test uploading locally:
|
||||
|
||||
```bash
|
||||
# Set environment variables
|
||||
export AWS_ACCESS_KEY_ID="your-r2-access-key-id"
|
||||
export AWS_SECRET_ACCESS_KEY="your-r2-secret-access-key"
|
||||
export R2_ENDPOINT="https://your-account-id.r2.cloudflarestorage.com"
|
||||
|
||||
# Install AWS CLI
|
||||
pip install awscli
|
||||
|
||||
# Test upload (use a small test file first)
|
||||
echo "test" > test.txt
|
||||
aws s3 cp test.txt \
|
||||
s3://voicebox-releases/test/test.txt \
|
||||
--endpoint-url $R2_ENDPOINT \
|
||||
--acl public-read
|
||||
|
||||
# Verify it's accessible
|
||||
curl https://downloads.voicebox.sh/test/test.txt
|
||||
|
||||
# If successful, try the actual CUDA binary
|
||||
aws s3 cp backend/dist/voicebox-server-cuda.exe \
|
||||
s3://voicebox-releases/cuda/v0.1.12-test/voicebox-server-cuda-x86_64-pc-windows-msvc.exe \
|
||||
--endpoint-url $R2_ENDPOINT \
|
||||
--acl public-read
|
||||
```
|
||||
|
||||
### Verify Upload
|
||||
|
||||
Check if the file is accessible:
|
||||
|
||||
```bash
|
||||
curl -I https://downloads.voicebox.sh/cuda/v0.1.12-test/voicebox-server-cuda-x86_64-pc-windows-msvc.exe
|
||||
```
|
||||
|
||||
Should return:
|
||||
```
|
||||
HTTP/2 200
|
||||
content-length: 2545086396
|
||||
content-type: application/x-msdownload
|
||||
...
|
||||
```
|
||||
|
||||
## CI Workflow
|
||||
|
||||
The workflow now:
|
||||
|
||||
1. **Builds CPU binary** → Includes in installer
|
||||
2. **Builds CUDA binary** → Uploads to R2
|
||||
3. **Release notes** → Include R2 download link
|
||||
|
||||
### CI Steps (Windows)
|
||||
|
||||
```yaml
|
||||
- name: Build CUDA Python server (Windows only)
|
||||
# Builds the CUDA binary
|
||||
|
||||
- name: Upload CUDA server to Cloudflare R2 (Windows only)
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
|
||||
R2_ENDPOINT: ${{ secrets.R2_ENDPOINT }}
|
||||
run: |
|
||||
aws s3 cp backend/cuda-release/voicebox-server-cuda-*.exe \
|
||||
s3://voicebox-releases/cuda/${VERSION}/... \
|
||||
--endpoint-url $R2_ENDPOINT \
|
||||
--acl public-read
|
||||
```
|
||||
|
||||
## Cost Tracking
|
||||
|
||||
Monitor your R2 usage:
|
||||
|
||||
**Cloudflare Dashboard → R2 → voicebox-releases → Metrics**
|
||||
|
||||
Expected costs (per month):
|
||||
- Storage: 2.4GB × $0.015/GB = **$0.036**
|
||||
- Egress: **$0.00** (free!)
|
||||
- Class A ops: ~100 × $4.50/million = **$0.00**
|
||||
|
||||
**Total: ~$0.04/month** (essentially free!)
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Upload fails: "Access Denied"
|
||||
|
||||
**Solution:** Check API token permissions
|
||||
- Must have "Object Read & Write" on the bucket
|
||||
- Regenerate token if needed
|
||||
|
||||
### File not accessible at downloads.voicebox.sh
|
||||
|
||||
**Solution:** Check custom domain configuration
|
||||
- R2 Dashboard → Bucket → Settings → Custom Domains
|
||||
- Ensure `downloads.voicebox.sh` is properly configured
|
||||
- DNS may take time to propagate
|
||||
|
||||
### "endpoint-url" not recognized
|
||||
|
||||
**Solution:** Make sure AWS CLI is updated
|
||||
```bash
|
||||
pip install --upgrade awscli
|
||||
```
|
||||
|
||||
### File uploaded but wrong permissions
|
||||
|
||||
**Solution:** Re-upload with `--acl public-read`
|
||||
```bash
|
||||
aws s3 cp ... --acl public-read
|
||||
```
|
||||
|
||||
Or set bucket default permissions in R2 Dashboard.
|
||||
|
||||
## Security Notes
|
||||
|
||||
### API Token Permissions
|
||||
|
||||
✅ **Recommended:**
|
||||
- Object Read & Write only
|
||||
- No admin permissions needed
|
||||
- Scoped to `voicebox-releases` bucket only
|
||||
|
||||
❌ **Avoid:**
|
||||
- Account-wide permissions
|
||||
- Account admin access
|
||||
- Worker edit permissions
|
||||
|
||||
### Secret Rotation
|
||||
|
||||
Rotate API tokens every 6-12 months:
|
||||
1. Create new API token
|
||||
2. Update GitHub secrets
|
||||
3. Verify CI still works
|
||||
4. Delete old token
|
||||
|
||||
## Maintenance
|
||||
|
||||
### Cleaning Old Versions
|
||||
|
||||
Optional: Delete old CUDA binaries to save storage costs
|
||||
|
||||
```bash
|
||||
# List all versions
|
||||
aws s3 ls s3://voicebox-releases/cuda/ \
|
||||
--endpoint-url $R2_ENDPOINT
|
||||
|
||||
# Delete old version
|
||||
aws s3 rm s3://voicebox-releases/cuda/v0.1.0/ \
|
||||
--recursive \
|
||||
--endpoint-url $R2_ENDPOINT
|
||||
```
|
||||
|
||||
### Monitoring
|
||||
|
||||
Set up Cloudflare notifications:
|
||||
- Storage approaching limits
|
||||
- Unusual traffic patterns
|
||||
- High operation counts
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. ✅ Bucket configured
|
||||
2. ⏳ Add GitHub secrets (R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY, R2_ENDPOINT)
|
||||
3. ⏳ Test local upload
|
||||
4. ⏳ Push branch and create test release
|
||||
5. ⏳ Verify CUDA binary accessible from downloads.voicebox.sh
|
||||
6. ⏳ Implement frontend download manager
|
||||
|
||||
---
|
||||
|
||||
**Status**: Ready for testing
|
||||
**Cost**: ~$0.04/month
|
||||
**Bandwidth**: Free (unlimited)
|
||||
Reference in New Issue
Block a user