How to Upload Media Files to Cloudflare R2 Using Laravel or Node.js
This document provides step-by-step instructions for uploading files to Cloudflare R2 storage from both Laravel (PHP) and Node.js applications.
Prerequisites
1. Cloudflare R2 bucket created
2. API credentials (Access Key ID and Secret Access Key)
3. Endpoint URL for your R2 bucket
4. Either:
- Laravel application (PHP) with Composer
- Node.js application with npm/yarn
Environment Variables
You'll need these environment variables configured in your application:
CLOUDFLARE_R2_ACCESS_KEY_ID=your_access_key_id CLOUDFLARE_R2_SECRET_ACCESS_KEY=your_secret_access_key CLOUDFLARE_R2_BUCKET=your_bucket_name CLOUDFLARE_R2_ENDPOINT=your_endpoint_url CLOUDFLARE_R2_URL=your_public_url
Laravel (PHP) Implementation
1. Install Required Packages
bash
composer require league/flysystem-aws-s3-v3
2. Configure Filesystem
Add this to your `config/filesystems.php`:
'r2' => [
'driver' => 's3',
'key' => env('CLOUDFLARE_R2_ACCESS_KEY_ID'),
'secret' => env('CLOUDFLARE_R2_SECRET_ACCESS_KEY'),
'region' => 'auto',
'bucket' => env('CLOUDFLARE_R2_BUCKET'),
'url' => env('CLOUDFLARE_R2_URL'),
'endpoint' => env('CLOUDFLARE_R2_ENDPOINT'),
'use_path_style_endpoint' => true,
],
3. Uploading Files in Laravel
Here's how to upload files in your controller: (PHP)
use Illuminate\Support\Facades\Storage;
public function uploadFile(Request $request)
{
$request->validate([
'file' => 'required|file',
]);
$path = $request->file('file')->store(
'uploads', // folder in R2 bucket
'r2' // filesystem disk
);
$url = Storage::disk('r2')->url($path);
return response()->json([
'path' => $path,
'url' => $url,
]);
}
4. Retrieving Files (PHP)
$url = Storage::disk('r2')->url('path/to/file.jpg');
$file = Storage::disk('r2')->get('path/to/file.jpg');
Node.js Implementation
1. Install Required Packages
npm install @aws-sdk/client-s3 @aws-sdk/s3-request-presigner
2. Configure S3 Client
Create a file "r2-client.js": JS File
const { S3Client } = require('@aws-sdk/client-s3');
const s3Client = new S3Client({
region: 'auto',
endpoint: process.env.CLOUDFLARE_R2_ENDPOINT,
credentials: {
accessKeyId: process.env.CLOUDFLARE_R2_ACCESS_KEY_ID,
secretAccessKey: process.env.CLOUDFLARE_R2_SECRET_ACCESS_KEY,
},
});
module.exports = s3Client;
3. Uploading Files in Node.js
Create a file upload handler: JS File
const { PutObjectCommand } = require('@aws-sdk/client-s3');
const s3Client = require('./r2-client');
const { getSignedUrl } = require('@aws-sdk/s3-request-presigner');
async function uploadFile(file) {
const params = {
Bucket: process.env.CLOUDFLARE_R2_BUCKET,
Key: `uploads/${Date.now()}_${file.originalname}`,
Body: file.buffer,
ContentType: file.mimetype,
};
try {
const command = new PutObjectCommand(params);
await s3Client.send(command);
const url = `${process.env.CLOUDFLARE_R2_URL}/${params.Key}`;
return { path: params.Key, url };
} catch (err) {
console.error('Error uploading file:', err);
throw err;
}
}
// Example usage in Express route
app.post('/upload', async (req, res) => {
if (!req.files || !req.files.file) {
return res.status(400).json({ error: 'No file uploaded' });
}
try {
const result = await uploadFile(req.files.file);
res.json(result);
} catch (err) {
res.status(500).json({ error: 'File upload failed' });
}
});
4. Generating Presigned URLs (Node.js)
For temporary access to private files: JS File
const { GetObjectCommand } = require('@aws-sdk/client-s3');
async function generatePresignedUrl(fileKey, expiresIn = 3600) {
const command = new GetObjectCommand({
Bucket: process.env.CLOUDFLARE_R2_BUCKET,
Key: fileKey,
});
return await getSignedUrl(s3Client, command, { expiresIn });
}
Best Practices
1. Security:
- Never expose your secret access key in client-side code
- Please always use env variables for your credentials
- Implement proper file validation (size, type, etc.)
2. Performance:
- For large files, consider multipart uploads
- Use CDN caching for frequently accessed files
3. Organization:
- Use meaningful folder structures in your bucket
- Implement naming conventions for uploaded files
4. Error Handling:
- Implement proper error handling for upload failures
- Log errors for debugging
Troubleshooting
1. Access Denied Errors:
- Verify your credentials are correct
- Check bucket permissions in Cloudflare dashboard
2. Connection Issues:
- Verify your endpoint URL is correct
- Check network connectivity to Cloudflare
3. File Upload Failures:
- Check file size limits (both client and server side)
- Verify MIME types are correctly set
4. URL Generation Issues:
- Ensure the bucket is configured for public access if needed
0 Comments