Blob Blame History Raw
#!/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 40 MiB for every worker
  local default=$(((${MEMORY_LIMIT_IN_BYTES:-MAX_MEMORY_LIMIT_IN_BYTES}/1024/1024 - 43) / 40))
  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