[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Packaging Django applications and projects



W dniu 08.03.2011 18:10, Paul Wise pisze:
On Tue, Mar 8, 2011 at 9:50 PM, Zygmunt Krynickiu<zkrynicki@ubuntu.com>  wrote:

I'd like to define and document the recommended best practice of packaging
Django 1.0+ (and especially 1.3) web applications and projects for Debian. I
started this on the Debian wiki at
http://wiki.debian.org/DjangoPackagingDraft

Some things I (as a sysadmin user of Debian) would like to suggest for
all web apps, django based or not:

Use debconf to ask if the sysadmin wants to setup a site and then ask
for enough detail to do so. The package should ship a script that can
be called either manually by the sysadmin or automatically by the
maintainer scripts (using debconf answers) to setup a site or a
sub-path of a site.

The current web apps policy recommends [1] that by default the application should be accessible at http://SERVER/PACKAGE and I understand that decision (it should be possible to install all the web apps without conflicts).

The problem of how to do that generally is still valid (there are a lot of web servers to support potentially). I would start with an initial set that must support apache2 with mod_wsgi. In the future we can offer support for additional web servers.

Ideally this might work with some abstraction layer such as wwwconfig-common. Web applications could drop a file in /usr/share/wwwconfig-common/webapps.d/PACKAGE. Then if the administrator wants to reconfigure the "webapps" running on his server all he needs to do is edit something like /etc/webapps-common/webapps.conf and dpkg-reconfigure webapps-common.

Each application would only need to declare a few pieces:
 - stuff to serve statically (either as DOMAIN or URL-PREFIX)
 - wsgi file
 - name

For example, as JSON:

{
  "name": "django-hello",
  "static-content": [
    {
      "pathname": "/var/lib/django-hello/static",
      "url_prefix": "static/",
      "domain_prefix": "static.",
      "description": "Static resources used by django-hello"
   },
   {
      "pathname": "/var/lib/django-hello/media",
      "url_prefix": "media/",
      "domain_prefix": "media."
      "description": "User submitted resources used by django-hello"
   }
 ],
 "wsgi": "/var/lib/django-hello/django.wsgi"
}


The www-common middleware would then store a record for each application. This record would contain:
 - enabled or disabled status
 - custom sub-URL if desired
 - custom DOMAIN if desired

Again, as JSON:

{
  "name": "django-hello",
  "custom_url": false,
  "custom_domain": false,
  "enabled": true
}

This would serve it as http://SERVER/django-hello/

Another example:

{
  "name": "django-hello",
  "custom_url": "/",
  "custom_domain": "hello.example.org",
  "enabled": true
}

This would serve it as http://hello.example.org/



All combinations of those two options would be supported. Sub URL could be set to / to mark a single application as main. A custom DOMAIN would limit such entries to the specified virtual host.

The glue code would then read the database of web applications, read the configuration of each web application and regenerate the webserver-specific configuration files.

Database (with South etc) and configuration upgrades (with
Config::Model or similar) are great, please do them as automatically
as possible after confirmation using debconf and or provide scripts
for the sysadmin to do them.

South support is rather easy. I still need to check what should happen in the downgrade use case and where exactly to store a backup of the database but in general it should be possible to support this correctly.

Configuration upgrade is more difficult as it really depends on what the maintainers of a web application desire to expose as configuration and what is merely an implementation detail that should not be configurable by the system administrator. I agree that supporting this is important (and especially supporting upgrades that don't break things). I tend to lean to a recommendation that application settings are handled explicitly by particular web application. That is: a web application should define a configuration file with all the things it publicly supports. IMHO this would be usually limited to email settings (do we have webapps-email-common?), database settings (dbconfig-common), administrator name, pathname of the "storage area" for user content. The rest should be implementation detail. We can have a django module for supporting such configuration system. It would have the advantage of not requiring code changes (the way django currently requires) and could be a healthy thing for the wider django community in general.

I'm a little worried about upgrade verbosity. In particular, I would like to allow silent (unattended) upgrades if possible. I think with proper debconf settings it's possible to ask the question "do you want to upgrade database schema to version $FOO" with "yes, I do" being the silent default. The issue here is that unless you upgrade you cannot really start the application properly which should (AFAIR) be treated equally as upgrade failure. That's rather extreme IMHO. I'd rather require that applications can be safely upgraded because the system will create appropriate database/media files backups before it triggers the process.

Data: I like to differentiate between data supporting the package and
data that belongs to the sysadmin/site. IMO the former belongs in /var
somewhere and the latter at a path chosen by the sysadmin. I don't
think this is gotten right by much software, including by all database
packages.

How do you differentiate which data belongs to the sysadmin/site and which to the package? Do I understand correctly that user-submitted content is "application data" and static resources are "package data"?

Thanks for the feedback!
Zygmunt Krynicki

[1] http://webapps-common.alioth.debian.org/draft/html/ch-httpd.html#s-httpd-location


Reply to: