viernes, 20 de marzo de 2015

Mac: Django con Apache

El problema

Lograr que un proyecto django pueda ser servido por apache.

Fue un poco difícil encontrar información precisa al respecto. Aquí trato de indicar los pasos que seguí. Ojalá te sirva de ayuda.

Escenario

  • Mac con OSX 10.10.1 (Yosemite)
  • Apache 2.4.9
  • Proyecto hecho con Django 1.7.3
    • mydjango_site
      • env
      • mydjango_project
        • manage.py
        • mydjango
          • static
          • views.py
        • project
          • settings.py
          • urls.py
          • wsgi.py

Idea

  • Puedo correr el proyecto django con su servidor incorporado:
    • $ cd mydjango_site
    • $ source env/bin/activate
    • $ cd mydjango_project
    • $ python manage.py runserver
  • Quiero que corra bajo apache
    • mod_wsgi permite que apache ejecute el proyecto

Pasos

instalar mod_wsgi

  • $ brew tap homebrew/apache
  • $ brew install mod_wsgi
  • $ sudo vim /etc/apache2/httpd.conf
    • Ubico la sección de carga de módulos y agrego:

      LoadModule wsgi_module /usr/local/Cellar/mod_wsgi/4.4.9/libexec/mod_wsgi.so

wsgi del proyecto

  • $ cd mydjango_project/project
  • $ vim wsgi.pi:

    import sys, os
    BASE_DIR = os.path.dirname(os.path.dirname(__file__))
    
    sys.path.append(BASE_DIR + "mydjango_project/project")
    sys.path.append(BASE_DIR + "env/lib/python2.7/site-packages")
    
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings")
    
    from django.core.wsgi import get_wsgi_application
    application = get_wsgi_application()
    
    
  • Las líneas resaltadas son un seteo de path que no viene por default. Son necesarias para proveer a mod_wsgi el path de los módulos python que necesita.

hosts

  • $ sudo vim /etc/hosts:

    127.0.0.1 mydjangosite.dev
    
    
  • Esto es para que la solicitud de acceso a ese hosts sea atendida por el localhost

virtualhost

  • La configuración del virtualhost permite la solicitud de acceso a cierto host sea servida con el contenido web de cierto directorio. Normalmente se sirve contenido estático. Con mod_php se suele servir contenido php sin hacer mayor configuración en esta parte. Sin embargo, con mod_wsgi es necesario hacer algunas indicaciones al respecto en la configuración de cada virtualhost que lo use. 
  • En /etc/apache2/httpd.conf, tengo esta línea:
    Include /private/etc/apache2/extra/httpd-vhosts.conf
  • $ cd /etc(apache2/extra (/private/etc y /etc parecen ser el mismo directorio)
  • En httpd-vhosts.conf tengo estas líneas:

    include /private/etc/apache2/extra/vhosts/localhost.conf
    include /private/etc/apache2/extra/vhosts/mydjangosite.dev.conf
    
    
  • $ cd vhosts
  • En mydjangosite.dev.conf:

    <VirtualHost *:80>
        LogLevel info
    
        ServerName mydjangosite.dev
        ServerAdmin akobashikawa@gmail.com
        
        ErrorLog "/Users/akobashikawa/Sites/logs/mydjangosite.dev-error_log"
        CustomLog "/Users/akobashikawa/Sites/logs/mydjangosite.dev-access_log" common
    
        # Static files
        DocumentRoot "/Users/akobashikawa/Sites/django/mydjango_site/mydjango"
        Alias /static/ /Users/akobashikawa/Sites/django/mydjango_site/mydjango_project/mydjango/static/
    
        <Directory "/Users/akobashikawa/Sites/django/mydjango_site/mydjango_project/mydjango/static">
            Require all granted
        </Directory>
    
        # WSGI configuration
    
        WSGIDaemonProcess mydjangosite.dev python-path=/Users/akobashikawa/Sites/django/mydjango_site/mydjango_project/project:/Users/akobashikawa/Sites/django/mydjango_site/env/lib/python2.7/site-packages
    
        WSGIProcessGroup mydjangosite.dev
        
        WSGIScriptAlias / /Users/akobashikawa/Sites/django/mydjango_site/mydjango_project/project/wsgi.py
    
        <Directory "/Users/akobashikawa/Sites/django/mydjango_site/mydjango_project/project">
            <Files wsgi.py>
                Require all granted
            </Files>
        </Directory>
        
    </VirtualHost>
    
    • Hasta que este archivo de configuración no estuvo correctamente seteado, obtuve errores (podía ver el log en /Users/akobashikawa/Sites/logs/mydjangosite.dev-error_log). Me ayudó mucho http://stackoverflow.com/a/22477904.
      • Un error que tenía era usar Order allow, deny (la notación antigua); en la notación nueva es Require all granted.
      • Otro error era que el wsgi.py que viene por default no tenía los seteos de path que mod_wsgi requiere.
  • $ sudo apachectl config test
  • $ sudo apachectl start
  • Acceder a http://mydjangosite.dev

Referencias