Getting Media on Your Local WordPress Site

If you’ve worked with WordPress sites for a while you’ll know that sometimes the hardest part is settings up a local environment that is close enough to your production environment to make a difference. While there are plenty of ways to do this one mistake I often see made is a somewhat crazy push to synchronize the contents of the uploads directory with your local site. This is the wrong question.

You Don’t Need the Uploads

First of all, most of the time you really don’t need the uploads at all. In fact, if you’re developing a plugin or a theme you probably don’t need any of the content in the uploads folder, the database or anywhere else. After all, if the goal is your code the push to keep the content in sync isn’t just unnecessary but may in fact be slowing you down.

Let’s say though that you are maintaining a large complex site. In this case you’ll definitely want to make sure your development environment (and hopefully your staging environment) simulates production as closely as possible. For the database this isn’t too hard, copy it down from production (Navicat is great for this), replace the domain names and you’re good to go.

You Still Don’t Need the Uploads

This is where most people go wrong. I’ve seen it all from trying to download terabytes of images and media to trying to commit them to GIT or some other repository. This is not the way to do it. Now you have two choices… First you can download only the files you need using a plugin like Paul Clark’s Uploads by Proxy. This isn’t a bad way to go and if you work offline frequently might be the best method for you. It will take any media it finds and attempt to download it locally the first time it sees it allowing you to easily be able to use it, online or offline, and it will be there every time you go back to the page even if you lose your connection. If you’re always connected though this still isn’t efficient as you could still wind up with thousands of extra media files on your local machine that aren’t really needed.

Proxy for the Win

A better approach to this is to simply not download the files at all and load them directly from the production site. Doing this method has three distinct advantages:

  1. You’re not wasting local hard drive space. While this isn’t the problem it used to be it can still be inefficient on a very large site.
  2. Images displayed are always the latest image. If someone updates the image on production, you’ll see it. On a media-intensive site or a site heavily involved with media and front-end interactions this along could make it worth it as you’ll always have the most appropriate image for dev. For example, if you’re trying to solve an image sizing bug and the client does so with switching to a different sized image you’ll quickly be able to account for this in your local dev.
  3. You’ll have every image for every page. This should be a no-brainer. No matter how obscure the link you’ll have the media for it. Simple as that.

Of course the only time this isn’t going to work for you is if you work offline regularly but, let’s face it, for most of us that isn’t the case these days.

How to Proxy Your Site’s Images

So how do we do this? For most of using an Apache based local server like DesktopServer, XAMPP or something else it’s as easy as adding a couple of lines to your .htaccess file in the site root:

RewriteEngine On
RewriteBase /
RewriteRule ^wp-content/uploads(.*)$ http://www.mysite.com/wp-content/uploads/$1 [L,R]

Of course you’ll need to replace www.mysite.com with your own site address but putting this above the WordPress rules in your .htaccess file will mean that any file on the production site will be displayed on the dev site, no questions asked, no files downloaded.

 

About Chris Wiegman

Chris is a developer for UF Health at the University of Florida who has been working on WordPress since 2008. Over the years he built one of the largest security plugins on WordPress.org as well as numerous other plugins, themes and other solutions. When not coding Chris loves to teach and has presented at numerous WordCamps and other conferences as well as taught computer security for St. Edward’s University and other University courses ranging from computers to aviation.

Find Chris on Facebook, GitHub, WordPress.org, and Twitter.

Comments

  1. Of course the only time this isn’t going to work for you is if you work offline regularly but, let’s face it, for most of us that isn’t the case these days
    Speak for yourself! Ok, so it’s not that often but it is a real need for me, plus local access is always much faster than a proxied remote. I didn’t realize Uploads By Proxy actually detected used images and downloaded them to local (haven’t tried it in ages), but thinking I need to try it again now. I’ve got too many sites with 5GB+ of assets sucking up precious local SSD space.

    One thing you didn’t touch on. If you add_image_size() locally, how it that handled?

    1. Hey Jon,

      Yeah, this isn’t for everyone. As for manipulating image sizes locally… You would see this on new posts you were testing but it would not be reflected in existing content.

  2. Clear sometimes I am not. I was wondering what would happen with UbP or the htaccess proxy if locally you ran a Regenerate Thumbnails script (Ajax rebuid, regen thumbs, or WP CLI).

    I’m guessing:
    – With UbP it’d create the new size locally only?
    – With htaccess proxy it would just fail (no write permission to remote or if it did would write the new thumb locally and then not know to look for it).

  3. Chris,

    @jb510 showed me this at our dev meetup tonight. Great article, thanks for sharing! There’s a snippit I use that does pretty much the same thing. I’d love to hear your thoughts on the implementation:

    RewriteCond %{HTTP_HOST} ^__local__\.dev$ [NC]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} .*.(?:gif|jpe?g|png|pdf|mp3|avi|mpeg|bmp|mov)$
    RewriteRule ^ http://__remote__%{REQUEST_URI} [L,R=301]

    The thought process on this snippit is that it checks first if the file exists locally (as it would for files uploaded in your local dev environment), and only ship it off to the origin server if it doesn’t exist. That way you don’t cause unnecessary 404s on the origin server. This one is also limited to specific file types too, but I suppose that isn’t super necessary.

    -Brandon

Comments are closed.