Production Config

Your production config file looks much like your development.ini file, but you will generally need to make a number of changes to make your config “production ready”. There are a lot of warnings in this document because there are a lot of ways to seriously compromise your security by mis-handling or mis-configuring a production.ini file.

Note

Throughout this document we’ll refer to this file as production.ini. The file can be named anything you like, and there can be multiple versions, such as having myapp-staging.ini and myapp-production.ini to configure two different deployment branches of your application.

Warning

You must never check your production.ini files into a publicly-accessible source-code control system! Doing so will violate your web-site’s and potentially your server’s security! See Check In Your Config

Set debug=false

Warning

You MUST set debug=false in your production.ini, Paste in debug mode provides interactive debugging which allows any user of the site to run arbitrary Python code! This must never happen on a production site (or even a development site which is exposed to other machines), as it will give any visitor to the site complete control of your server.

In your configuration, you will find a line that looks like this in the [DEFAULT] section:

[DEFAULT]
...
# WARNING == If debug is not set to false, you'll get the interactive
# debugger on production, which is a huge security hole.
debug = false

be absolutely sure that debug is set to false. Similarly, there will be another line (normally further down the file, in the app:main section) which looks like this:

[app:main]
...
# WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT*
# Debug mode will enable the interactive debugging tool, allowing ANYONE to
# execute malicious code after an exception is raised.
set debug = false

again, be absolutely sure that set debug = false is uncommented and that the value is false (not true).

Set full_stack to False

This is another security-related configuration element. You should not expose a full_stack enabled application to the Internet.

[app:main]
...
full_stack = false

Todo

verify whether this is still necessary in TurboGears 2.1

Set Your Production Database URL

You will need to alter the SQLAlchemy database URL to reflect your production database. See Production Database.

Warning

Keep in mind that anyone who has access to this file will now be able to connect to your database. The SQLAlchemy URL includes the username and password to log in as your DB user.

See Check In Your Config

Change Your Keys

There are a number of “private keys” configured in the config file. You should update each of these to a new value. At minimum, the following keys should be updated:

[sa_auth]
cookie_secret = long-string-of-digits-here

[app:main]
beaker.session.secret = long-string-of-digits-here

These values should not be shared. See Check In Your Config

Check File-Storage Locations

Warning

This section does not apply if you are deploying your code using an egg (which is the Standard Deployment Pattern). It likely applies if you Deploy with a Source Code Checkout.

You may be planning to replace your entire application checkout directory every time you re-deploy your application, so things such as persistent session-storage, and cache directories should be located outside your checkout. By default the quick-started application will use %(here)s variables to control where the cache and session data is stored. If your production.ini is in your source-code checkout (see Check In Your Config for issues with this), this will be a directory that will potentially be deleted frequently, and you will need to specify an alternate location.

The appropriate location for application data-storage is somewhat open to sysadmin preference, but a good default choice would be /var/local/myappname, which would require config lines like this:

[app:main]
...
beaker.session.data_dir = /var/local/myapp/sessions
beaker.cache.data_dir = /var/local/myapp/cache
beaker.cache.lock_dir = /var/local/myapp/locks

You will need to create these directories and make them writable by the www-data user.

See Caching and Web Session Usage for discussions of the Beaker system along with alternative deployment options, such as the use of Memcached.

See Deploying Your Project Code.

Check Log-file Options

Generally speaking you will want to store your log files in the standard log hierarchy for production systems. You will also likely want to configure the log files to use a logging.handlers.RotatingFileHandler to prevent your application log-files from filling up your server’s hard-disk.

[handler_logfile]
class = logging.handlers.RotatingFileHandler
args = ('/var/log/myapp/myapp.log', 'a',1024*1024*50,3)
level = WARN
formatter = generic

You may want to set up multiple log-files with different logging levels configured, or split out a particular type of log (such as access logs) into a separate file.

You’ll want to reduce the SQLAlchemy logging level to WARN in most cases:

[logger_sqlalchemy]
level = WARN

You will want to be sure that the /var/log/myapp directory exists, and is writable by the www-data user.

$ sudo mkdir /var/log/myapp
$ sudo chown www-data:www-data /var/log/myapp

See Configuring and using the Logging System for more details.

Configure Proxy Mount Point

Warning

This section only applies to “proxied” sites, which are not part of the Standard Deployment Pattern.

If you are not mounting your application at the root of your site (i.e. you are mounting your application as a sub-site of some larger site) and are using a non-embedded WSGI environment (such as a reverse proxy) then you will need to configure TurboGears so that it knows how to resolve application URLs from that base URL.

# DO NOT DO THIS WITH MOD-WSGI!
[app:main]
...
filter-with = proxy-prefix

[filter:proxy-prefix]
use = egg:PasteDeploy#prefix
prefix = /wherever_your_app_is mounted

See the PasteDeploy Documentation for details on the prefix middleware being configured here.

Test your Config

Your paster config-file is a regular config-file, and often you can run it with the Paste web-server. Keep in mind that your config file will likely specify file-paths that only the www-data user can write to, so you will likely need to run paster as the www-data user:

$ sudo -u www-data server production.ini

Check In Your Config

Warning

Your production.ini contains secrets, keys, passwords, and everything else an attacker would need to crack your application and potentially your server. Never check it into a publicly readable repository! Particularly, if you run an Open Source project, never check your production.ini into the main repository!

You will want to check your production.ini into source-code control of some form, but before you add it to your project’s source-code project, consider the security implications of doing so.

Your production.ini includes your application’s database connection parameters (the SQLAlchemy URL). If your organization’s policies preclude developers from having access to such information, you cannot check the files into the project. Even if they don’t, if your database is likely to hold personal, financial or other sensitive information, you may find it prudent to store the production.ini in a separate location so that the information can be controlled.

If you have a dedicated sysadmin team, they will often have a preexisting configuration management system which can be used to store the production.ini file.

Note

If you are your organization’s entire technical team, you can likely check your production.ini directly into your application’s repository, as long as that repository is not shared publically.

What’s Next?

  • Production Database – you will normally have to run paster setup-app with your production.ini in order to initialize your database
  • deploy_modwsgi_deploy – if you are using the Standard Deployment Pattern you will need to move your production.ini to expected location