1. Home
  2. Blog
  3. Blog Details

How to Upload Media Files to Cloudflare R2 Using Laravel or Node.js

  • Cloud Atlus
  • 0 Comments

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

  • Category: Laravel (PHP)
Cloud Atlus

Cloud Atlus

Tech writer at Cloud Atlus, breaking down cloud computing, DevOps, and infrastructure. Turning complex concepts into clear guides. Passionate about AWS, Docker, and open-source innovation.

0 Comments

Post Comment