Skip to Content

Offload Media Manual Upload

🎯 Goal: Upload the contents of uploads/ into the correct object prefix in your bucket (as set by AS3CF_OBJECT_PREFIX), without nesting the uploads directory itself.

  1. Launch Cyberduck and Connect to R2
  • Open Cyberduck.

  • Click Open Connection.

  • Choose Amazon S3.

  • Enter:

    • Server: https://<your-account>.r2.cloudflarestorage.com
    • Access Key ID / Secret Access Key: From your Cloudflare R2 settings
    • Path: Leave blank or use the bucket name depending on Cyberduck’s setup

⚠️ If using a custom endpoint or Cloudflare’s compatibility mode, configure Cyberduck for S3 (Custom) and set the correct endpoint.

  1. Navigate to the Bucket and Object Prefix Path

    Once connected:

    • Open your bucket.
    • Navigate to the folder path that matches your AS3CF_OBJECT_PREFIX, e.g.:
    object-prefix/

    This is where WordPress expects media to be stored in object storage.

    You can find this prefix in your .env file:

    AS3CF_OBJECT_PREFIX=object-prefix/
  2. Upload Files (⚠️ Not the uploads Folder)

    • On your local machine, open the “ folder.
    • Select all its contents (year-based folders like 2023/, 2024/, etc. and any other files).
    • Drag & drop those contents directly into the object-prefix/ folder in Cyberduck.

    DO NOT drag the entire uploads folder — this would nest everything incorrectly like:

    object-prefix/uploads/2024/...

    Which breaks media URL resolution.

  3. Confirm Upload

    • Use Cyberduck’s remote browser to verify folder structure inside your bucket:
    object-prefix/2023/ object-prefix/2024/ etc.
    • Confirm that uploaded files match what’s in your local /uploads folder.
  4. Add entries to wp_as3cf_items table

    Within your project directory, make a temporary file and copy snippet below (offload.sql). Do not commit this file

    • Replace <region> with s3 bucket region.
    • Replace <bucket> with s3 bucket name.
    • Replace all <project_slug> with your project slug.

    Import using wp cli:

    terminal
    wp db import offload.sql

    Check wp_as3cf_items table entries to have the correct paths.

    offload.sql
    INSERT IGNORE INTO wp_as3cf_items ( provider, region, bucket, path, original_path, is_private, source_type, source_id, source_path, original_source_path, extra_info, originator, is_verified ) SELECT 'aws', '<region>', '<bucket>', concat('<project_slug>/', pm.meta_value) AS path, concat('<project_slug>/', pm.meta_value) AS original_path, 0, 'media-library', p.id AS source_id, pm.meta_value AS source_path, pm.meta_value AS original_source_path, 'a:2:{s:13:"private_sizes";a:0:{}s:14:"private_prefix";s:0:"";}', 0, 1 FROM `wp_posts` p LEFT JOIN `wp_postmeta` pm ON pm.post_id = p.id AND pm.meta_key = '_wp_attached_file' WHERE p.post_type = 'attachment';
Last updated on