Install

This document explains how to install the application, normally on a developer workstation but potentially on a standalone server for testing.

Our standard configuration is to use Gunicorn to serve both the Django application and the static files.

Install the required packages:

  • Python 3.8, venv and pip

  • git

  • binutils, geos, gdal and proj for GeoDjango

  • gcc, python-devel and postgresql-devel for pyscopg2

  • gettext for Django translations

  • libxml2-dev and libxslt1-dev for XML support in the REST API

On a Debian-based system using apt as the package manager (this includes Ubuntu):

sudo apt -y --no-install-recommends install python3-pip python3-venv git binutils gdal-bin libproj-dev gcc libpq-dev python3-dev gettext libxml2-dev libxslt1-dev libgdal-dev libgraphviz-dev latexmk postgresql-client redis-tools texlive-fonts-recommended texlive-latex-extra

Configure the Environment Variables required for setup:

CLIENT=fnt
APP=fdw
ENV=lcl
REPO=git@gitlab.com:/fewsnet/data/$APP.git
BRANCH=master
PYTHON=3.8
BASEDIR=~/git/$APP

Create the application directory and download the source code:

git clone $REPO $BASEDIR
cd $BASEDIR
git checkout -b $BRANCH
git submodule update --init --recursive

Create the virtualenv:

cd $BASEDIR
python3 -m venv --prompt="${CLIENT}${APP}${ENV}" ~/.venvs/${CLIENT}${APP}${ENV}
VENV=${CLIENT}${APP}${ENV}; source ~/.venvs/${VENV}/bin/activate

Install GDAL:

pip install numpy==1.18.5  # Match the version in requirements/base.txt
VERSION=$(gdal-config --version); CFLAGS=$(gdal-config --cflags) pip install GDAL==${VERSION}

Install the application requirements:

pip install -r requirements/local.txt

Configure the Environment Variables required for the application by copying the example file:

cp env.example .env

Edit the .env file in a text editor. Then make it auto activate whenever the virtual env is entered by entering:

cat <<EOF | tee ${VIRTUAL_ENV}/bin/postactivate
# Set environment variables
cd ${BASEDIR}
set -a
source .env
set +a
EOF
cat <<EOF | tee -a ${VIRTUAL_ENV}/bin/activate
. ${VIRTUAL_ENV}/bin/postactivate
EOF

Activate the virtual env:

source ${VIRTUAL_ENV}/bin/activate

Once you have activated the virtual environment you can start the containers:

docker-compose up

Note that this command will take up to 30 minutes the first time you run it, depending on your internet connection.

Creating a Superuser

You will often need to create a superuser account after you have launched the app container, before you can administer the application:

docker-compose run --rm --entrypoint=/bin/bash app

or if that doesn’t work:

docker-compose up app
docker-compose exec app bash

Then:

./manage.py createsuperuser exit

Enable data-explorer (KDE)

The frontend app can be found at /data-explorer and is hosted in a separate repository. If you want to enable it, enter the data-explorer directory:

cd data-explorer

Then install its dependencies:

npm install

The build the app:

npm run build

Alternatively, in a development environment, you can create a version of KDE that builds faster:

npm run build:dev

You can now exit the folder and run KDW with KDE enabled:

cd .. ./manage.py runserver

Running with WSGI

Update the wsgi.py to configure additional environment variables. It would be prefereable to pass these in from the environment using SetEnv in the Apache virtual host directive, but those variables end up in the per-request environment instead of in the persistent environment that the server process is running in. It may be possible to avoid this using Daemon Mode, but that requires further investigation:

sudoedit $APP/wsgi.py
    os.environ.setdefault("EMAIL_HOST", "mail.example.com")
    os.environ.setdefault("EMAIL_HOST_PASSWORD", "password")
    os.environ.setdefault("EMAIL_HOST_USER", "mailuser")
    os.environ.setdefault("PGDATABASE", "fdwdev")
    os.environ.setdefault("PGHOST", "1.2.3.4")
    os.environ.setdefault("PGPASSWORD", "password")
    os.environ.setdefault("PGPORT", "5432")
    os.environ.setdefault("PGUSER", "fdwdev")
    os.environ.setdefault("SECRET_KEY", "acbcdefghijklmnopqrstuvwxyz")

Configure Apache:

cat << EOF | sudo tee /etc/$APACHE/conf.d/django_apps.conf
Alias /robots.txt /var/local/django_apps/$APP/$ENV/static/robots.txt
Alias /favicon.ico /var/local/django_apps/$APP/$ENV/static/favicon.ico

AliasMatch ^/([^/]*\.css) /var/local/django_apps/$APP/$ENV/static/styles/$1

Alias /media/ /var/local/django_apps/$APP/$ENV/media/
Alias /static/ /var/local/django_apps/$APP/$ENV/assets/

<Directory /var/local/django_apps/$APP/$ENV/assets>
    Order deny,allow
    Allow from all
</Directory>

<Directory /var/local/django_apps/$APP/$ENV/media>
    Order deny,allow
    Allow from all
</Directory>

WSGIPythonHome /var/local/django_apps/$APP/$ENV/env
WSGIScriptAlias / /var/local/django_apps/$APP/$ENV/$APP/wsgi.py
WSGIPythonPath /var/local/django_apps/$APP/$ENV:/var/local/django_apps/$APP/$ENV/env/lib/python${PYTHON}/site-packages

<Directory /var/local/django_apps/$APP/$ENV>
    <Files wsgi.py>
        Order deny,allow
        Allow from all
    </Files>
</Directory>
EOF
sudo service $APACHE restart

Troubleshooting

GeoDjango Dependencies

You can check that all the dependencies for GeoDjango are available with:

./manage.py shell

    from django.contrib.gis import gdal
    gdal.HAS_GDAL # should return true

    from django.contrib.gis import geos
    geos.geos_version () # should return > 3.3.2

    # This is not necessarily required
    import pyproj
    pyproj.__version__
    pyproj.test ()