How to migrate user data and preserve old links with Nginx
Saturday, June 5th, 2010Yesterday I found that I’ve hosted 1GB of Freshlog-uploaded screenshots on my VPS account since I’ve launched in August 2009.
VPS (Virtual private server) are great for hosting Rails applications since they more or less provide you a guaranteed slice of CPU and memory. Furthermore, if another account on the same physical server dies, it’s self-contained and the other slices continue to run without a performance hit. Throw in a full-fledge root account and the option to independently reboot your slice – definitely more stability and control than a shared rails hosting environment. They’re cheap too, I’m only paying US$8 per month to my provider, prgmr.com, perfect for bootstrapping a startup, Freshlog in my case.
However, since I’m only selling Freshlog as a one time purchase and have been offering complimentary screenshot hosting, (the main selling point of Freshlog is uploading screenshots to other services), I wouldn’t be able to afford to upgrade to a bigger plan indefinitely.
Even so, I really enjoy using Freshlog myself and didn’t want to disappoint friends and fans by discontinuing my hosted screenshot service.
I understand the need for the links to existing Freshlog screenshots to continue to work, as users would have embedded HTML containing freshlog screenshot links in their own online documents and it would be very irresponsible to simple break them. I have also personally used countless Freshlog screenshots in my help and support documents on my Freshlog support site.
So here’s how I migrated 1GB of screenshots to another web host (VPS hosting costs are pricier for the full control you have over it) and freed up space on my VPS with an Nginx configuration, while preserving old links:
With existing Freshlog screenshot urls looking like this:
http://freshlog.com/photos/3704/large/ca2507287635411f76aade14a5a11d39.png
And I need them to be redirected transparently to my new host like this:
http://dh.freshlog.com/freshlog1/photos/3704/original/ca2507287635411f76aade14a5a11d39.png
I achieved this with Nginx rewrites, similar to Apache’s mod_rewrite, here’s what I added to nginx.conf:
if (!-f $request_filename) {
rewrite ^\/photos\/(\d+)\/([a-z]+)\/([a-z0-9]+).png$ http://dh.fres\
hlog.com/freshlog1/photos/$1/$2/$3.png;
}
Here’s what it does:
If the requested file ($request_filename) does not exist (!-f), parse the URL via regular expressions and redirect it to the new URL.
The changes are transparent to users and if you were to create new screenshots, the new screenshots will continue to be created and hosted my VPS, but if you were to access screenshots that were transferred to my other webhost, Nginx will find that the file does not exist locally and transparently redirect to the new host, all without any broken links.
In future, when storage starts to dwindle again, I’d simply transfer the screenshots to my secondary host and delete them locally on the VPS and Nginx will handle all the transparent redirects.
If you have a better way to migrate users’ data, do let me know in the comments.









