Skip to content

Instantly share code, notes, and snippets.

@tomfa
Last active December 19, 2015 23:50
Show Gist options
  • Save tomfa/860130912711b9852ae5 to your computer and use it in GitHub Desktop.
Save tomfa/860130912711b9852ae5 to your computer and use it in GitHub Desktop.
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" "[email protected]: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
Copy link
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