Posts Tagged ‘ubuntu’

Ubuntu 8.04 Server LTS – Django + Nginx + Apache/mod_wsgi

Friday, August 14th, 2009

Based on:

Assumptions

  1. Logged in as root locally.
  2. Network interface has been configured.

Steps

  1. Update your apt-get sources

    apt-get upgrade

  2. Add some accounts (using bob as my own account):

    useradd django
    mkdir /home/django
    chown django:django /home/django
    useradd bob
    mdkir /home/bob
    chown bob:bob /home/bob
    passwd bob

  3. Change the default shell:

    chsh root -s /bin/bash
    chsh bob -s /bin/bash
    chsh django -s /bin/bash

  4. passwd bob
    passwd django

  5. Add root permission to bob by adding the account to the admin group.

    usermod -a -Gadmin bob

  6. Try logging in as bob:

    su bob

  7. If OpenSSH is not installed then visit this page about setting it up.

    sudo apt-get install openssh-server
    sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.original
    sudo chmod a-w /etc/ssh/sshd_config.original

    Check if ssh is running:

    ps -ef | grep sshd

    If not try:

    /etc/init.d/ssh start

    If you’re getting a ‘Connection refused’ message, check that the /etc/hosts file is set correctly particularly if you changed to a static address by changing /etc/network/interfaces. If there is nothing wrong there double check any firewall settings.

  8. We’ll be restricting ssh to bob only, so create a special sshers group:

    sudo groupadd sshers
    sudo usermod -a -Gsshers bob

  9. Time to configure ssh:
    Make these changes to /etc/ssh/sshd_config

    #Port 22
    Port XXXX (pick a port number)

    #PermitRootLogin yes
    PermitRootLogin no

    #X11 Forwarding yes
    X11 Forwarding no

    Add these if not found

    MaxAuthTries 6
    UseDNS no
    AllowGroups sshers

    And restart the ssh service:

    sudo /etc/init.d/ssh restart

    Check that you can login:

    ssh bob@xxx.xxx.xxx.xxx -p XXXX

    If it works you can disable the root password:

    sudo passwd -l root

  10. Next install Postgres (might need to install gcc and make as well):

    sudo apt-get install postgresql-8.3 postgresql-server-dev-8.3

    Change the password for the postgresuser:

    sudo -u postgres psql template1

    You’ll get the psql prompt and then just type:

    • ALTER USER postgres WITH PASSWORD ‘somePassword‘;
    • \q
  11. The config file for Postgres also needs to be modified:

    sudo vi /etc/postgresql/8.3/main/pg_hba.conf

    The end of the file should changed to look like:

    # Database administrative login by UNIX sockets
    local all postgres ident sameuser
    # TYPE DATABASE USER CIDR-ADDRESS METHOD
    # “local” is for Unix domain socket connections only
    local all all password
    # IPv4 local connections:
    #host all all 127.0.0.1/32 md5
    # IPv6 local connections:
    #host all all ::1/128 md5

    Next, just restart Postgres:

    sudo /etc/init.d/postgresql-8.3 restart

  12. Nginx will serve static content and proxy requests to Apache2. We’ll need to install the latest stable version.

    sudo aptitude -y install libpcre3 libpcre3-dev libpcrecpp0 libssl-dev zlib1g-dev
    mkdir ~/sources
    cd ~/sources/
    wget http://sysoev.ru/nginx/nginx-0.7.61.tar.gz
    tar -zxvf nginx-0.7.61.tar.gz
    cd nginx-0.7.61
    ./configure --sbin-path=/usr/local/sbin --with-http_ssl_module
    make
    sudo make install

    Start Nginx

    sudo /usr/local/sbin/nginx

    Try viewing it on a browser.
    Stop it and create an init script

    sudo kill `cat /usr/local/nginx/logs/nginx.pid`
    sudo vi /etc/init.d/nginx

    #! /bin/sh

    ### BEGIN INIT INFO
    # Provides: nginx
    # Required-Start: $all
    # Required-Stop: $all
    # Default-Start: 2 3 4 5
    # Default-Stop: 0 1 6
    # Short-Description: starts the nginx web server
    # Description: starts nginx using start-stop-daemon
    ### END INIT INFO

    PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

    DAEMON=/usr/local/sbin/nginx
    NAME=nginx
    DESC=nginx

    test -x $DAEMON || exit 0

    # Include nginx defaults if available
    if [ -f /etc/default/nginx ] ; then
    . /etc/default/nginx
    fi

    set -e

    case "$1" in
    start)
    echo -n "Starting $DESC: "
    start-stop-daemon --start --quiet --pidfile /usr/local/nginx/logs/$NAME.pid \
    --exec $DAEMON -- $DAEMON_OPTS
    echo "$NAME."
    ;;
    stop)
    echo -n "Stopping $DESC: "
    start-stop-daemon --stop --quiet --pidfile /usr/local/nginx/logs/$NAME.pid \
    --exec $DAEMON
    echo "$NAME."
    ;;

    restart|force-reload)
    echo -n "Restarting $DESC: "
    start-stop-daemon --stop --quiet --pidfile \
    /usr/local/nginx/logs/$NAME.pid --exec $DAEMON
    sleep 1
    start-stop-daemon --start --quiet --pidfile \
    /usr/local/nginx/logs/$NAME.pid --exec $DAEMON -- $DAEMON_OPTS
    echo "$NAME."
    ;;
    reload)
    echo -n "Reloading $DESC configuration: "
    start-stop-daemon --stop --signal HUP --quiet --pidfile /usr/local/nginx/logs/$NAME.pid \
    --exec $DAEMON
    echo "$NAME."
    ;;
    *)
    N=/etc/init.d/$NAME
    echo "Usage: $N {start|stop|restart|reload|force-reload}" >&2
    exit 1
    ;;
    esac

    exit 0

    sudo chmod +x /etc/init.d/nginx

    Add it to the default run levels:

    sudo /usr/sbin/update-rc.d -f nginx defaults

    Create folder layout:

    sudo mkdir /usr/local/nginx/sites-available
    sudo mkdir /usr/local/nginx/sites-enabled

    Change the nginx.conf file:

    sudo vi /usr/local/nginx/conf/nginx.conf

    to:

    user www-data www-data;
    worker_processes 4;

    events {
    worker_connections 1024;
    }

    http {
    include mime.types;
    default_type application/octet-stream;

    sendfile on;
    tcp_nopush on;
    tcp_nodelay off;
    keepalive_timeout 5;

    gzip on;
    gzip_comp_level 2;
    gzip_proxied any;
    gzip_types text/plain text/html text/css application/x-javascript text/xml application/xml
    application/xml+rss text/javascript;

    include /usr/local/nginx/sites-enabled/*;
    }

    Next add a proxy.conf file:

    sudo vi /usr/local/nginx/conf/proxy.conf

    # proxy.conf
    proxy_redirect off;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    client_max_body_size 10m;
    client_body_buffer_size 128k;
    proxy_connect_timeout 90;
    proxy_send_timeout 90;
    proxy_read_timeout 90;
    proxy_buffers 32 4k;

    And start Ngninx:

    sudo /etc/init.d/nginx start

  13. Get files for Apache2:

    sudo apt-get install apache2 libapache2-mod-wsgi

    Modify ports.conf

    sudo vi /etc/apache2/ports.conf

    with

    NameVirtualHost 127.0.0.1:80
    Listen 127.0.0.1:80

    Need to modify apache2.conf

    sudo vi /etc/apache2/apache2.conf

    Change KeepAlive to:

    # KeepAlive On
    KeepAlive Off

    Then restart:

    sudo apache2ctl restart

  14. Create a virtual host file for your site with nginx:

    sudo vi /usr/local/nginx/sites-available/example.com

    and add the following where 255.255.255.255:80 should be replaced with the correct IP:

    server {
    listen 255.255.255.255:80;
    server_name www.example.com;
    rewrite ^/(.*) http://example.com/$1 permanent;
    }
    server {
    listen 255.255.255.255:80;
    server_name www.example.com example.com;

    access_log /home/django/domains/example.com/log/access.log;
    error_log /home/django/domains/example.com/log/error.log;

    location / {
    proxy_pass http://127.0.0.1:80/;
    include /usr/local/nginx/conf/proxy.conf;
    }

    location /media/ {
    root /home/django/domains/example.com/public/;
    expires 1d;
    }
    }

    sudo ln -s /usr/local/nginx/sites-available/example.com /usr/local/nginx/sites-enabled/example.com

  15. Add some django folders:

    sudo usermod -a -G www-data django
    sudo usermod -a -G www-data bob
    su django
    mkdir domains
    chgrp -R www-data /home/django/domains
    chmod -R 2750 /home/django/domains
    mkdir .python-eggs
    chown django:www-data .python-eggs
    chmod g+w .python-eggs/
    cd /home/django/domains
    mkdir example.com
    mkdir -p example.com/{public,log}
    mkdir example.com/public/media
    chown -R django:www-data example.com
    exit
    sudo rm /etc/apache2/sites-enabled/000-default
    sudo rm /usr/local/nginx/sites-enabled/default
    sudo /etc/init.d/nginx stop
    sudo /etc/init.d/nginx start
    sudo apache2ctl graceful

  16. Install some general libraries

    sudo apt-get install mercurial git-core curl
    sudo apt-get install build-essential python-dev python-setuptools python-psycopg2

    sudo easy_install pip
    sudo pip install virtualenv
    sudo pip install virtualenvwrapper
    su django
    cd
    mkdir virtualenv
    chgrp -R www-data virtualenv
    vi .bashrc
    “export WORKON_HOME=$HOME/virtualenv
    source /usr/bin/virtualenvwrapper_bashrc”
    source .bashrc
    cd
    virtualenv –no-site-packages –unzip-setuptools envName

  17. Create a pip installation file e.g. ‘envName_env.txt‘:

    #Django
    Django>=1.1

    #PIL
    http://effbot.org/downloads/Imaging-1.1.6.tar.gz

    # egenix-mx-base
    # Caused an error with pip: "--single-version-externally-managed"
    #http://downloads.egenix.com/python/egenix-mx-base-3.1.2.tar.gz

    # psycopg2
    http://initd.org/pub/software/psycopg/psycopg2-2.0.12.tar.gz

    pip -E envName install -r envName_env.txt
    ./envName/bin/easy_install egenix-mx-base

  18. Create a Django project (virtualenvwrapper might be useful here):

    /home/django/virtualenv/envName/bin/python /home/django/virtualenv/envName/bin/django-admin.py startproject myProject

  19. Link admin/media with public/media/admin and change settings.py

    ln -s /home/django/virtualenv/envName/lib/python2.5/site-packages/django/contrib/admin/media /home/django/domains/example.com/public/media/admin

    Then update the ADMIN_MEDIA_PREFIX setting in your myProject/settings.py file :

    vi /home/django/domains/example.com/myProject/settings.py

    It should look like:

    #ADMIN_MEDIA_PREFIX = ‘/media/’
    ADMIN_MEDIA_PREFIX = ‘/media/admin/’

  20. Create a database:

    sudo su postgres
    createuser -P pg_substanceis
    # should not be a superuser
    # should not be able to create databases
    # should not be able to create more new roles
    createdb –encoding=UNICODE db_example -O pg_example
    exit

    vi /home/django/domains/example.com/myProject/settings.py

    and add in the details:

    DATABASE_ENGINE = ‘postgresql_psycopg2′
    DATABASE_NAME = ‘db_example’
    DATABASE_USER = ‘pg_example’
    DATABASE_PASSWORD = ‘123456789′
    DATABASE_HOST = ”
    DATABASE_PORT = ”

    Then just sync the database to check these settings:

    ~/domains/virtualenv/envName/bin/python myProject/manage.py syncdb

  21. Create a wsgi file for the project:

    sudo vi /home/django/domains/example.com/myProject/myProject.wsgi

    And add the following:

    ALLDIRS = ['/home/django/virtualenv/envName/lib/python2.5/site-packages']
    # note that the above directory depends on the locale of your virtualenv,
    # and will thus be *different for each project!*
    import os
    import sys
    import site

    prev_sys_path = list(sys.path)

    for directory in ALLDIRS:
    site.addsitedir(directory)

    new_sys_path = []
    for item in list(sys.path):
    if item not in prev_sys_path:
    new_sys_path.append(item)
    sys.path.remove(item)
    sys.path[:0] = new_sys_path

    # this will also be different for each project!
    sys.path.append('/home/django/domains/example.com/myProject/')

    os.environ['PYTHON_EGG_CACHE'] = '/home/django/.python-eggs'
    os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
    import django.core.handlers.wsgi
    application = django.core.handlers.wsgi.WSGIHandler()

  22. Create a VirtualHost file for Apache:

    sudo vi /etc/apache2/sites-available/example.com

    Add the VirtualHost definition:


    ServerName www.example.com
    ServerAlias example.com


    Order deny,allow
    Allow from all

    LogLevel warn
    ErrorLog /home/django/domains/example.com/log/apache_error.log
    CustomLog /home/django/domains/example.com/log/apache_access.log combined

    WSGIDaemonProcess example.com user=www-data group=www-data threads=25
    WSGIProcessGroup example.com
    WSGIScriptAlias / /home/django/domains/example.com/myProject/myProject.wsgi

    Then just enable it and restart Apache2 – you should see the Django debug screen:

    sudo ln -s /etc/apache2/sites-available/example.com /etc/apache2/sites-enabled/example.com
    sudo apache2ctl graceful

  23. Some security: take a look at some StricterDefaults. By default /dev/shm is mouted read/write but on servers it should be read only as some exploits may use it. Edit the /etc/fstab file to include the following:

    sudo vi /etc/fstab

    tmpfs /dev/shm tmpfs defaults,ro 0 0

Install git on Ubuntu 9.04 (Jaunty)

Monday, June 22nd, 2009

Installing git using

sudo apt-get install git

I noticed that it was only version 1.6.04.

So thanks to Peter Vandenabeele for posting how he installed git – I had to make a few adjustments:

$ sudo apt-get build-dep git-core git-doc libssl-dev
$ wget http://kernel.org/pub/software/scm/git/git-1.6.3.3.tar.gz
$ tar -xvzf git-1.6.3.3.tar.gz
$ cd git-1.6.3.3/
$ make prefix=/usr all doc
$ sudo make prefix=/usr install install-doc
$ git --version
git version 1.6.3.3

I used "prefix=/usr" because version 1.6.0.4 wasn't removed after I did a "sudo apt-get remove git".