Showing posts with label django. Show all posts
Showing posts with label django. Show all posts

Tuesday, October 8, 2013

An Introduction to Fabric

Fabric is described as a simple, Pythonic tool for application deployment or systems administration tasks. The fab tool simply imports your fabfile (fabfile.py, by default) and executes the function or functions at your disposal. There is no magic about fabric – anything we can do in a Python script can be done in a fabfile. Here is a small but complete fabfile that defines one task:

def hello(name="World"):
    print("Hello %s!" % name)



Calling fab hello will display the familiar message "Hello World!" However, we can personalize it by issuing:

$fab hello:name=Jay

The message shown will be: "Hello Jay!"

Below is another small fabfile that allows us to find kernel release as well as machine hardware of a remote system by using SSH:

from fabric.api import run

def host_type():
    run("uname -srm")


Since there is no remote host defined in the fabfile, we need to specify it (hostname) using option -H:

$fab -H hostname host_type

Fabric provides many command-execution functions, the following five are frequently used:
  • run(command) -- Run a shell command on a remote host.
  • sudo(comand) -- Run (with superuser privileges) a shell command on a remote host.
  • local(command) -- Run a command on the local host.
  • get(remote_path, local_path) -- Download one or more files from a remote host.
  • put(local_path, remote_path) -- Upload one or more files to a remote host.
Fabric also includes context managers for use with the with statement, the following three are commonly used:
  • settings(*args, **kwargs) -- Nest context managers and/or override env variables.
  • lcd(path) -- Update local current working directory.
  • cd(path) -- Update remote current working directory. 
The third sample fabfile allows us to deploy a Django project to three production servers (serv1, serv2 and serv3). In fact, it can be extended to deploy various applications. The deployment consists of the following steps:
  1. testing the project -- python manage.py test apps
  2. packing the project  -- tar czf /tmp/project.tgz .
  3. moving the packed file to server -- put("/tmp/project.tgz", "/path/to/serv/tmp/project.tgz") 
  4. unpacking the file -- run("tar xzf /path/to/serv/tmp/project.tgz"), and 
  5. deploying the project on server -- run("touch manage.py") 
To use it, we issue:
$fab install



from __future__ import with_statement
from fabric.api import *
from fabric.contrib.console import confirm

env.hosts = ['serv1', 'serv2', 'serv3']
env.user= "admin"

def test():
    """
    Run test;  if it fails prompt the user for action.
    """
    src_dir = "/path/to/local/src/directory"
    with settings(warn_only=True), lcd(src_dir):
        result = local("python manage.py test apps", capture=True)
    if result.failed and not confirm("Tests failed. Continue anyway?"):
        abort("Aborting at user request.")

def pack_move():
    """
    Archive our current code and upload to servers.
    """
    src_dir = "/path/to/local/src/directory"   
    with settings(warn_only=True), lcd(src_dir):
        local( "tar czf /tmp/project.tgz .")
    put( "/tmp/project.tgz", "/path/to/serv/tmp/project.tgz" )
    local( "rm /tmp/project.tgz" )

def install():
    """
    Deploy the project on servers.
    """
    test()
    pack_move()
    dst_dir = "/path/to/serv/dst/directory"
    with settings(hide("warnings"), warn_only=True):
        if run("test -d %s" % dst_dir).failed:
            run("mkdir -p %s" % dst_dir)   
    with cd(dst_dir):
        run("tar xzf /path/to/serv/tmp/project.tgz")
        run("touch manage.py")
    run("rm -f /path/to/serv/tmp/project.tgz")

      


Wednesday, April 3, 2013

How to test Django development server remotely?

Django development server is intended only for use while developing. There are times that we need to test Django applications remotely through development server. Thought we may bind the development server to some public IPs to achieve this, it is not a good practice in general for various reasons. Ssh port forwarding provides a much secure way for remote testing of Django development server. Let serv be the server where Django development server resides, test the remote host where you want to conduct the tests. Here is a how-to.

1. On host serv, start your development server:
python manage.py runserver 8080
where 8080 is any port number of your choice.

2. On host test, start ssh port forwarding:
ssh -L 9090:localhost:8080 user@serv
where 9090 is the port number providing remote service.

3. On host test, point your browser to localhost:9090 to perform tests.


If you want to test the development server through other hosts, say  third, you should enable gateway forwarding on host test by issuing:

ssh -g -L 9090:localhost:8080 user@serv

Then you may perform tests through host third by pointing your browser to test:9090.

Tuesday, January 1, 2013

deploying static files and django applications with Nginx

Just learned a trick to serve static files as well as django applications with nginx. In the following setup, nginx tries to serve static files first, if the requested file is not found, then it passes request to the (django) application server (gunicorn, if you wish).


    location / {
        try_files $uri @proxy_to_app;
    }

    location @proxy_to_app {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;

        proxy_pass   http://127.0.0.1:8080;
    }


If we want to enable user-dir mode, the configuration code should be put before these.

deploying django with gunicorn and nginx

Gunicorn is a wsgi HTTP server. As its document says:
it is best to use Gunicorn behind HTTP proxy server.
Nginx is strongly suggested as the proxy server. Here is a quick note for deploying django with nginx and gunicorn.

The nginx server can be configured as follows:

server {
    listen   80; ## listen for ipv4;
    listen   [::]:80 default ipv6only=on; ## listen for ipv6

    server_name your.app.domain.name;

    location /static {
        root /path/to/your/staticfiles;
    }

    location / {

        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    }
}


Start gunicorn to serve your django application. Be sure to bind gunicorn to the port number (8080) specified in the previous configuration file:

gunicorn -b localhost:8080 django_application.wsgi:application


Tuesday, December 25, 2012

hooray

It works!

[django + mezzanine + apache2 + wsgi] on fedora 17 and ubuntu 12.04

how to:
  1. collect static files for mezzanine
    python manage.py collectstatic
  2. put static and template files under the mezzaine application directory
  3. configure mod_wsgi (conf.d/wsgi.conf) for apache2
    there are examples on site of djangoproject:
    https://docs.djangoproject.com/en/1.4/howto/deployment/wsgi/modwsgi/