Well, first off, I wouldn't move files directly from dev or qa to production. Like your question implies, I would deploy a tagged release from your SCM (subversion, in this case) directly to your respective environments.
Broadly speaking, I would recommend looking in to a specialized deployment tool, like Capistrano. There is a bit of an up-front time investment to learning the tool and setting up your deploy scripts, but the power of being able to say "cap deploy qa" or "cap rollback production" later on to change your running version in a matter of seconds will a) more than repay that initial time investment, and b) save your butt when things go wrong.
To directly address your question, though, if you were doing it by hand I would recommend a process something like this (with sudo inserted where necessary):
- Have a
/opt/my_app/
directory with multiple subdirectories containing different versions, and a "current" symlink to whichever one is live.
- Point your apache configuration to
/opt/my_app/current
- To roll out a new version, run something like "
svn export https://my_repo/my_app /opt/my_app/1.2.3
" (assuming the new version was 1.2.3).
- Change the symlink: "
rm /opt/my_app/current; ln -s /opt/my_app/1.2.3 opt/my_app/current
"
- Restart Apache or other processes as necessary.
Database updates are a more interesting question. Personally, I love Rails's Migrations for this. If you were doing it by hand, you might include a couple shell scripts in your project to update the db and roll it back, respectively, but keeping those versioned correctly would be sort of tricky, since they would be specific to only one particular version. I'd recommend using an existing system like Migrations (which can be used separately from Rails - I've seen it as the only Ruby component of some Java-based projects), or asking that as a separate question.