Uploads/Media Best Practice

I’ve looked and searched here for any best practice for handling and serving media/uploads/images; staying organised and in sync.

I’m using a digital ocean setup and have the uploads content served directly from there.

Ultimately I know media/content should be uploaded to the live site, with copies pulled into development when its necessary to do so. But initial setups/builds always take place locally until theres something worth pushing live/staging.

I use wp-db-sync to keep the database up-to-date in either direction and this works wonderfully.

For uploading/downloading images scp is used.

Is this whats most common or do people make use of CDNs s3 or some other cloud solution?

Any pointers or suggestions welcome, apologies if my question is not direct enough.

I personally find this playbook handy by @louim. It uses rsync which is a lot more efficient than scp. It only copies media when it’s needed.

Of course having a CDN would be ideal, but in some projects the budget/time doesn’t allow for it

Here’s the full post: Pushing or pulling uploads with Trellis


This is a free plugin but the premium version it’s ripping off has a Media Files add-on. It’ll do a media transfer while syncing the DB.

Thanks @Simeon the ‘legit’ version is on my radar and I may well fork out in the future once the number of wp sites maintained/built justifies it.

For us, the best practice is not keeping uploads on the Wordpress instance at all. Everything goes to S3. Images are served through Imgix, which performs all the image operations such as scaling and cropping on the fly.

I wrote a plugin to manage all of this:

You can use via composer ilab/ilab-media-tools


Thanks for linking this, looks like a fantastic solution. Will be using this in the next build :grinning:

Hi @Jon. Gave your plugin a whirl as it solves a key need here. added via composer and went to activate to find it won’t with a fatal error below. On php7, sage9.
atal error: Cannot redeclare render_view() (previously declared in /srv/www/[domain].com/current/web/app/plugins/wp-views/embedded/inc/wpv-api.php:147) in /srv/www/[domain].com/current/web/app/plugins/ilab-media-tools/helpers/ilab-media-tool-view.php on line 77
Call Stack

Time Memory Function Location

1 0.0010 473968 {main}( ) …/plugins.php:0
2 1.8409 57162512 plugin_sandbox_scrape( ) …/plugins.php:164
3 1.8416 57176136 include( ‘/srv/www/[domain].com/current/web/app/plugins/ilab-media-tools/ilab-media-tools.php’ ) …/plugin.php:1882

You have two plugins with the same function name. They should either be prefixing their function name with a unique prefix or using PHP namespaces. You should probably let both of them know their plugin code is causing fatal errors.

Thanks for the plugin Jon! I’ll be giving it a try.

That’s what you get for using Types :wink:

1 Like

I just posted 1.4.7 which fixes the issue.


1 Like

Thanks man! I see all y’all ACF fan-boys :slight_smile:

Great plugin @Jon . I’m slowly stripping out Types for ACF and dropped S3 Offload in favor of Media Cloud with imgix. Top notch work.

1 Like

Good catch, will look into it.


Hah lol that was from a year ago. Nevermind :wink:

We use https://github.com/humanmade/S3-Uploads and it works just fine at scale. Pulling things down to dev is a non-issue because all the correct URLs are in the database.

I’ve just started using this plugin, all installed great.

I’m a bit stumped on the correct image upload path from Bedrock as described in the plugin documentation here:

wp s3-uploads upload-directory /path/to/uploads/ uploads

What’s the correct path in place of /path/to/uploads ?

I can’t remember 100%, but I’m pretty sure it’s relative to where you run the wp command from.
Try navigating to your install and under current - swap the above path for: /web/app/uploads

If that doesn’t work, keep testing it out with different variations. I’m pretty sure /web/app/uploads/ worked for me, when I ran said command from inside the current directory.

1 Like