Django. DEBUG in production - python

I'm writing my first real project in Django and I have a problem with properly setting DEBUG in development and production. In my settings.py project file I have:
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = os.environ.get('DJANGO_DEBUG', 'True') == 'True'
So I expect that it should work as follows. By default DEBUG is set to True (I use this in my development). But on my production server I have an environmental variable DJANGO_DEBUG set to "False" so Django should set DEBUG to False.
But this does not work! When I go to my_website/notexistingurl I see Django detail error page which says that I have DEBUG set to True in my settings.py file. And to make this completely unclear to me, when I open a python shell on my server it says that os.environ.get('DJANGO_DEBUG', 'True') == 'True' is False.
Does anyone have an idea what I am missing? Because to me it looks like two completely contradictory things!

This is more a guess, but normally the Django server will not run under the same user as the "administrator". Indeed, as an extra security measure often such processes run under a separate user with limited privileges.
The aim is to prevent users that somehow can inject code in your Django application to gain more control. Indeed, imagine that a hacker found a way to evaluate arbitrary Python code by the Django server, then that hacker could eventually get control to all thinks the user that is running the Django app has control over such as files, devices, internet connections, etc. To limit this, often the Django app will run with a user that has that much privileges necessary to run the Django app, but not (much) more than that. While there might still be exploits to perform privilege escalation, this will at least make it more difficult and time-consuming.
This thus means that the environment of the user with which you are setting up the Django app, is not the user that runs the Django app, and therefore the environment variable probably is not set for that user. There is no universal way to solve this, since this likely depend on your hosting provider, but (very) likely there are ways to set environment variables for the django app user.
But nevertheless, it might be better to "reverse" the setting: right now you run in debug mode by default, and only in production when explicitly set. That is more risky, since things could get wrong when setting the environment variable, or deploying the application. When the Django app runs in debug mode it shows fragments of the source code, and one perhaps can manipulate the view that serves static/media files to serve more sensitive files. It might be better to run by default in production mode, and only run in debug mode when explicitly stated. For example with:
DEBUG = os.environ.get('DJANGO_DEBUG', 'False') == 'True'

You should run
heroku config:set "Set DEBUG VALUE"

Related

Deploy/Reload code from python pyramid project in production

I use ...\pserve development.ini --reload in my dev environment to restart my API when code change.
The doc says:
Auto-template-reload behavior is not recommended for production sites
as it slows rendering slightly; it’s usually only desirable during
development.
But the doc has no proposition for a production environment. What's the recommendation to reload, do I have to make it manually every time?
Yes, you will need to restart the service if you change anything in your config file.
If you know that you'll be changing things and don't want to restart it every time that happens, move some of your configs to a database and refactor your app to read from that. This won't be possible for everything, and you'll need to be careful that when an update happens it is applied correctly, but it can be done for some things.
First of all, you are talking about the section of the documentation, Automatically Reloading Templates. That only discusses how to reload templates automatically, not your entire application.
The documentation explicitly states not to use --reload in production. That is an automatic function, not a manual one.
If you change your code and deploy it to a production environment, it is assumed that you would restart your application manually, thereby removing the need to use --reload when invoking pserve production.ini.

Django: Push app from local server to production server via FTP

This is a bit embarassing, but I'm a Django noob and I couldn't find a simple solution to this:
I have written a Django app in a local VM that I now want to deploy to a "production" server. App works like a charm locally.
Now my IT colleague has set up the server with Django and that also works fine. I can open it via the Web and I get the usual "Congratulations on your first Django-powered page". I can also log into the admin interface. The project has been created.
This is a very low-key mini project and I'm not too familiar with git, so we've decided to just push files via FTP. (And I want to stick with that if at all possible.) So I uploaded the app folder into the project folder and also adjusted the project's settings.py and urls.py.
However, nothing seems to be happening on the server's end. The welcome page is the same, the app does not show up in the admin interface and the URLs won't be resolved as hoped.
Any suggestions what I should have done / done differently?
You need to restart apache or whatever is running your django project. Your changes to py files are cached when you first load your server config (settings).
Any suggestions what I should have done / done differently?
You should be using git/jenkins/deployment techniques, I know you said you've decided not to use it but you're going to be missing out on important things like being able to keep track of changes and unit testing

Django and Heroku: Environment variables [duplicate]

I currently have a running production Django application on Heroku. Unfortunately, I haven't been able to turn off the DEBUG setting on Heroku. Turning it off locally works fine, but when pushed to Heroku (after heroku config:set DEBUG=False), it doesn't apply.
The error pages are still the default DEBUG ones instead of the 404, 403, and 500 templates in our template root.
I have also tried using a DJANGO_DEBUG setting in case there were any environment conflicts with DEBUG, and casting the result to a boolean in the settings file. heroku config shows the settings in the environment are correct. This is on Django 1.3, Heroku Cedar.
Any tips or solutions?
Does your django settings.py file even look in the environment?
It does not, by default, care about anything you've set in the environment (via "config:set"). If you're "casting" the environment to a boolean, make sure you're casting it correctly. bool('False') is still True.
It's simplest just to detect if the environment variable exists so you don't have to worry about type casting or specific formats of the configuration.
DEBUG = os.environ.get('DEBUG', False)
To disable debug, remove the variable from the environment instead of trying to type cast... it just seems much more reliable and fool proof. config:unset DEBUG
The problem is that the environment variable is not a boolean, rather a string.
So do place below line in settings.py
DEBUG = (os.environ.get('DEBUG_VALUE') == 'True')

