Skip to content

Instantly share code, notes, and snippets.

@tomfa tomfa/django-on-heroku.sh
Last active Dec 19, 2015

Embed
What would you like to do?
Django in virtualenv on heroku. Initiates a python virtualenv, installs django and creates a heroku instance where it runs. Run this script from terminal with: sh django-on-heroku.sh
#!/bin/bash
# Requires python, pip, virtualenv
# which can be installed with brew install python
# (See brew.sh for brew installation)
bold=$(tput bold)
normal=$(tput sgr0)
function trueFalseInput {
while true; do
printf "$2 (${bold}y${normal}/n): "
read INPUT
if [ "$INPUT" = "n" ] ; then
printf -v $1 false
break
else
if [ "$INPUT" = "y" ] || [ "$INPUT" = "" ] ; then
printf -v $1 true
break
else
echo "Invalid input."
fi
fi
done
}
function nonEmptyTextInput {
while true; do
printf "$2 (e.g. $3): "
read INPUT
if [ "$INPUT" = "" ] ; then
echo "Invalid input"
else
printf -v $1 true
break
fi
done
}
function textInput {
while true; do
printf "$2 (e.g. $3): "
read INPUT
if [ "$INPUT" = "" ] ; then
echo "Invalid input"
else
printf -v $1 true
break
fi
done
}
trueFalseInput "USE_GIT" "Are you using git"
if [ "$USE_GIT" = true ] ; then
nonEmptyTextInput "GIT_REPO" "git url" "git@github.com:gituser/reponame.git"
trueFalseInput "DEV_BRANCH" "Would you like me to make a dev-branch?"
fi
nonEmptyTextInput "DJANGO_PROJECT_NAME" "Django project name" "myproject"
trueFalseInput "USE_HEROKU" "Are you using heroku"
if [ "$USE_HEROKU" = true ] ; then
trueFalseInput "NEW_HEROKU" "Should I create a new heroku app for you?"
textInput "HEROKU_DOMAINS" "(optional) Domains to be forwarded to heroku" "example.com sub.example.com"
fi
# Ensure we have the necessary requirements
type git >/dev/null 2>&1 || [ "$USE_GIT" = false ] || { echo >&2 "I require git but it's not installed. Please install with 'brew install git' or see https://git-scm.com/book/en/v2/Getting-Started-Installing-Git"; exit 1; }
type python >/dev/null 2>&1 || { echo >&2 "I require python but it's not installed. Please install with 'brew install python' or see https://www.python.org/downloads/"; exit 1; }
type pip >/dev/null 2>&1 || { echo >&2 "I require pip but it's not installed. Please install with 'curl --silent --show-error --retry 5 https://bootstrap.pypa.io/get-pip.py | sudo python'"; exit 1; }
type virtualenv >/dev/null 2>&1 || { echo >&2 "I require virtualenv but it's not installed. Please install with 'pip install virtualenv'"; exit 1; }
type heroku >/dev/null 2>&1 || [ "$USE_HEROKU" = false ] || { echo >&2 "I require heroku but it's not installed. Please install with 'brew install heroku' or see toolbelt.heroku.com."; exit 1; }
type pg_config >/dev/null 2>&1 || [ "$USE_HEROKU" = false ] || { echo >&2 "I require postgres but it's not installed. Please install with 'brew install postgres' or see www.postgresql.org/download/"; exit 1; }
exit 1;
mkdir $DJANGO_PROJECT_NAME
cd $DJANGO_PROJECT_NAME
if [ "$USE_GIT" = true ] ; then
git init
echo "Adding remote repository $GIT_REPO"
git remote add origin $GIT_REPO
fi
virtualenv env # create virtualenv
source env/bin/activate # activate virtualenv
if [ "$USE_HEROKU" = true ] ; then
pip install django-toolbelt
else
pip install Django
pip install dj-database-url==0.3.0
pip install dj-static==0.0.6
fi
django-admin startproject $DJANGO_PROJECT_NAME .
# Add django config
echo "Creating django settings"
cat <<EOF >> $DJANGO_PROJECT_NAME/settings.py
# AUTO-GENERATED CONFIG
# Parse database configuration from $DATABASE_URL
import dj_database_url
DATABASES['default'] = dj_database_url.config()
# Honor the 'X-Forwarded-Proto' header for request.is_secure()
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
# Allow all host headers
ALLOWED_HOSTS = ['*']
# Static asset configuration
import os
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
STATIC_ROOT = 'staticfiles'
STATIC_URL = '/static/'
DEBUG = False
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'verbose': {
'format': ('%(asctime)s [%(process)d] [%(levelname)s] ' +
'pathname=%(pathname)s lineno=%(lineno)s ' +
'funcname=%(funcName)s %(message)s'),
'datefmt': '%Y-%m-%d %H:%M:%S'
},
'simple': {
'format': '%(levelname)s %(message)s'
}
},
'handlers': {
'null': {
'level': 'DEBUG',
'class': 'logging.NullHandler',
},
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'verbose'
}
},
'loggers': {
'testlogger': {
'handlers': ['console'],
'level': 'INFO',
}
}
}
EOF
mkdir $DJANGO_PROJECT_NAME/settings
mv $DJANGO_PROJECT_NAME/settings.py $DJANGO_PROJECT_NAME/settings/base.py
cat <<EOF >> $DJANGO_PROJECT_NAME/settings/example_local.py
"""
Local settings. Copy this file to local.py to enable local settings.
"""
import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
DEBUG = True
ALLOWED_HOSTS = ['*']
# Database
# https://docs.djangoproject.com/en/1.8/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
EOF
cp $DJANGO_PROJECT_NAME/settings/example_local.py $DJANGO_PROJECT_NAME/settings/local.py
cat <<EOF >> $DJANGO_PROJECT_NAME/settings/__init__.py
from $DJANGO_PROJECT_NAME.settings.base import *
import os
dir = os.path.dirname(__file__)
filename = os.path.join(dir, 'local.py')
if os.path.exists(filename):
from $DJANGO_PROJECT_NAME.settings.local import *
else:
print("Not using localsettings, $DJANGO_PROJECT_NAME.settings.local could not be found. Continuing with default settings")
EOF
cp $DJANGO_PROJECT_NAME/settings/local_example.py $DJANGO_PROJECT_NAME/settings/local.py
if [ "$USE_HEROKU" = true ] ; then
# Create procfile for gunicorn (heroku)
echo "Creating Procfile"
cat > Procfile << EOF
web: gunicorn $DJANGO_PROJECT_NAME.wsgi --log-file -
EOF
# Set up application for heroku
echo "Creating wsgi file"
cat > $DJANGO_PROJECT_NAME/wsgi.py << EOF
import os
from django.core.wsgi import get_wsgi_application
from dj_static import Cling
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "$DJANGO_PROJECT_NAME.settings")
application = Cling(get_wsgi_application())
EOF
fi
pip freeze > requirements.txt # Export pip requirements to file
if [ "$USE_GIT" = true ] ; then
# Ignore certain files from being added to git
cat > .gitignore << EOF
env
*.py[cod]
.DS_Store
staticfiles
.idea
local.py
EOF
git init
echo "Adding remote repository $GIT_REPO"
git remote add origin $GIT_REPO
git add .
git commit -m "Autogenerated app $DJANGO_PROJECT_NAME"
git
if [ "$DEV_BRANCH" = true ] ; then
git checkout -b dev
fi
fi
if [ "$USE_HEROKU" = true ] ; then
if [ "$NEW_HEROKU" = true ] ; then
echo "Spinning up a new heroku"
heroku create
git push heroku master
heroku ps:scale web=1
if ! [ "$HEROKU_DOMAINS" = "" ] ; then
heroku domains:add $HEROKU_DOMAINS
fi
else
echo "-----------------------------------------------"
echo " This app can now be published to heroku with:"
echo " > cd $DJANGO_PROJECT_NAME"
echo " > heroku create"
echo " > git push heroku master"
echo " > heroku ps:scale web=1 "
echo "-----------------------------------------------"
fi
fi
if [ "$USE_GIT" = true ] ; then
echo "-----------------------------------------------"
echo " Create your empty repository if you haven't, "
echo " e.g. at https://github.com/new"
echo " and push with"
echo " > cd $DJANGO_PROJECT_NAME"
echo " > git push -u"
echo "-----------------------------------------------"
if [ "$USE_HEROKU" = true ]; then
echo "-----------------------------------------------"
echo " Automatic deploy from github to heroku can be"
echo " configured from https://dashboard.heroku.com/"
echo " > app > deploy > github"
echo "-----------------------------------------------"
fi
fi
@tomfa

This comment has been minimized.

Copy link
Owner Author

tomfa commented Dec 19, 2015

See instead the herango-bash-repo for a more stable and complete version

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.