- Deploy early If you want to avoid the hassle of debugging 100 things at once, deploy your project as soon as possible. By "as soon as possible" I mean right after you create it - when there are no models, views and funky url settings!
- Commit often You are of course using source control for your project, correct? By committing often you allow for greater granularity of your project. In a way you "isolate" bugs in a particular commit. This makes finding them later on particularly easy.
- Deploy often Same as #1 - the only way to make sure it works - is to put it out into the wild!
- Separate production from development. You should have something like this in your settings.py file: if socket.gethostname() == 'server40.online.com': DEBUG = False else: DEBUG = True and feed all your other settings (i.e. database, media, etc) from this variable. This will make for painless deployment.
- Use dynamic path names Don't just hardcode "C:\Documents" or "/home/user/app" in your settings. Don't be lazy. This is how we do it: import os SITE_ROOT = os.path.dirname(os.path.realpath(__file__)) and then go crazy for all the other path veriables: MEDIA_ROOT = os.path.join(SITE_ROOT, 'core/media') TEMPLATE_DIRS = ( os.path.join(SITE_ROOT, 'core/templates') ) and so on...
- Checkout source code into production Don't just copy your code to production server with FTP or SCP! Install revision control like git or mercurial on the server, so you can hack away at the code without being afraid of messing things up, and more importantly - not loosing your important "tweaks" that you can only do in production.
Debugging the Deployed
- Check your path and full-qualify the import names Make sure you python path is correct. Sometimes the modules you can see in your development - are invisible in production. If your project structure is something like this: /project ---/app ------- views.py and you are importing your views in your urls.py files like so: from app import views than you might get a wierd handler500 error that makes no sense at all. Either reference your modules with full qualified names, i.e. "project.app.views" or put the path to your app directory into your path: "/home/user/blah/project/app".
- Back up - test - roll forward Sometimes you can't tell if the bug is from your latest update. Because production can keep some code in memory - one often fails to notice a bug until it is more than one update later. Your first order of business should be to find the bug exactly. Figure out which "commit" added that bug into the system. For this you must follow these steps: a) Roll back to some point in the code where it worked b) Restart your server, services etc... Make sure it works. c) Roll forward to the newer revision d) Restart. If everything still works - go to c). e) If stuff is broken Roll back to some point before a). Essentially you are doing a "binary" search on your commit history to isolate the bug. If you are using git - you can automate this process with git-bisect. Once you find the offending commit - roll your code to the revision before it, and start by copying by hand the code from the offending revision. Hopefully because you kept your commits small, it should not be too long before you find the bug!
- 90% it's urls and imports Most likely you screwed up your imports or urls. Check them over.
- The other 10% it's your 500.html and 404.html Did you create your 500.html and 404.html pages in your templates directory? The production environment won't work without them.
- User postgresql_psycopg2 and not postgresql This is more of a tip than debugging technique, but one often confuses the two. The new psycopg is termed psycopg2 and so we must use postgresql_psycopg2 for our database engine setting.
- Set DEBUG to True on production Just below your logic which determines your DEBUG variable, overwrite it temporarily with true. if blah.. DEBUG = True else: DEBUG = False DEBUG = True # Overwrite temporarily This is a real hack, but it can temporarily give you some great insight into the problem.
Conclusion
In the end if you try to keep the "production" on your mind from the start, your deployment should be not a problem. Because one does not deploy very often, one tends to forget all the mistakes that were made previously. This makes it really challenging to get it "right" every time. Some time is spent going over the error logs and figuring out the same problems. However we cannot solve this. It will always be like so.
The best thing you can do is prepare for this process ahead of time - and once there, have effective ways of dealing with it.