Common errors when moving a django app from dev to prod?

I am developping a django app on Windows, SQLite and the django dev server . I have deployed it to my host server which is running Linux, Apache, FastCgi, MySQL.
Unfortunately, I have an error returned by the server on the prod while everything ok on the dev machine. I've asked my provider for a pre-production solution in order to be able to debug and understand the problem.
Anyway, what are according to you the most likely errors that can happen when moving a django app from dev to prod?
Best
Update: I think that a pre-prod is the best way to address this kind of problem. But I would like to build a check list of what must be done before to put in production.
Thanks for the very valuable answers that I received until now :)
Update: FYI, I 've implemented the preprod server and the email notification as suggested by shanyu and I can see that the error comes from the smart_if templatetag that I am using on this new version. Any trick with template tags?
Update: I think I've fixed the pb which was caused I think by the Filezilla FTP sending. I was using the "replace if newer" option which I guess is causing some unexpected results. Using the "replace all" option fix the issue. However, it was an opportunity for me to learn more about deployment. Thansk for your answers.
Problems I typically have include:
Misconfigured productions settings, whether in my production localsettings.py, wsgi/cgi, or apache site files in /etc/sites-available
Database differences. I use South for migrations and have run into some subtle issues when performing my migration on PostgreSQL when it worked smoothly in sqlite.
Static file hosting since I cheat and use the Django server in development
Permissions, both on the file system and within the database
Rare, but possible, network issues preventing me from getting my dependencies, whether on PyPi or some 3rd party site
Ways that I have mitigated these issues:
Use the same database in production and development (in your case, MySQL everywhere)
I've found it is useful to have a "test" environment which mimics production in every way possible (it can be on lower end hardware, or even the same machine). This way, if there are any issues in this "production-like" enivornment, I can solve them without taking my production server offline.
Script everything for repeatable deployments. I use fabric, but zc.buildout or Paver would also work. These tools help reduce typos while deploying and reduce the time to deploy my app.
Use version control (mercurial, git, subversion) and a schema migration tool (like South), so if something does go wrong when you deploy to production, you have the possibility of backing out the changes and allowing production to run on the old code with the old database schema.
I haven't set up an "egg proxy" yet, but I am considering it, to avoid issues when downloading dependencies.
I've found pip's freezing dependencies to be useful, in case a new, incompatible change to a library occurred since I downloaded it initially
Use a web testing framework like Windmill or Selenium to test my application in my "test" environment, so that I can get a lot of test coverage of my system very quickly.
Regarding your case, I can think of 2 simple things that may help you:
You can enable Django to send messages when exceptions occur giving details about them. Look at here for details.
You'll be better off if you set up a test environment on the prod server (say, test.example.com) so that you can check if things will go smoothly or not before you deploy the app.
I believe these were the podcasts I listened to recently (from Pycon 2009):
Locate Django in the Real World (PyCon 2009):
http://advocacy.python.org/podcasts/pycon.rss
Parts 1 to 3
Very good introduction to designing your apps for deployment, in particular for reuse and redeployment.
Regs.

Restarting a Django application running on Apache + mod_python

I'm running a Django app on Apache + mod_python. When I make some changes to the code, sometimes they have effect immediately, other times they don't, until I restart Apache. However I don't really want to do that since it's a production server running other stuff too. Is there some other way to force that?
Just to make it clear, since I see some people get it wrong, I'm talking about a production environment. For development I'm using Django's development server, of course.
If possible, you should switch to mod_wsgi. This is now the recommended way to serve Django anyway, and is much more efficient in terms of memory and server resources.
In mod_wsgi, each site has a .wsgi file associated with it. To restart a site, just touch the relevant file, and only that code will be reloaded.
As others have suggested, use mod_wsgi instead. To get the ability for automatic reloading, through touching the WSGI script file, or through a monitor that looks for code changes, you must be using daemon mode on UNIX. A slight of hand can be used to achieve same on Windows when using embedded mode. All the details can be found in:
http://code.google.com/p/modwsgi/wiki/ReloadingSourceCode
You can reduce number of connections to 1 by setting "MaxRequestsPerChild 1" in your httpd.conf file. But do it only on test server, not production.
or
If you don't want to kill existing connections and still restart apache you can restart it "gracefully" by performing "apache2ctl gracefully" - all existing connections will be allowed to complete.
Use a test server included in Django. (like ./manage.py runserver 0.0.0.0:8080) It will do most things you would need during development. The only drawback is that it cannot handle simultaneous requests with multi-threading.
I've heard that there is a trick that setting Apache's max instances to 1 so that every code change is reflected immediately--but because you said you're running other services, so this may not be your case.

Categories

Resources