Skip to content

Instantly share code, notes, and snippets.

@jacob414
Forked from shazow/create_project.sh
Created May 16, 2012 20:18
Show Gist options
  • Save jacob414/2713613 to your computer and use it in GitHub Desktop.
Save jacob414/2713613 to your computer and use it in GitHub Desktop.
Setup deployment target for Nginx + Python/uWSGI + Supervisor + Git (for a Linode Stackscript)
#!/bin/bash
# Setup deployment target for Nginx + Python/uWSGI + Supervisor + Git
function usage() {
cat << EOF
Usage: $0 [-y] PROJECT_NAME [DOMAIN]
Options:
-y No prompts, assume yes to all.
Example:
$0 -y foo fooapp.com
EOF
}
while getopts "h:y" OPTION; do
case $OPTION in
h)
usage
exit
;;
y)
NOPROMPT="y"
shift
;;
?)
usage
exit
;;
esac
done
PROJECTNAME="$1"
DOMAIN="$2"
USERNAME="$(whoami)"
if [ "$USERNAME" == "root" ]; then
echo "Error: Must be run as non-root."
exit 2
fi
if [ ! "$PROJECTNAME" ]; then
echo "Error: Must specify a project name."
exit 3;
fi
if [ ! "$DOMAIN" ]; then
DOMAIN="$PROJECTNAME.com"
fi
if [ "$NOPROMPT" != "y" ]; then
echo "This script is intended to be run on a remote server, not on a local development environment. It will create a bunch of directories and change a bunch of configurations, are you sure you want to continue? [y/N] "
read -n1 answer
if [ "$answer" != "y" ]; then
echo "\nAborting."
exit 4
fi
fi
# Setup our directory structure
mkdir ~/{deploy,env,logs,public_html,repo,uploads}
mkdir ~/{repo,deploy,logs,public_html,uploads}/$PROJECTNAME
# Create a detached tree repository
cd ~/repo/$PROJECTNAME
git init --bare
git config core.bare false
git config core.worktree ~/deploy/$PROJECTNAME
git config receive.denycurrentbranch ignore
# Setup post-receive hook to update detached tree on receive
cat > hooks/post-receive << EOF
#!/bin/sh
git checkout -f
UWSGI_PID=/tmp/$PROJECTNAME-uwsgi.pid
if [ -f "\$UWSGI_PID" ]; then
echo "Restarting uwsgi.";
kill -HUP $(cat \$UWSGI_PID);
fi
EOF
chmod +x hooks/post-receive
# Setup static assets to be served by nginx directly
ln -s ~/deploy/$PROJECTNAME/static ~/public_html/$PROJECTNAME/static
# Virtualenv
virtualenv ~/env/$PROJECTNAME
source ~/env/$PROJECTNAME/bin/activate
# Install root config files
## Supervisor
sudo tee /etc/supervisor/conf.d/$PROJECTNAME.conf > /dev/null << EOF
[program:$PROJECTNAME-uwsgi]
directory=/home/$USERNAME/deploy/$PROJECTNAME
user=$USERNAME
command=/usr/bin/uwsgi-python -C -H /home/$USERNAME/env/$PROJECTNAME -L -w wsgi --socket /tmp/$PROJECTNAME-uwsgi.sock --master --processes 1 --pidfile /tmp/$PROJECTNAME-uwsgi.pid
stdout_logfile=/home/$USERNAME/logs/$PROJECTNAME/uwsgi.log
redirect_stderr=true
stopsignal=INT
autorestart=true
EOF
## Nginx
sudo tee /etc/nginx/sites-available/$PROJECTNAME > /dev/null << EOF
server {
listen 80;
server_name $DOMAIN;
access_log /home/$USERNAME/logs/$PROJECTNAME/access.log;
charset utf-8;
gzip on;
gzip_http_version 1.1;
gzip_vary on;
gzip_comp_level 6;
gzip_proxied any;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
gzip_buffers 16 8k;
gzip_disable "MSIE [1-6].(?!.*SV1)";
location ~ ^/(robots.txt|favicon.ico)\$ {
root /home/$USERNAME/public_html/$PROJECTNAME.com/static;
}
location /static {
root /home/$USERNAME/public_html/$PROJECTNAME.com/;
expires max;
add_header Cache-Control "public";
}
location / {
include uwsgi_params;
uwsgi_pass unix:///tmp/$PROJECTNAME-uwsgi.sock;
uwsgi_param SCRIPT_NAME "";
}
}
server {
listen 80;
server_name www.$DOMAIN;
rewrite ^/(.*) http://$DOMAIN/\$1 permanent;
}
EOF
## Enable new Nginx config
sudo ln -sft /etc/nginx/sites-enabled/ "../sites-available/$PROJECTNAME"
# Restart things
sudo /etc/init.d/nginx reload
sudo supervisorctl reload
# Print instructions
IP_ADDRESS="$(ifconfig eth0 | awk -F: '/inet addr:/ {print $2}' | awk '{ print $1 }')"
cat << EOF
Setup your development clone as follows:
git branch live
git remote add -t live live ssh://$USERNAME@$IP_ADDRESS/home/$USERNAME/repo/$PROJECTNAME
Now you can deploy:
git checkout live
git merge master
git checkout master
git push live
Or use this handy 'deploy' alias in your ~/.gitconfig file:
deploy = "!merge(){ git checkout \$2 && git merge \$1 && git push \$2 && git checkout \${1#refs/heads/}; }; merge \$(git symbolic-ref HEAD) \$1"
So you can do (from 'master'):
git deploy live
Happy pushing!
EOF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment