Archive for the ‘ubuntu’ Category

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

Kernel upgrade on Ubuntu 9.04 running in VMware Fusion

Wednesday, June 24th, 2009

If you’re running Ubuntu 9.04 in VMware Fusion (2.04) you’ve probably come across the following post from VMware:

Ubuntu 9.04 “Jaunty Jackalope” on VMware Fusion 2

If you upgrade the kernel you’ll have to follow the instructions again making sure to do the following as mentioned in one of the comments:

What did work for me was to:

sudo apt-get remove xserver-xorg-input-vmmouse

and then

sudo apt-get install xserver-xorg-input-vmmouse

I then logged out, restarted the Xserver..

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".