Django Settings for Production and Development: Best Practices
sparklewise.com
sparklewise.com
That said I tend to use env vars to identify which environment an app is running in and build everything off that, which branch / db / logging target etc to use.
Be aware about issues between mod_wsgi and that approach - http://code.google.com/p/modwsgi/wiki/ApplicationIssues#Appl...
The answer to this is always no.
settings.py:
CACHES = {
'default': { 'BACKEND' : 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION' : [ {% for IP in MEMCACHED_SERVERS %}'{{IP}}:{{MEMCACHED_PORT}}', {% endfor %} ],
},
Yes, that's a django template in python code. Upon deployment, my fabfile renders the settings file along with various other config files. This makes sure that {{MEMCACHED_PORT}} doesn't accidentally say one thing in settings.py, and another in memcached.conf.This also allows me to keep my sitewide settings in a single file or two, namely a module in the fabfile folder.
It feels a little dirty to do things this way (though I can't figure out why), but it's saved me a lot of headaches.
settings.py
settings_development.py
settings_staging.py
settings_production.py
Where the first one has the defaults (usable for local development), and the others contain any overrides needed to run with Gunicorn on the corresponding dev/staging/production servers. settings/
__init__.py
defaults.py
dev.py
live.py
testing.py
users/
__init__.py
*user specific settings*Here's a good example (start at line 207): https://github.com/armon/DjangoProjectExample/blob/master/pr...
ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
configs = {
'/path/to/my/local/dev/folder': 'alex',
'/var/www/www.mywebsite.com/test/private/django/mywebsite': 'test',
'/var/www/www.mywebsite.com/prod/private/django/mywebsite': 'prod'
}
config_module = __import__('config.%s' % configs[ROOT_PATH], globals(), locals(), 'mywebsite')
for setting in dir(config_module):
if setting == setting.upper():
locals()[setting] = getattr(config_module, setting)
Then I have alex.py, prod.py and test.py all in a config subfolder. All under version control, with my settings.py automatically choosing the right environment based on where it's deployed to.I typically use this set up:
- settings.py contains global settings that aren't effected by deployment level.
- at the bottom of that file you have
try:
from settings_local import *
except:
pass
- in settings_local.py you have your deployment level dependent settings- then just git ignore settings_local.py
Thanks
except ImportError:
right? ;)In my fabfile I have environment 'setters' that precede regular commands. So I can do 'fab qa deploy' or 'fab prod deploy' and the deploy command grabs the correct settings_local file for the target environment.
Save your local settings as settings_local.py.exmp and then
ln -s settings_local.py.exmp settings_local.py
Giving you working local settings, and a versioned copy of them, that is useless unless linked properly.I can then, in each of my specific environment files just from settings import * and have access to the direct variables for all of my __init__.py items I setup. Most of the time you'll just have different database and cache settings for these environments.
Before you yell at me about the * import, yes, it normally is a bad idea but in this case it is good. It does often get abused and that is why so many people see it was "bad".
More info: http://devcenter.heroku.com/articles/django
WP gets a bad rap because it seems to spit out the oh so unattractive "Error Connecting to Database" message under the slightest load. Perhaps it's inefficient, i'm not sure why it seems to die so easily.
But... good news is, there is a simple solution. WP renders everything dynamically on every request. It fetches the post from the DB each time you load the page. But, more often than not, the content is only going to change when 1) you write a new post, or 2) a comment is made to a post.
A simple caching plugin solves this. It will render the page with a specific timeout (3600 seconds is default I think?, 1 hr) and then just serve up that HTML rather than hitting the DB. This will solve 99% of your problems. I've never really seen a WP site die when used with something like this. Duh, because it's just static HTML at that point haha.
Combine this with a PHP cache like APC (my personal favorite opcode cache of the moment) and a fast webserver like nginx, and you're gonna pretty much survive anything.