The Ultimate Guide To Trellis (Bedrock + Backups + CDN + Sendgrid + CSP + Sync Scripts + WP-CLI Aliases)

Amazon S3 WP Uploads Hosting + Amazon Cloudfront CDN

Hosting media is one of the best wordpress hosting sites on Amazon S3 and using the Amazon Cloudfront CDN for serving the media is one of the most amazing tools in my workflow. For example, I’m developing locally, but all my media is being uploaded to Amazon S3, so when I launch my staging or production site, I don’t have to migrate any uploads. How great is it to forget about have to sync media?!

For this functionality, I use the S3 Uploads plugin for WordPress.

Creating Amazon IAM User & Getting Access Keys

Coming soon…

Installing S3 Uploads with Composer

Since I use a composer based WP framework such as Bedrock, I add this plugin to my composer.json.

"repositories": [
      "type": "package",
      "package": {
        "name": "humanmade/s3-uploads",
        "version": "master",
        "type": "wordpress-plugin",
        "source": {
          "type": "git",
          "url": "",
          "reference": "master"
    "require": {
        "humanmade/s3-uploads": "v2.0.0-beta3"

Configuring S3 Uploads Plugin

Add the below to your wp-config.php file or config/application.php for Bedrock. If you’re not using a .env file place the env() variables directly here.

 * AWS S3 & Cloudfront Settings
define('S3_UPLOADS_REGION', 'eu-central-1');
define('S3_UPLOADS_BUCKET_URL', '');

Add the below to your development wp-config.php or config/environments/development.php for Bedrock.

/** Use local s3 folder */
define('S3_UPLOADS_USE_LOCAL', true);
/** Disable S3 URL overwrites */
define( 'S3_UPLOADS_AUTOENABLE', false );

Add the below to your production wp-config.php or config/environments/production.php for Bedrock. This add the HTTP Expires and HTTP Cache Control headers.

/** Cache control */
define( 'S3_UPLOADS_HTTP_CACHE_CONTROL', 30 * 24 * 60 * 60 );
/** Expires header */
define( 'S3_UPLOADS_HTTP_EXPIRES', gmdate( 'D, d M Y H:i:s', time() + (30 * 24 * 60 * 60) ) .' GMT' );

Add this to your .env (match format of what’s already there) or trellis/group_vars/production/vault.yml

## backups
aws_s3_bucket_name: bucket.url
aws_s3_bucket_access_key: access.key
aws_s3_bucket_secret_key: secret.key

Verifying Setup

Coming soon…

wp s3-uploads enable

Migrating Attachments to Amazon S3 Before Pushing to Staging/Production

Your uploads should automatically be going to your S3 bucket. To confirm you would turn off local uploads by setting this previously defined variable to false define('S3_UPLOADS_USE_LOCAL', false);

Then go to your dev site and confirm all images are working and pointing to the Cloudfront CDN url.

If for some reason, you attachments aren’t already on S3, that means you will need to manually migrate them.

In your terminal run the command to migrate all attachments to your S3 bucket.

wp s3-uploads migrate-attachments

If many or all of your attachments are being skipped, you may need to cut and paste (important to cut) the uploads from web/app/uploads/s3/aws_bucket_name/uploads to web/app/uploads.

Check if they are now showing up without 404 errors and switch back this variable back to true to continue development: define('S3_UPLOADS_USE_LOCAL', false);

Amazon S3 Backups

Mike Doubintchik

Author Mike Doubintchik

More posts by Mike Doubintchik

Leave a Reply