DotCloud Build File

The DotCloud Build File, ``dotcloud.yml``, describes our stack.

We will start with a single "python" service (we will add the database later).
This service allows us to expose a WSGI-compliant web application. Django
can do WSGI out of the box, so that's perfect for us.

..

The role and syntax of the DotCloud Build File is explained in further
detail in the documentation, at http://docs.dotcloud.com/guides/build-file/.
Specifying Requirements

A lot of Python projects use a ``requirements.txt`` file to list
their dependencies. DotCloud detects this file, and if it exists,
``pip`` will be used to install the dependencies.

In our case, we just need to add ``Django`` to this file.

..

``pip`` is able to install code from PyPI (just like ``easy_install``);
but it can also install code from repositories like Git or Mercurial,
as long as they contain a ``setup.py`` file. This is very convenient
to install new versions of packages automatically without having to
publish them on PyPI at each release.

See http://www.pip-installer.org/en/latest/requirement-format.html for
details about ``pip`` and the format of ``requirements.txt``.
Django Basic Files

Let's pretend that our Django project is called ``hellodjango``.
We will add the essential Django files to our project.
Actually, those files did not come out of nowhere: we just ran
``django-admin.py startproject hellodjango`` to generate them!

.. note::

   The rest of the tutorial assumes that your project is in the
   ``hellodjango`` directory. If you're following those instructions
   to run your existing Django project on DotCloud, just replace
   ``hellodjango`` with the real name of your project directory,
   of course.
wsgi.py

The ``wsgi.py`` file will bridge between the ``python`` service and our
Django app.

We need two things here:

* inject the ``DJANGO_SETTINGS_MODULE`` variable into the environment,
  pointing to our project settings module;
* setup the ``application`` callable, since that is what the DotCloud
  service will be looking for.

..

We can now push our application, by running ``dotcloud push djangotutorial``
(you can of course use any application name you like). A Python service
will be created, the code will be deployed, and the URL of the service
will be shown at the end of the build. If you go to this URL, you will
see the plain and boring Django page, typical of the "just started"
project.
Add PostgreSQL Database

It's time to add a database to our project! The first step is to tell
DotCloud that we want a PostgreSQL server to be added to our application.
Just edit the Build File again.

..

Note that we called our database ``db``, but it could have been anything
else, really.

If you ``dotcloud push`` again, you will see that the database service
will be created (DotCloud will notice that we added a section to the
Build File).
Add Database Credentials to settings.py

Now, we need to edit ``settings.py`` to specify the host, port, user,
and password to connect to our database. When you deploy your application,
these parameters are stored in the DotCloud Environment File.
This allows you to repeat the deployment of your application
(e.g. for staging purposes) without having to manually copy-paste
the parameters into your settings each time.

If you don't want to use the Environment File, you can retrieve the
same information with ``dotcloud info hellodjango.db``.

The Environment File is a JSON file holding a lot of information about
our stack. It contains (among other things) our database connection
parameters. We will load this file, and use those parameters in Django's
settings.

See http://docs.dotcloud.com/guides/environment/ for more details about
the Environment File.

..

.. note::

   We decided to use the ``template1`` database here. This was made
   to simplify the configuration process. If you want to use another
   database, you will have to create it manually, or to add some extra
   commands to the ``postinstall`` script shown in next sections.
Django Admin Site

We will now activate the Django administration application.
Nothing is specific to DotCloud here: we just uncomment the relevant
lines of code in ``settings.py`` and ``urls.py``.

..

If we push our application now, we can go to the ``/admin`` URL,
but since we didn't call ``syncdb`` yet, the database structure
doesn't exist, and Django will refuse to do anything useful for us.
Automatically Call syncdb

To make sure that the database structure is properly created, we
want to call ``manage.py syncdb`` automatically each time we push
our code. On the first push, this will create the Django tables;
later, it will create new tables that might be required by new
models you will define.

To make that happen, we create a ``postinstall`` script. It is
called automatically at the end of each push operation.

..

A few remarks:

* this is a shell script (hence the ``#!/bin/sh`` shebang at the
  beginning), but you can also use a Python script if you like;
* by default, ``syncdb`` will interactively prompt you to create
  a Django superuser in the database, but we cannot interact with
  the terminal during the push process, so we disable this thanks
  to ``--noinput``.

If you push the code at this point, hitting the ``/admin`` URL
will display the login form, but we don't have a valid user yet,
and the login form won't have the usual Django CSS since we didn't
take care about the static assets yet.
Create Django Superuser

Since the ``syncdb`` command was run non-interactively, it did not
prompt us to create a superuser, and therefore, we don't have a
user to login.

To create an admin user automatically, we will write a simple Python
script that will use Django's environment, load the authentication
models, create a ``User`` object, set a password, and give him
superuser privileges.

The user login will be ``admin``, and its password will be ``password``.
Note that if the user already exists, it won't be touched. However,
if it does not exist, it will be re-created. If you don't like this
``admin`` user, you should not delete it (it would be re-added each
time you push your code) but just remove its privileges and reset its
password, for instance.

..

At this point, if we push the code, we will be able to login, but
we still lack the CSS that will make the admin site look nicer.
Handle Static and Media Assets

We still lack the CSS required to make our admin interface look nice.
We need to do three things here.

First, we will edit ``settings.py`` to specify ``STATIC_ROOT``,
``STATIC_URL``, ``MEDIA_ROOT``, and ``MEDIA_URL``. Note that we
decided to put those files in ``/home/dotcloud/data``. By convention,
the ``data`` directory will persist across pushes. This is important:
while you could store static assets in ``/home/dotcloud/current``
(or one of its subdirectories), you probably don't want to store
media (user uploaded files...) in ``current`` or ``code``, because
those directories are wiped out at each push.

The next step is to instruct Nginx to map ``/static`` and ``/media``
to those directories in ``/home/dotcloud/data``. This is done through
a Nginx configuration snippet. You can do many interesting things
with custom Nginx configuration files; http://docs.dotcloud.com/guides/nginx/
gives some details about that.

The last step is to add the ``collectstatic`` management command to
our ``postinstall`` script. Before calling it, we create the required
directories, just in case.

..

After pushing this last round of modifications, the CSS for the admin
site (and other static assets) will be found correctly, and we have a
very basic (but functional) Django project to build on!
add a few explanations
typo ?
Merge pull request #1 from qpleple/patch-1
Generate the static files in ~/volatile instead of ~/data

With the new "Granite" builder, DotCloud applications are built in the
background while your production application is still running. When the
build is finished the old service is stopped and its "~/data" directory
is migrated to the new service.

This change in the way applications are built means that the "~/data"
directory is only accessible during the initial push of an application.
In subsequent pushes the "~/data" directory is migrated when the build
is over which means that the build can no longer modify the "~/data"
directory.

This commit simply changes the path where static files are generated
(STATIC_ROOT) to the "~/volatile/static" directory.
Merge pull request #2 from dotcloud/master

Pull static files out of ~/data/
added helloapp and made some minor changes and added template dir
added createdb.py
added missing import
added redis caching, logging, and other minor tweaks here and there