Skip to content

Instantly share code, notes, and snippets.

@simkimsia
Last active August 29, 2015 14:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save simkimsia/bc76eb9496ec22c9da43 to your computer and use it in GitHub Desktop.
Save simkimsia/bc76eb9496ec22c9da43 to your computer and use it in GitHub Desktop.
Even better installation script for server that will support the django application, the front end and the database for different python environment
#!/bin/bash
###
#
# forked from https://gist.github.com/1264701/08f93534ba177f173b9382b53c419cd0de5b07ea
#
# Ubuntu 14.04 based web server installation script
# Run this by executing the following from a fresh install of Ubuntu 14.04 server:
#
# bash -c "$(curl -fsSL https://gist.githubusercontent.com/simkimsia/41c55e0c08eda42e2cb3/raw/2c87d853643df5942d00ae9ebe87f8cbe1ac39e3/install.sh)" <mysqlPassword>
#
# Be sure to replace <mysqlPassword> with your intended MySQL Password.
# Also, run this as root, unless you enjoy failing.
#
# Its handy to install 'screen' if you want to ensure your remote connection to
# a server doesn't disrupt the installation process. If you want to do this, just
# do the following before running the main bash command:
#
# apt-get install screen -y
# screen
#
# To recover your session if you are disconnected, ssh to your server as root again,
# and type:
#
# screen -x
#
# Dependencies:
# - curl
#
# Todo:
# - SSL Configuration
#
###
EXPECTEDARGS=0
if [ $# -ne $EXPECTEDARGS -o "x$0" == "x" -o $0 == "bash" ]; then
echo "Usage:"
echo " Parameter 1: MySQL root password"
exit 1
fi
MYSQLPASS=$0
export DEBIAN_FRONTEND=noninteractive
########################################
## System Updates
########################################
apt-get update -y
apt-get install \
curl \
aptitude \
-y
apt-get upgrade --force-yes -y
########################################
## Tools and Utilities
########################################
apt-get install git-core --force-yes -y
apt-get install xclip --force-yes -y
apt-get install unzip --force-yes -y
########################################
## MySQL
########################################
apt-get install \
mysql-client \
mysql-server \
--force-yes -y
mysqladmin -u root password $MYSQLPASS
########################################
## PostgreSQL
########################################
sh -c "echo 'deb http://apt.postgresql.org/pub/repos/apt/ precise-pgdg main' > /etc/apt/sources.list.d/pgdg.list"
wget --quiet -O - http://apt.postgresql.org/pub/repos/apt/ACCC4CF8.asc | apt-key add -
apt-get update -y
apt-get install \
postgresql-common \
postgresql-9.3 \
libpq-dev \
--force-yes -y
########################################
## pip
########################################
apt-get install python-virtualenv --force-yes -y ## for virtualenv
apt-get install python3-setuptools --force-yes -y ## for python3
apt-get install python-setuptools --force-yes -y ## for python2.7 or above
apt-get install python-dev --force-yes -y ## because ubuntu 14.04 does not have dev version of python 2
apt-get install python3-dev --force-yes -y ## because ubuntu 14.04 does not have dev version of python 3.4
apt-get install links --force-yes -y ##a command line web browser
apt-get install python-flup --force-yes -y ## connects python to uwsgi)
apt-get install build-essential --force-yes -y ##
########################################
## Nginx
########################################
apt-get install \
nginx \
--force-yes -y
## Common Configuration
read -r -d '' FILECONTENT <<'ENDFILECONTENT'
index index.html;
location ~ /\.ht {
deny all;
}
ENDFILECONTENT
echo "$FILECONTENT" > /etc/nginx/common.conf
## FastCGI Configuration
read -r -d '' FILECONTENT <<'ENDFILECONTENT'
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
fastcgi_param HTTPS $ssl_session_id;
fastcgi_index index.php;
# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param REDIRECT_STATUS 200;
fastcgi_connect_timeout 60;
fastcgi_read_timeout 180;
fastcgi_send_timeout 180;
fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
fastcgi_intercept_errors on;
ENDFILECONTENT
echo "$FILECONTENT" > /etc/nginx/fastcgi_params
## Nginx Main Configuration
read -r -d '' FILECONTENT <<'ENDFILECONTENT'
user www-data;
worker_processes 4;
pid /var/run/nginx.pid;
events {
worker_connections 768;
}
http {
sendfile off; #sendfile deliberately turn off
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 2;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
gzip_disable "msie6";
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
ENDFILECONTENT
echo "$FILECONTENT" > /etc/nginx/nginx.conf
## PHP Configuration
read -r -d '' FILECONTENT <<'ENDFILECONTENT'
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
}
index index.php;
ENDFILECONTENT
echo "$FILECONTENT" > /etc/nginx/php.conf
## Default Site Configuration
read -r -d '' FILECONTENT <<'ENDFILECONTENT'
server {
listen 80; ## listen for ipv4; this line is default and implied
root /usr/share/nginx/www;
index index.html index.htm;
server_name localhost;
location / {
try_files $uri $uri/ /index.html;
}
location /doc {
root /usr/share;
autoindex on;
allow 127.0.0.1;
deny all;
}
location /images {
root /usr/share;
autoindex off;
}
}
ENDFILECONTENT
echo "$FILECONTENT" > /etc/nginx/sites-available/default
/etc/init.d/nginx restart
########################################
## Remove any unwanted packages
########################################
apt-get autoremove --force-yes -y
In order to support such a system; you will need to install the following:
1. Database server(s) that you would like to support. As this is a single purpose server, you will also need to install database command line clients. See
2. Source code tools (git, etc.)
3. A global process manager (like supervisor or circus).
4. Base Python versions you intend to support; and their development headers (sudo apt-get install python-dev)
setuptools, pip, and then virtualenv. These tools should be installed from source rather than your package manager; to ensure the latest versions are installed. You should install these globally (ie, as root) so they are available for all users.
A build tool chain (ie, "Development Tools" or build-essential)
Support libraries for any extensions (but not the extensions themselves). The easiest way to do this is to use the package manager to build the dependencies and not the packages sudo apt-get build-dep python-imaging psycopg2 python-mysqldb.
The next thing you need to do is decide how you will run your application servers (the "django code"). You can use uwsgi, gunicorn, etc. as these are the ones most tested with django.
You need to be able to support multiple versions of these runtimes, so instead of installing them globally across the system; just build their dependencies and install the specific version required for each application in its own isolated environment.
The next thing you need to install is a front end proxy for your applications. You can install whatever proxy suits your needs (nginx is the most popular); but please install from source rather than the packages as those are almost always out of date.
Once all this is setup, the process of hosting a django application is the following:
Create a separate user account with a non-login shell.
Create a virtual environment in this user's home directory. I recommend keeping some standard here, like env for the virtual environments.
Download/copy the source code of your application.
Create a standard directory where you will store the static files. For example I use $HOME/www/static.
Create an entry in your process manager.
Create an entry in your proxy for front end routing.
Reload your proxy server.
Reload your process manager.
You can automate/script a lot of the above. For example, you can create a custom skeleton directory to create the base directories for you when adding new users; and you can create custom templates for other areas using tools like cookiecutter.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment