#!/bin/bash source /opt/app-root/etc/generate_container_user set -e function is_gunicorn_installed() { hash gunicorn &>/dev/null } function is_django_installed() { python -c "import django" &>/dev/null } function should_migrate() { is_django_installed && [[ -z "$DISABLE_MIGRATE" ]] } # Guess the number of workers according to the number of cores function get_default_web_concurrency() { limit_vars=$(cgroup-limits) local $limit_vars if [ -z "${NUMBER_OF_CORES:-}" ]; then echo 1 return fi local max=$((NUMBER_OF_CORES*2)) # Require at least 43 MiB and additional 10 MiB for every worker local default=$(((${MEMORY_LIMIT_IN_BYTES:-MAX_MEMORY_LIMIT_IN_BYTES}/1024/1024 - 43) / 10)) default=$((default > max ? max : default)) default=$((default < 1 ? 1 : default)) echo $default } app_script_check="${APP_SCRIPT-}" APP_SCRIPT="${APP_SCRIPT:-app.sh}" if [[ -f "$APP_SCRIPT" ]]; then echo "---> Running application from script ($APP_SCRIPT) ..." if [[ "$APP_SCRIPT" != /* ]]; then APP_SCRIPT="./$APP_SCRIPT" fi exec "$APP_SCRIPT" else test -n "$app_script_check" && (>&2 echo "ERROR: file '$app_script_check' not found.") && exit 1 fi app_file_check="${APP_FILE-}" APP_FILE="${APP_FILE:-app.py}" if [[ -f "$APP_FILE" ]]; then echo "---> Running application from Python script ($APP_FILE) ..." exec python "$APP_FILE" else test -n "$app_file_check" && (>&2 echo "ERROR: file '$app_file_check' not found.") && exit 1 fi APP_HOME=${APP_HOME:-.} # Look for 'manage.py' in the directory specified by APP_HOME, or the current direcotry manage_file=$APP_HOME/manage.py if should_migrate; then if [[ -f "$manage_file" ]]; then echo "---> Migrating database ..." python "$manage_file" migrate --noinput else echo "WARNING: seems that you're using Django, but we could not find a 'manage.py' file." echo "Skipped 'python manage.py migrate'." fi fi if is_gunicorn_installed; then if [[ -z "$APP_MODULE" ]]; then # Look only in the directory specified by APP_HOME, or the current directory # replace all "/" with ".", remove leading "." and ".py" suffix APP_MODULE=$(find $APP_HOME -maxdepth 1 -type f -name 'wsgi.py' | sed 's:/:.:g;s:^\.\+::;s:\.py$::') fi if [[ -z "$APP_MODULE" && -f setup.py ]]; then APP_MODULE="$(python setup.py --name)" fi if [[ "$APP_MODULE" ]]; then export WEB_CONCURRENCY=${WEB_CONCURRENCY:-$(get_default_web_concurrency)} echo "---> Serving application with gunicorn ($APP_MODULE) ..." exec gunicorn "$APP_MODULE" --bind=0.0.0.0:8080 --access-logfile=- --config "$APP_CONFIG" fi fi if is_django_installed; then if [[ -f "$manage_file" ]]; then echo "---> Serving application with 'manage.py runserver' ..." echo "WARNING: this is NOT a recommended way to run you application in production!" echo "Consider using gunicorn or some other production web server." exec python "$manage_file" runserver 0.0.0.0:8080 else echo "WARNING: seems that you're using Django, but we could not find a 'manage.py' file." echo "Skipped 'python manage.py runserver'." fi fi >&2 echo "ERROR: don't know how to run your application." >&2 echo "Please set either APP_MODULE, APP_FILE or APP_SCRIPT environment variables, or create a file 'app.py' to launch your application." exit 1