Moving Your Drupal 'files' Folder - Dev to Live Sites

When I was rebuilding www.jeffgeerling.com in Drupal, I decided to use the testing domain new.jeffgeerling.com. This presented me with a challenge, once I started working a bit more on the site, as I set up imagecache, the file system, the favicon, the logo, internal images in posts, images inserted into blocks, etc., into my /sites/new.jeffgeerling.com/files directory.

If I simply renamed the directory to 'jeffgeerling.com' and went live, I'd end up with tons of 404 errors. Currently, there's no easy way to switch the location of your files directory in Drupal. Lacking an easy method, it's time to get your hands dirty with a little SQL (I entered the following commands via phpMyAdmin, since my host doesn't yet allow SSH access):

  • Update the files table (which is used by the system as well as imagecache):
    • UPDATE `files` SET `filepath` = REPLACE(`filepath`, `sites/OLDDOMAIN/files/`, `sites/NEWDOMAIN/files/`);
  • Update the boxes table (which is used for all the block content):
    • UPDATE `boxes` SET `body` = REPLACE(`body`, `sites/OLDDOMAIN/files/`, `sites/NEWDOMAIN/files/`);
  • Update the node_revisions table (all the node content is in here... you'll need to update both the body and the teaser fields):
    • UPDATE `node_revisions` SET `body` = REPLACE(`body`, `sites/OLDDOMAIN/files/`, `sites/NEWDOMAIN/files/`);
    • UPDATE `node_revisions` SET `teaser` = REPLACE(`teaser`, `sites/OLDDOMAIN/files/`, `sites/NEWDOMAIN/files/`);
  • Update the users table 'picture' value (if you're using user pictures):
    • UPDATE `users` SET `picture` = REPLACE(`picture`, `sites/OLDDOMAIN/files/pictures/`, `sites/NEWDOMAIN/files/pictures/`);

Now make sure you clear your cache tables (I just used 'Clear caches' in my Admin menu), then empty your watchdog table (TRUNCATE `watchdog`;) and look for any 404 errors. If you find a bunch, there might be another field you need to update with your new filepath.

Hopefully Drupal core will be better able to handle file moving in version 7—I haven't studied that too much yet, but I've heard files will be treated more as 'first class citizens.' Until then, you can either have fun with the above MySQL queries, or you could use private file handling (which uses a path such as /system/files, and allows your file path to be whatever you'd like).

(One other solution is to set up a folder like /sites/sitename instead of /sites/sitename.com, and set up a symlink to the /sites/sitename folder... that's okay, I guess... but not ideal. It would be best if Drupal could handle this stuff (path aliasing, etc.) out of the box.).

Comments

yo dude
everytime i see an article on the planet page i click and it doesnt show up
it happened right now
it gave a 404 error i think cause the search searched for a 500(u have 404search module i think)
anyway i run ur cron a couple of times and it went ok
please fix
good article

i do it this way:
export the db via phpmyadmin as a text file
open with notepad++ and do a find&replace:
like C:/Xampp/htdocs/site to user/home/etc.......

Thanks for the information - I should probably run cron more often on this site anyways... I only have it run once every hour, and when I post a new article, it would be best for cron to have run within a few minutes so it's indexed.

Subdomains (e.g. for small scale testing or staging) work well and these queries are really useful.

Worth keeping in mind though is that there's no need to setup a new sites folder for the subdomain.

Drupal will resolve and use sites/example.com for new.example.com and example.com

That way there's no overhead of ensuring file links are maintained.

This works fine in most sittuations, except for example where your upgrading an existing drupal site working off the same codebase/multisite in which case the new theme and or custom modules would need to be done in sites/new.example.com

Quite true... and something worth noting!

I should've probably thought of that before; I could've worked in the lifeisaprayer.com directory the whole time. But for some other projects, I've still had to move the location of the 'files' folder, and it's always a tedious job (especially upgrading a Drupal site from 4.7.x to 6.x!).

This seems like a nice approach for scenarios where you don't know the NEWDOMAIN when starting development. If you want to see an approach that needs no intervention whatsoever when setup properly from the very beginning, please visit my blog at http://www.paragon-es.de/blog/development-environment-prepared-later-mig...

you should probably also replace

/sites/[domain]/files/
http://[domain]/sites/[domain]/files/
https://[domain]/sites/[domain]/files/

and instead of just replacing the path I would do:
'href=[path]' and 'src=[path]'
(this bit me before. I can't remember why).

you might want to replace in the comments table too, depending on your site.

Quite true! I didn't even think about that... luckily, moving to this new site, I don't have any comments to speak of.

If you search and replace a mysql dump, you risk messing up any serialized arrays that have that text in it. The mysql replace command can be directed at specific fields which you can tell are not serialized.

A very good caveat, to be sure... If you do go the dump route, it would be best to make sure you only dump the node_revisions, files, etc. tables which you need to change.

But a script that would simply change all these values for you (or heck, even a module), would be best.