I use a lot of different tools to run my websites, and over time I’ve learned what I want is to have my static content, the files that are uploaded and are images, stored separately from my apps. So while I have the basic folders on my domain (wordpress, wiki, gallery) I have a special subdomain called static.example.com
for all those images and videos.
There are a few reasons I do this. First, I like having my images separate. Second, it allows me to establish a cookie-free subdomain for images and that shuts up YSlow’s check.
Create The Subdomain
Do this however your host allows. Keep in mind that some don’t allow you to traverse domain folders. If your host creates your domain as /home/user/example.com
and subdomains as /home/user/static.example.com
you may have to fight a little more with things depending on your setup. If possible, I prefer to put the subdomain folder inside the main web root.
If you’re using cPanel, by default you get your static subdomain installed at /home/user/public_html/static
which is how I like it. This is perfectly accessible by all things but it’s also browsable at example.com/static/
and we don’t want that. Applying a little .htaccess magic will solve this.
# CDN
<If "%{HTTP_HOST} == 'example.com' ">
RedirectMatch ^/static/(.*)$ http://static.example.com/$1
</If>
Now we’re ready to go!
Move WordPress Uploads
This used to be really easy. Go to Settings -> Media and change things. But we removed that to stop people from blowing themselves up. Now there are a couple ways about it. I jumped right over to editing the options by going to wp-admin/options.php
and look for upload_path
and upload_url_path
.

I change upload_path
to /home/example/public_html/static/wordpress
which is where I’ve moved all my images. Then upload_url_path
becomes http://static.example.com/wordpress
and I’m done except for fixing my old posts. It’s actually pretty neat that once I put those paths in, the Media Settings page lists them as editable.
Fixing the old posts takes a little trick though, and you’ll have to search/replace your posts via the database:
UPDATE wp_posts SET post_content = REPLACE(post_content,'http://example.com/wp-content/uploads/','http://static.example.com/wordpress/');
Or in wp-cli:
wp search-replace http://example.com/wordpress/wp-content/uploads http://example.com/wordpress
The gotcha here is that since I use SSL for my administration, I had to set up a new certificate for the static domain. Not a big deal right now since I can set up a self-signed, or use StartSSL until Let’s Encrypt is off the ground. It is something to consider though.
Move ZenPhoto Uploads
I have to start by warning you that Zenphoto doesn’t like this. When you install it, it puts your images in an albums folder, in the Zenphoto gallery install. This isn’t so bad, but you actually can move it around. You have to look in your zenphoto.cfg.php
file (found in zp-data
). The default location for your albums is defined by this:
$conf['album_folder'] = '/albums/';
$conf['album_folder_class'] = 'std';
Since I want it in the static location, I tell it my folder path based on ‘web root’ and that its ‘in_webpath’ (which tells ZenPhoto to look in the root and not relative), by changing that section to this:
$conf['album_folder'] = '/static/gallery/albums/';
$conf['album_folder_class'] = 'in_webpath';
But that means my URLs for images become http://example.com/static/gallery/albums...
and I wanted http://static.example.com/gallery/albums...
instead. Thankfully the .htaccess rule I used at the beginning of all this covers me there. Looking into this, I understand this is the case because unlike MediaWiki or WordPress, ZenPhoto only has one ‘location’ setting. The other two have path and URL.
MediaWiki
This was … weird. Technically all you have to do is set up the folders and change the following values in LocalSettings.php
:
$wgUploadPath = "/static/wiki";
$wgUploadDirectory = "/home/example/public_html/static/wiki/";
The thing that’s weird is that the documentation says you can do this:
$wgUploadPath = "http://static.example.com/wiki";
And when you do, the image URLs properly call from the domain name. They just won’t load. When you dig deeper, it turns out that it’s caused by the settings for responsive images. The way it puts in srcset
doesn’t seem to like this. So for now I’ve disabled it and my setup is this:
$wgUploadPath = "http://static.example.com/wiki";
$wgUploadDirectory = "/home/example/public_html/static/wiki/";
$wgResponsiveImages = false;
End Result?
All my uploaded content is on my ‘static’ subdomain, separate from everything else, which makes version control even easier. Also now if I ever decide to move things off to a CDN, I’m pretty well set up.
The real reason I do this is that while some of my content is uploaded via the content management systems I use (WordPress, ZenPhoto, etc), the majority is not. ZenPhoto, for example, is faster to FTP up a gig of images than it is to use a PHP tool. Ditto videos. And because of them, it’s nice to have a separate location I can give access to without allowing someone full rights on all my tools.