diff --git a/.gitignore b/.gitignore
index b903977..0fcf136 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,13 +1,10 @@
-
+.idea/
.DS_Store
-
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
-
# C extensions
*.so
-
# Distribution / packaging
.Python
env/
@@ -25,17 +22,14 @@ var/
*.egg-info/
.installed.cfg
*.egg
-
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
-
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
-
# Unit test / coverage reports
htmlcov/
.tox/
@@ -45,23 +39,62 @@ htmlcov/
nosetests.xml
coverage.xml
*,cover
-
# Translations
*.mo
*.pot
-
# Django stuff:
*.log
-
# Sphinx documentation
docs/_build/
-
# PyBuilder
target/
-
# Downstream Project
downloaded/
geoserver/
uploaded/
development.db
development.db-journal
+# PyCharm
+.idea
+venv
+*.pyc
+*.*~
+vagrant-fabric-lxc
+django_project/media/images
+visual_changelog.db
+.vagrant
+node_modules
+id_dsa.pub
+id_rsa.pub
+docs/build
+fabgis_resources
+private.py
+# Vim leftovers
+# project specifc
+django_project/core/settings/secret.py
+xmlrunner
+# Usually these files are written by a python script from a template
+# before PyInstaller builds the exe, so as to inject date/other infos
+# into it.
+#PyCharm
+# Virtual env
+# Node
+django_project/static
+# Working data not intended to be versioned
+data_for_import
+scrap.html
+.pycharm_helpers
+.sudo_as_admin_successful
+# Pg cluster for docker
+deployment/pg
+# Template for apt-cacher
+# static and media dirs
+deployment/static
+deployment/media
+deployment/docker/71-apt-cacher-ng
+django_project/geonode
+django_project/celerybeat-schedule
+# local media
+django_project/media
+# OSX Crap
+deployment/backups
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..1b94b02
--- /dev/null
+++ b/README.md
@@ -0,0 +1,30 @@
+# Haitidata
+
+You should write some docs, it's good for the soul.
+
+# Docker installation
+
+## Install docker
+This will install an Haitidata container
+
+Makes sure to have docker-compose installed
+```
+sudo apt-get install python-pip
+sudo pip install docker-compose
+```
+
+## Get project code
+Clone the repo:
+```
+git clone https://github.com/HaitiData/haitidata.git
+```
+
+## Run project
+Run the docker container:
+```
+cd deployment
+make deploy
+make update-migrations-localization:
+```
+
+then you can visit http://0.0.0.0:33300```
diff --git a/README.rst b/README.rst
deleted file mode 100644
index 283d3e1..0000000
--- a/README.rst
+++ /dev/null
@@ -1,84 +0,0 @@
-Haitidata
-========================
-
-You should write some docs, it's good for the soul.
-
-Installation
-------------
-
-Install geonode with::
-
- $ sudo add-apt-repository ppa:geonode/stable
-
- $ sudo apt-get update
-
- $ sudo apt-get install geonode
-
-Create a new template based on the geonode example project.::
-
- $ django-admin startproject my_geonode --template=https://github.com/GeoNode/geonode-project/archive/2.6.zip -epy,rst
- $ sudo pip install -e my_geonode
-
-.. note:: You should NOT use the name geonode for your project as it will conflict with the default geonode package name.
-
-Usage
------
-
-Rename the local_settings.py.sample to local_settings.py and edit it's content by setting the SITEURL and SITENAME.
-
-Edit the file /etc/apache2/sites-available/geonode and change the following directive from:
-
- WSGIScriptAlias / /var/www/geonode/wsgi/geonode.wsgi
-
-to:
-
- WSGIScriptAlias / /path/to/my_geonode/my_geonode/wsgi.py
-
-To avoid having to grant apache permissions (i.e. www-data user and group) to your home dir where you likely setup the geonode-project; you may want to instead copy the wsgi.py file next to geonode.wsgi and replace the file name instead of the entire path.
-
- $ cp /path/to/my_geonode/my_geonode/wsgi.py /var/www/geonode/wsgi/wsgi.py
-
-Add the "Directory" directive for your folder like the following example:
-
-
-
- Order allow,deny
-
- Options Indexes FollowSymLinks
-
- Allow from all
-
- Require all granted
-
- IndexOptions FancyIndexing
-
-
-
-Restart apache::
-
- $ sudo service apache2 restart
-
-Edit the templates in my_geonode/templates, the css and images to match your needs.
-
-In the my_geonode folder run::
-
- $ python manage.py collectstatic
-
-Github Considerations
-------------------------
-
-While it is helpful to recommit your django project wrapper back to a distributed version control repository.
-* It is also important to remember that production instances will store security information in the local_settings.py
-* Admin/Devs should always remember to exclude this file in the .gitignore file in the same folder as the .git::
-
- $ nano .gitignore
-
- /{project}/local_settings.py
-
-save, make sure the file is also removed from git cache::
-
- $ git rm -f --cache //local_settings.py
-
- $ git status
-
-confirm the file is no longer staged for the next commit or that if it is as "removed"
diff --git a/deployment/Makefile b/deployment/Makefile
new file mode 100644
index 0000000..eed39b6
--- /dev/null
+++ b/deployment/Makefile
@@ -0,0 +1,386 @@
+PROJECT_ID := haitidata
+PRODUCTION_HOST := haitidata.com
+
+SHELL := /bin/bash
+
+# ----------------------------------------------------------------------------
+# P R O D U C T I O N C O M M A N D S
+# ----------------------------------------------------------------------------
+fresh-web: build permissions web
+
+# Use this for fresh build (it will restore with empty stable database)
+fresh-deploy: fresh-web
+ @docker exec -t -i $(PROJECT_ID)-db su - postgres -c "dropdb gis"
+ @docker exec -t -i $(PROJECT_ID)-db su - postgres -c "createdb -O docker -T template_postgis gis"
+ @docker exec -t -i $(PROJECT_ID)-db pg_restore /fresh-backups/fresh-database.dmp | docker exec -i $(PROJECT_ID)-db su - postgres -c "psql gis"
+
+
+default: web
+run: build permissions web migrate collectstatic
+
+deploy: run
+ @echo
+ @echo "------------------------------------------------------------------"
+ @echo "Bringing up fresh instance "
+ @echo "You can access it on http://localhost:63300"
+ @echo "------------------------------------------------------------------"
+
+build:
+ @echo
+ @echo "------------------------------------------------------------------"
+ @echo "Building in production mode"
+ @echo "------------------------------------------------------------------"
+ @docker-compose -p $(PROJECT_ID) build uwsgi
+ @docker-compose -p $(PROJECT_ID) build uwsgi-ephemeral
+
+
+web:
+ @echo
+ @echo "------------------------------------------------------------------"
+ @echo "Running in production mode"
+ @echo "------------------------------------------------------------------"
+ @docker-compose -p $(PROJECT_ID) up -d web
+ @docker-compose -p $(PROJECT_ID) up -d uwsgi-ephemeral
+ @# Dont confuse this with the dbbackup make command below
+ @# This one runs the postgis-backup cron container
+ @# We add --no-recreate so that it does not destroy & recreate the db container
+ @docker-compose -p $(PROJECT_ID) up --no-recreate --no-deps -d dbbackups
+
+permissions:
+ # Probably we want something more granular here....
+ # Your sudo password will be needed to set the file permissions
+ # on logs, media, static and pg dirs
+ @if [ ! -d "logs" ]; then mkdir logs; fi
+ @if [ ! -d "media" ]; then mkdir media; fi
+ @if [ ! -d "static" ]; then mkdir static; fi
+ @if [ ! -d "backups" ]; then mkdir backups; fi
+ @if [ -d "logs" ]; then sudo chmod -R a+rwx logs; fi
+ @if [ -d "media" ]; then sudo chmod -R a+rwx media; fi
+ @if [ -d "static" ]; then sudo chmod -R a+rwx static; fi
+ @if [ -d "backups" ]; then sudo chmod -R a+rwx backups; fi
+
+db:
+ @echo
+ @echo "------------------------------------------------------------------"
+ @echo "Running db in production mode"
+ @echo "------------------------------------------------------------------"
+ @docker-compose -p $(PROJECT_ID) up -d db
+
+nginx:
+ @echo
+ @echo "------------------------------------------------------------------"
+ @echo "Running nginx in production mode"
+ @echo "Normally you should use this only for testing"
+ @echo "In a production environment you will typically use nginx running"
+ @echo "on the host rather if you have a multi-site host."
+ @echo "------------------------------------------------------------------"
+ @docker-compose -p $(PROJECT_ID) up -d nginx
+ @echo "Site should now be available at http://localhost"
+
+migrate:
+ @echo
+ @echo "------------------------------------------------------------------"
+ @echo "Running migrate static in production mode"
+ @echo "------------------------------------------------------------------"
+ @docker exec -t -i $(PROJECT_ID)_uwsgi-ephemeral_1 /bin/bash -c "\
+ python manage.py migrate"
+
+update-migrations:
+ @echo
+ @echo "------------------------------------------------------------------"
+ @echo "Running update migrations in production mode"
+ @echo "------------------------------------------------------------------"
+ @docker-compose -p $(PROJECT_ID) run uwsgi-ephemeral python manage.py makemigrations
+
+
+update-migrations-localization:
+ @echo
+ @echo "------------------------------------------------------------------"
+ @echo "Running update migrations in production mode"
+ @echo "------------------------------------------------------------------"
+ @docker-compose -p $(PROJECT_ID) run uwsgi bash -c "python manage.py makemigrations && python manage.py migrate"
+
+collectstatic:
+ @echo
+ @echo "------------------------------------------------------------------"
+ @echo "Collecting static in production mode"
+ @echo "------------------------------------------------------------------"
+ #We need to run collect static in the same context as the running
+ # uwsgi-ephemeral container it seems so I use docker exec here
+ # no -it flag so we can run over remote shell
+ @docker-compose -p $(PROJECT_ID) run uwsgi-ephemeral python manage.py collectstatic --noinput
+
+reload:
+ @echo
+ @echo "------------------------------------------------------------------"
+ @echo "Reload django project in production mode"
+ @echo "------------------------------------------------------------------"
+ # no -it flag so we can run over remote shell
+ @docker exec $(PROJECT_ID)-uwsgi uwsgi --reload /tmp/django.pid
+
+kill:
+ @echo
+ @echo "------------------------------------------------------------------"
+ @echo "Killing in production mode"
+ @echo "------------------------------------------------------------------"
+ @docker-compose -p $(PROJECT_ID) kill
+
+kill-uwsgi:
+ @echo
+ @echo "------------------------------------------------------------------"
+ @echo "Killing in uwsgi production mode"
+ @echo "------------------------------------------------------------------"
+ @docker-compose -p $(PROJECT_ID) kill uwsgi
+
+kill-uwsgi-ephemeral:
+ @echo
+ @echo "------------------------------------------------------------------"
+ @echo "Killing in uwsgi production mode"
+ @echo "------------------------------------------------------------------"
+ @docker-compose -p $(PROJECT_ID) kill uwsgi-ephemeral
+
+rm: dbbackup rm-only
+
+
+rm-only: kill
+ @echo
+ @echo "------------------------------------------------------------------"
+ @echo "Removing production instance!!! "
+ @echo "------------------------------------------------------------------"
+ @docker-compose -p $(PROJECT_ID) rm
+
+logs:
+ @echo
+ @echo "------------------------------------------------------------------"
+ @echo "Showing uwsgi logs in production mode"
+ @echo "------------------------------------------------------------------"
+ @docker-compose -p $(PROJECT_ID) logs uwsgi
+
+dblogs:
+ @echo
+ @echo "------------------------------------------------------------------"
+ @echo "Showing db logs in production mode"
+ @echo "------------------------------------------------------------------"
+ @docker-compose -p $(PROJECT_ID) logs db
+
+nginxlogs:
+ @echo
+ @echo "------------------------------------------------------------------"
+ @echo "Showing nginx logs in production mode"
+ @echo "------------------------------------------------------------------"
+ @docker-compose -p $(PROJECT_ID) logs web
+
+shell:
+ @echo
+ @echo "------------------------------------------------------------------"
+ @echo "Shelling in in production mode"
+ @echo "------------------------------------------------------------------"
+ @docker-compose -p $(PROJECT_ID) run uwsgi-ephemeral /bin/bash
+
+superuser:
+ @echo
+ @echo "------------------------------------------------------------------"
+ @echo "Creating a superuser in production mode"
+ @echo "------------------------------------------------------------------"
+ @docker-compose -p $(PROJECT_ID) run uwsgi-ephemeral python manage.py createsuperuser
+
+reviewaccess:
+ @echo
+ @echo "------------------------------------------------------------------"
+ @echo "Creating review permissions in production mode"
+ @echo "------------------------------------------------------------------"
+ @docker-compose -p $(PROJECT_ID) run uwsgi-ephemeral python manage.py create_review_permissions
+
+dbbash:
+ @echo
+ @echo "------------------------------------------------------------------"
+ @echo "Bashing in to production database"
+ @echo "------------------------------------------------------------------"
+ @docker exec -t -i $(PROJECT_ID)-db /bin/bash
+
+dbsnapshot:
+ @echo
+ @echo "------------------------------------------------------------------"
+ @echo "Grab a quick snapshot of the database and place in the host filesystem"
+ @echo "------------------------------------------------------------------"
+ @docker exec -t -i $(PROJECT_ID)-db /bin/bash -c "PGPASSWORD=docker pg_dump -Fc -h localhost -U docker -f /tmp/$(PROJECT_ID)-snapshot.dmp gis"
+ @docker cp $(PROJECT_ID)-db:/tmp/$(PROJECT_ID)-snapshot.dmp .
+ @docker exec -t -i $(PROJECT_ID)-db /bin/bash -c "rm /tmp/$(PROJECT_ID)-snapshot.dmp"
+ @ls -lahtr *.dmp
+
+dbschema:
+ @echo
+ @echo "------------------------------------------------------------------"
+ @echo "Print the database schema to stdio"
+ @echo "------------------------------------------------------------------"
+ @docker exec -t -i $(PROJECT_ID)-db /bin/bash -c "PGPASSWORD=docker pg_dump -s -h localhost -U docker gis"
+
+dbshell:
+ @echo
+ @echo "------------------------------------------------------------------"
+ @echo "Shelling in in production database"
+ @echo "------------------------------------------------------------------"
+ @docker exec -t -i $(PROJECT_ID)-db psql -U docker -h localhost gis
+
+dbrestore:
+ @echo
+ @echo "------------------------------------------------------------------"
+ @echo "Restore dump from backups/latest.dmp in production mode"
+ @echo "------------------------------------------------------------------"
+ @# - prefix causes command to continue even if it fails
+ -@docker exec -t -i $(PROJECT_ID)-db su - postgres -c "dropdb gis"
+ @docker exec -t -i $(PROJECT_ID)-db su - postgres -c "createdb -O docker -T template_postgis gis"
+ @docker exec -t -i $(PROJECT_ID)-db pg_restore /backups/latest.dmp | docker exec -i $(PROJECT_ID)-db su - postgres -c "psql gis"
+
+dbbackup:
+ @echo
+ @echo "------------------------------------------------------------------"
+ @echo "Create `date +%d-%B-%Y`.dmp in production mode"
+ @echo "Warning: backups/latest.dmp will be replaced with a symlink to "
+ @echo "the new backup."
+ @echo "------------------------------------------------------------------"
+ @# - prefix causes command to continue even if it fails
+ @# Explicitly don't use -it so we can call this make target over a remote ssh session
+ @docker exec $(PROJECT_ID)-db-backups /backups.sh
+ @docker exec $(PROJECT_ID)-db-backups cat /var/log/cron.log | tail -2 | head -1 | awk '{print $4}'
+ -@if [ -f "backups/latest.dmp" ]; then rm backups/latest.dmp; fi
+ # backups is intentionally missing from front of first clause below otherwise symlink comes
+ # out with wrong path...
+ @ln -s `date +%Y`/`date +%B`/PG_$(PROJECT_ID)_gis.`date +%d-%B-%Y`.dmp backups/latest.dmp
+ @echo "Backup should be at: backups/`date +%Y`/`date +%B`/PG_$(PROJECT_ID)_gis.`date +%d-%B-%Y`.dmp"
+
+sentry:
+ @echo
+ @echo "--------------------------"
+ @echo "Running sentry production mode"
+ @echo "--------------------------"
+ @docker-compose -p $(PROJECT_ID) up -d sentry
+
+maillogs:
+ @echo
+ @echo "------------------------------------------------------------------"
+ @echo "Showing smtp logs in production mode"
+ @echo "------------------------------------------------------------------"
+ @docker exec -t -i $(PROJECT_ID)-smtp tail -f /var/log/mail.log
+
+mailerrorlogs:
+ @echo
+ @echo "------------------------------------------------------------------"
+ @echo "Showing smtp error logs in production mode"
+ @echo "------------------------------------------------------------------"
+ @docker exec -t -i $(PROJECT_ID)-smtp tail -f /var/log/mail.err
+
+mediasync:
+ @echo
+ @echo "------------------------------------------------------------------"
+ @echo "Syncing media files and secret.py from live server"
+ @echo "------------------------------------------------------------------"
+ @rsync -av --progress $(PRODUCTION_HOST):/home/web/haitidata/deployment/media/ media
+ @rsync -av --progress $(PRODUCTION_HOST):/home/web/haitidata/django_project/core/settings/secret.py ../django_project/core/settings/
+
+dbsync:
+ @echo
+ @echo "------------------------------------------------------------------"
+ @echo "Syncing database files from live server"
+ @echo "------------------------------------------------------------------"
+ -@ssh $(PRODUCTION_HOST) "cd /home/web/haitidata/deployment; make dbbackup"
+ @rsync -av --progress $(PRODUCTION_HOST):/home/web/haitidata/deployment/backups/ backups
+
+create-machine:
+ @echo
+ @echo "------------------------------------------------------------------"
+ @echo "Creating a docker machine."
+ @echo "------------------------------------------------------------------"
+ @docker-machine create -d virtualbox $(PROJECT_ID)
+
+enable-machine:
+ @echo
+ @echo "------------------------------------------------------------------"
+ @echo "Enabling docker machine."
+ @echo "------------------------------------------------------------------"
+ @echo "eval \"$(docker-machine env mezzanine)\""
+
+create-workspace:
+ @echo
+ @echo "------------------------------------------------------------------"
+ @echo "Create geoserver workspace."
+ @echo "------------------------------------------------------------------"
+ @curl -v -u admin:geoserver -XPOST -H "Content-type: text/xml" -d "geonodetrue" http://localhost:33308/geoserver/rest/workspaces
+
+# ----------------------------------------------------------------------------
+# DEVELOPMENT C O M M A N D S
+# --no-deps will attach to prod deps if running
+# after running you will have ssh and web ports open (see dockerfile for no's)
+# and you can set your pycharm to use the python in the container
+# Note that pycharm will copy in resources to the /root/ user folder
+# for pydevd etc. If they dont get copied, restart pycharm...
+# ----------------------------------------------------------------------------
+
+devweb: db
+ @echo
+ @echo "------------------------------------------------------------------"
+ @echo "Running in DEVELOPMENT mode"
+ @echo "------------------------------------------------------------------"
+ @docker-compose -p $(PROJECT_ID) up --no-deps -d devweb
+
+
+build-devweb: db
+ @echo
+ @echo "------------------------------------------------------------------"
+ @echo "Building devweb"
+ @echo "------------------------------------------------------------------"
+ @docker-compose -p $(PROJECT_ID) build devweb
+
+
+# --------------- help --------------------------------
+
+help:
+ @echo "* **build** - builds all required containers."
+ @echo "* **build-devweb** - build the development container. See [development notes](README-dev.md)."
+ @echo "* **collectstatic** - run the django collectstatic command."
+ @echo "* **create-machine** ."
+ @echo "* **db** - build and run the db container."
+ @echo "* **dbbackup** - make a snapshot of the database, saving it to deployments/backups/YYYY/MM/project-DDMMYYYY.dmp. It also creates a symlink to backups/latest.dmp for the latest backup."
+ @echo "* **dbbash** - open a bash shell inside the database container."
+ @echo "* **dblogs** - view the database logs."
+ @echo "* **dbrestore** - restore deployment/backups/latest.dmp over the active database. Will delete any existing data in your database and replace with the restore, so **use with caution**."
+ @echo "* **dbschema** - dump the current db schema (without data) to stdio. Useful if you want to compare changes between instances."
+ @echo "* **dbshell** - get a psql prompt into the db container. "
+ @echo "* **dbsnapshot** - as above but makes the backup as deployment/snapshot.smp - replacing any pre-existing snapshot."
+ @echo "* **dbsync** - use this from a development or offsite machine. It will rsync all database backups from deployment/backups to your offsite machine."
+ @echo "* **default** ."
+ @echo "* **deploy** ."
+ @echo "* **devweb** - create an ssh container derived from uwsgi that can be used as a remote interpreter for PyCharm. See [development notes](README-dev.md)."
+ @echo "* **enable-machine** - "
+ @echo "* **kill** - kills all running containers. Does not remove them."
+ @echo "* **logs** - view the logs of all running containers. Note that you can also view individual logs in the deployment/logs directory."
+ @echo "* **mailerrorlogs** - View the error logs from the mail server."
+ @echo "* **maillogs** - view the transaction logs from the mail server."
+ @echo "* **mediasync** - use this from a development or offsite machine. It will rsync all media backups from deployment/media to your offsite machine."
+ @echo "* **migrate** - run any pending migrations. "
+ @echo "* **nginx** - builds and runs the nginx container."
+ @echo "* **nginxlogs** - view just the nginx activity logs."
+ @echo "* **permissions** - Update the permissions of shared volumes. Note this will destroy any existing permissions you have in place."
+ @echo "* **reload** - reload the uwsgi process. Useful when you need django to pick up any changes you may have deployed."
+ @echo "* **rm** - remove all containers."
+ @echo "* **rm-only** - remove any containers without trying to kill them first. "
+ @echo "* **run** - builds and runs the complete orchestrated set of containers."
+ @echo "* **sentry** - **currently not working I think.** The idea is to spin up a sentry instance together with your app for fault reporting."
+ @echo "* **shell** - open a bash shell in the uwsgi (where django runs) container."
+ @echo "* **superuser** - create a django superuser account."
+ @echo "* **update-migrations** - freshen all migration definitions to match the current code base."
+ @echo "* **web** - same as **run** - runs the production site."
+
+worker:
+ @echo
+ @echo "------------------------------------------------------------------"
+ @echo "Running worker production mode"
+ @echo "------------------------------------------------------------------"
+ @docker-compose -p $(PROJECT_ID) up -d worker
+
+workerlogs:
+ @echo
+ @echo "------------------------------------------------------------------"
+ @echo "Showing celery worker logs in production mode"
+ @echo "------------------------------------------------------------------"
+ @docker-compose -p $(PROJECT_ID) logs worker
diff --git a/deployment/README-docker.md b/deployment/README-docker.md
new file mode 100644
index 0000000..380f58b
--- /dev/null
+++ b/deployment/README-docker.md
@@ -0,0 +1,99 @@
+# Deploying with docker
+
+**Note:** This documentation is intentionally generic so that it can
+be copy-pasted between projects - do not put project specific details here.
+
+This document explains how to do various sysadmin related tasks when your
+site has been deployed under docker. These deployment modes are supported:
+
+* **production**: no debug etc is enabled, has its own discrete database. Configure
+ your production environment in core.settings.prod_docker - this
+ DJANGO_SETTINGS_MODULE is used when running in production mode.
+* **staging**: Configure your staging environment in core.settings.staging_docker -
+ this DJANGO_SETTINGS_MODULE is used when running in production mode.
+
+# Build your docker images and run them
+
+## Production
+
+You can simply run the provided script and it will build and deploy the docker
+images for you in **production mode**.
+
+```
+cd deployment
+# allow pg volume to be written to
+sudo chmod -R a+rwX pg/postgres_data/
+make deploy
+sudo chmod -R a+rwX static
+```
+
+Now point your browser at the ip of the web container on port 8080 or to the
+host port mapping as defined in the fig.yml file.
+
+
+To make a superuser account do:
+
+```
+make shell
+python manage.py createsuperuser
+exit
+```
+
+## Staging
+
+The procedure is exactly the same as production, but you should preceed
+each command with 'staging' e.g. ``make staging-deploy``.
+
+**Note:** VERY IMPORTANT - for staging deployment you should use a **separate
+git checkout** from the production checkout as the code from the git checkout
+is shared into the source tree.
+
+## Using make
+
+The following key make commands are provided for production:
+
+* **build** - build production containers
+* **run** - builds then runs db and uwsgi services
+* **collectstatic** - collect static in production instance
+* **migrate** - run django migrations in production instance
+
+Additional make commands are provided in the Makefile - please see there
+for details.
+
+#### Arbitrary commands
+
+Running arbitrary management commands is easy
+
+
+## Setup nginx reverse proxy
+
+You should create a new nginx virtual host - please see
+``*-nginx.conf`` in the deployment directory for examples. There is
+one provided for production and one for staging.
+
+Simply add the example file (renaming them as needed) to your
+``/etc/nginx/sites-enabled/`` directory and then modify the contents to
+match your local filesystem paths. Then use
+
+```
+sudo nginx -t
+```
+
+To verify that your configuration is correct and then reload / restart nginx
+e.g.
+
+```
+sudo /etc/init.d/nginx restart
+```
+
+
+### Managing containers
+
+Please refer to the general [fig documentation](http://www.fig.sh/cli.hyml)
+for further notes on how to manage the infrastructure using fig.
+
+# Configuration options
+
+You can configure the base port used and various other options like the
+image organisation namespace and postgis user/pass by editing the ``fig*.yml``
+files.
diff --git a/deployment/docker-compose.yml b/deployment/docker-compose.yml
new file mode 100644
index 0000000..4b300eb
--- /dev/null
+++ b/deployment/docker-compose.yml
@@ -0,0 +1,197 @@
+#
+# Production server with UWSGI configured to run on port 8080
+#
+# docker-compose build
+# docker-compose up -d web
+#
+# See accompanying Make commands for easy collectstatic etc.
+
+rabbitmq:
+ image: library/rabbitmq
+ hostname: rabbitmq
+ environment:
+ - RABBIT_PASSWORD=rabbit_test_password
+ - USER=rabbit_user
+ - RABBITMQ_NODENAME=rabbit
+
+
+smtp:
+ # Note you cannot scale if you use conteiner_name
+ container_name: haitidata-smtp
+ image: catatnight/postfix
+ hostname: postfix
+ environment:
+ # You could change this to something more suitable
+ - maildomain=kartoza.com
+ - smtp_user=noreply:docker
+ restart: always
+
+db:
+ # Note you cannot scale if you use conteiner_name
+ container_name: haitidata-db
+ image: kartoza/postgis:9.4-2.1
+ volumes:
+ - ./pg/postgres_data:/var/lib/postgresql
+ - ./backups:/backups
+ - ./fresh-backups:/fresh-backups
+ environment:
+ - USERNAME=docker
+ - PASS=docker
+ restart: always
+ ports:
+ - "33305:5432"
+
+uwsgi-base:
+ # Note you cannot scale if you use conteiner_name
+ build: docker
+ hostname: uwsgi
+ environment:
+ - DATABASE_NAME=gis
+ - DATABASE_USERNAME=docker
+ - DATABASE_PASSWORD=docker
+ - DATABASE_HOST=db
+ - RABBITMQ_HOST=rabbitmq
+ - DJANGO_SETTINGS_MODULE=core.settings.prod_docker
+ - VIRTUAL_HOST=haitidata.com
+ - VIRTUAL_PORT=8080
+ - GEOSERVER_PUBLIC_LOCATION=http://0.0.0.0:33300/api/geoserver/
+ # Set your locale - you need to ensure this is created in Dockerfile too...
+ - LC_ALL=en_ZA.UTF-8
+ volumes:
+ - ../django_project:/home/web/django_project
+ - ./static:/home/web/static:rw
+ - ./media:/home/web/media:rw
+ - ./reports:/home/web/reports
+ - ./logs:/var/log/
+ user: root
+
+uwsgi-ephemeral:
+ extends: uwsgi-base
+ links:
+ - smtp:smtp
+ - db:db
+ user: root
+ restart: on-failure:5
+
+uwsgi:
+ # Note you cannot scale if you use conteiner_name
+ extends: uwsgi-base
+ container_name: haitidata-uwsgi
+ links:
+ - smtp:smtp
+ - db:db
+ - geoserver:geoserver
+ restart: always
+
+dbbackups:
+ # Note you cannot scale if you use conteiner_name
+ container_name: haitidata-db-backups
+ image: kartoza/pg-backup:9.4
+ hostname: pg-backups
+ volumes:
+ - ./backups:/backups
+ links:
+ - db:db
+ environment:
+ # take care to let the project name below match that
+ # declared in the top of the makefile
+ - DUMPPREFIX=PG_haiti
+ # These are all defaults anyway, but setting explicitly in
+ # case we ever want to ever use different credentials
+ - PGUSER=docker
+ - PGPASSWORD=docker
+ - PGPORT=5432
+ - PGHOST=db
+ - PGDATABASE=gis
+ restart: always
+
+# This is normally the main entry point for a production server
+web:
+ # Note you cannot scale if you use conteiner_name
+ container_name: haitidata-web
+ image: nginx
+ hostname: nginx
+ volumes:
+ - ./sites-enabled:/etc/nginx/conf.d:ro
+ # I dont use volumes_from as I want to use the ro modifier
+ - ./static:/home/web/static:ro
+ - ./media:/home/web/media:ro
+ - ./logs:/var/log/nginx
+ # - /etc/letsencrypt:/etc/letsencrypt
+ - ./webroot-path:/home/web/webroot-path
+ links:
+ - uwsgi:uwsgi
+ - geoserver:geoserver
+ ports:
+ - "33300:8080"
+ restart: always
+
+# This is the entry point for a development server.
+# Run with --no-deps to run attached to the services
+# from produ environment if wanted
+devweb:
+ # Note you cannot scale if you use conteiner_name
+ container_name: haitidata-dev-web
+ build: docker
+ dockerfile: Dockerfile-dev
+ hostname: haitidata-dev-web
+ environment:
+ - DATABASE_NAME=gis
+ - DATABASE_USERNAME=docker
+ - DATABASE_PASSWORD=docker
+ - DATABASE_HOST=db
+ - RABBITMQ_HOST=rabbitmq
+ - DJANGO_SETTINGS_MODULE=core.settings.prod_docker
+ - PYTHONPATH=/home/web/django_project
+ - VIRTUAL_HOST=haitidata.com
+ - VIRTUAL_PORT=8080
+ - GEOSERVER_PUBLIC_LOCATION=http://0.0.0.0:33303/api/geoserver/
+ volumes:
+ - ../django_project:/home/web/django_project
+ - ./static:/home/web/static
+ - ./media:/home/web/media
+ - ./reports:/home/web/reports
+ - ./logs:/var/log/
+ links:
+ - smtp:smtp
+ - db:db
+ - rabbitmq:rabbitmq
+ - geoserver:geoserver
+ ports:
+ # for django test server
+ - "33303:8080"
+ # for ssh
+ - "33302:22"
+
+worker:
+ build: docker
+ hostname: worker
+ command: celery worker -A config.celery -l info --beat
+ environment:
+ - DATABASE_NAME=gis
+ - DATABASE_USERNAME=docker
+ - DATABASE_PASSWORD=docker
+ - DATABASE_HOST=db
+ - DATABASE_QGIS_HOST=db_gis
+ - RABBITMQ_HOST=rabbitmq
+ - DJANGO_SETTINGS_MODULE=core.settings.prod_docker
+ - VIRTUAL_HOST=haitidata.com
+ - VIRTUAL_PORT=8080
+ - C_FORCE_ROOT=true
+ volumes:
+ - ../django_project:/home/web/django_project
+ - ./static:/home/web/static
+ - ./media:/home/web/media
+ - ./reports:/home/web/reports
+ - ./logs:/var/log/
+ links:
+ - smtp:smtp
+ - db:db
+ - rabbitmq:rabbitmq
+ restart: on-failure:5
+
+geoserver:
+ image: kartoza/geoserver
+ container_name: haitidata-geoserver
+ ports:
+ - "33308:8080"
diff --git a/deployment/docker/71-apt-cacher-ng.template b/deployment/docker/71-apt-cacher-ng.template
new file mode 100644
index 0000000..de5127d
--- /dev/null
+++ b/deployment/docker/71-apt-cacher-ng.template
@@ -0,0 +1,4 @@
+#Acquire::http { Proxy "http://192.168.0.106:3142"; };
+#Acquire::http { Proxy "http://192.168.2.9:3142"; };
+#Acquire::http { Proxy "http://192.168.0.131:3142"; };
+#Acquire::http { Proxy "http://192.168.1.13:3142"; };
diff --git a/deployment/docker/Dockerfile b/deployment/docker/Dockerfile
new file mode 100644
index 0000000..0f87b64
--- /dev/null
+++ b/deployment/docker/Dockerfile
@@ -0,0 +1,60 @@
+#--------- Generic stuff all our Dockerfiles should start with so we get caching ------------
+# Note this base image is based on debian
+FROM kartoza/django-base
+MAINTAINER Muhammad Anis
+
+#RUN ln -s /bin/true /sbin/initctl
+
+# Use local cached debs from host (saves your bandwidth!)
+# Change ip below to that of your apt-cacher-ng host
+# Or comment this line out if you do not with to use caching
+ADD 71-apt-cacher-ng /etc/apt/apt.conf.d/71-apt-cacher-ng
+
+# Pandoc needed to generate rst dumps, uic compressor needed for django-pipeline
+RUN apt-get update -y
+
+# Set the locale - change to your preferred locale ... We use South African english
+# We do this as cartridge (ecommerce platform for mezzanine) relies on
+# the locale to set the correct number of decimal places for the MoneyField
+RUN echo "deb http://ftp.debian.org/debian jessie main" >> /etc/apt/sources.list.d/gdal.list
+RUN apt-get update
+
+RUN apt-get install locales && \
+ echo "en_ZA.UTF-8 UTF-8" >> /etc/locale.gen && \
+ locale-gen en_ZA.UTF-8
+RUN apt-get install libgdal-dev -y
+ENV LANG en_ZA.UTF-8
+ENV LANGUAGE en_ZA:en
+ENV LC_ALL en_ZA.UTF-8
+ENV CPLUS_INCLUDE_PATH /usr/include/gdal
+ENV C_INCLUDE_PATH /usr/include/gdal
+ENV TEST a
+
+ADD REQUIREMENTS.txt /REQUIREMENTS.txt
+RUN pip install -r /REQUIREMENTS.txt
+RUN pip uninstall -y South
+RUN pip install uwsgi
+
+RUN pip uninstall geonode-dialogos -y
+RUN pip install git+https://github.com/meomancer/geonode-dialogos.git
+
+RUN pip uninstall geonode-agon-ratings -y
+RUN pip install git+https://github.com/euclidian/custom-agon-ratings
+
+RUN pip uninstall Django -y
+RUN pip install Django==1.8.18
+
+RUN pip uninstall django-oauth-toolkit -y
+RUN pip install django-oauth-toolkit==0.12.0
+
+RUN pip uninstall django-user-accounts -y
+RUN pip install git+https://github.com/GeoNode/geonode-user-accounts@invite-user
+
+RUN apt-get install gdal-bin
+# Open port 8080 as we will be running our uwsgi socket on that
+EXPOSE 8080
+
+#USER www-data
+
+WORKDIR /home/web/django_project
+CMD ["uwsgi", "--env", "LC_ALL=en_ZA.UTF-8", "--ini", "/uwsgi.conf"]
diff --git a/deployment/docker/Dockerfile-cloud b/deployment/docker/Dockerfile-cloud
new file mode 100644
index 0000000..75e7256
--- /dev/null
+++ b/deployment/docker/Dockerfile-cloud
@@ -0,0 +1,68 @@
+#--------- Generic stuff all our Dockerfiles should start with so we get caching ------------
+# Note this base image is based on debian
+FROM kartoza/django-base
+MAINTAINER Muhammad Anis
+
+#RUN ln -s /bin/true /sbin/initctl
+
+# Use local cached debs from host (saves your bandwidth!)
+# Change ip below to that of your apt-cacher-ng host
+# Or comment this line out if you do not with to use caching
+# ADD 71-apt-cacher-ng /etc/apt/apt.conf.d/71-apt-cacher-ng
+
+# Pandoc needed to generate rst dumps, uic compressor needed for django-pipeline
+RUN apt-get update -y
+
+# Set the locale - change to your preferred locale ... We use South African english
+# We do this as cartridge (ecommerce platform for mezzanine) relies on
+# the locale to set the correct number of decimal places for the MoneyField
+RUN echo "deb http://ftp.debian.org/debian jessie main" >> /etc/apt/sources.list.d/gdal.list
+RUN apt-get update
+
+RUN apt-get install locales && \
+ echo "en_ZA.UTF-8 UTF-8" >> /etc/locale.gen && \
+ locale-gen en_ZA.UTF-8
+RUN apt-get install libgdal-dev -y
+ENV LANG en_ZA.UTF-8
+ENV LANGUAGE en_ZA:en
+ENV LC_ALL en_ZA.UTF-8
+ENV CPLUS_INCLUDE_PATH /usr/include/gdal
+ENV C_INCLUDE_PATH /usr/include/gdal
+
+ADD REQUIREMENTS.txt /REQUIREMENTS.txt
+RUN pip install -r /REQUIREMENTS.txt
+RUN pip uninstall -y South
+RUN pip install uwsgi
+
+RUN pip uninstall geonode-dialogos -y
+RUN pip install git+https://github.com/meomancer/geonode-dialogos.git
+
+RUN pip uninstall geonode-agon-ratings -y
+RUN pip install git+https://github.com/euclidian/custom-agon-ratings
+
+RUN pip uninstall Django -y
+RUN pip install Django==1.8.18
+
+RUN pip uninstall django-oauth-toolkit -y
+RUN pip install django-oauth-toolkit==0.12.0
+
+RUN pip uninstall django-user-accounts -y
+RUN pip install git+https://github.com/GeoNode/geonode-user-accounts@invite-user
+
+RUN apt-get install gdal-bin
+# Open port 8080 as we will be running our uwsgi socket on that
+EXPOSE 8080
+
+#USER www-data
+
+WORKDIR /home/web
+
+# Download repository
+RUN git clone https://github.com/euclidian/haitidata
+
+RUN make migrate
+RUN make collectstatic
+
+WORKDIR /home/web/django_project
+
+CMD ["uwsgi", "--env", "LC_ALL=en_ZA.UTF-8", "--ini", "/uwsgi.conf"]
diff --git a/deployment/docker/Dockerfile-dev b/deployment/docker/Dockerfile-dev
new file mode 100644
index 0000000..5dd9fa2
--- /dev/null
+++ b/deployment/docker/Dockerfile-dev
@@ -0,0 +1,41 @@
+#--------- Generic stuff all our Dockerfiles should start with so we get caching ------------
+# Note this base image is based on debian
+FROM haitidata_uwsgi
+MAINTAINER Muhammad Anis
+
+# Use local cached debs from host (saves your bandwidth!)
+# Change ip below to that of your apt-cacher-ng host
+# Or comment this line out if you do not with to use caching
+ADD 71-apt-cacher-ng /etc/apt/apt.conf.d/71-apt-cacher-ng
+
+
+# This section taken on 2 July 2015 from
+# https://docs.docker.com/examples/running_ssh_service/
+# Sudo is needed by pycharm when it tries to pip install packages
+RUN apt-get update && apt-get install -y openssh-server sudo
+RUN mkdir /var/run/sshd
+RUN echo 'root:docker' | chpasswd
+RUN sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/' /etc/ssh/sshd_config
+
+# SSH login fix. Otherwise user is kicked off after login
+RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd
+
+ENV NOTVISIBLE "in users profile"
+RUN echo "export VISIBLE=now" >> /etc/profile
+
+# End of cut & paste section
+
+ADD REQUIREMENTS-dev.txt /REQUIREMENTS-dev.txt
+RUN pip install -r /REQUIREMENTS-dev.txt
+ADD bashrc /root/.bashrc
+
+# --------------------------------------------------------
+# Open ports as needed
+# --------------------------------------------------------
+
+# Open port 8080 as we will be running our django dev server on
+EXPOSE 8080
+# Open port 22 as we will be using a remote interpreter from pycharm
+EXPOSE 22
+
+CMD ["/usr/sbin/sshd", "-D"]
diff --git a/deployment/docker/REQUIREMENTS-dev.txt b/deployment/docker/REQUIREMENTS-dev.txt
new file mode 100644
index 0000000..c2d8680
--- /dev/null
+++ b/deployment/docker/REQUIREMENTS-dev.txt
@@ -0,0 +1,15 @@
+django-nose
+coverage
+pep8>=1.5.7,<1.6
+pylint
+flake8==2.5.4
+factory_boy
+
+django-devserver
+
+# documentation
+Sphinx
+
+# pdb plus plus
+pdbpp
+
diff --git a/deployment/docker/REQUIREMENTS.txt b/deployment/docker/REQUIREMENTS.txt
new file mode 100644
index 0000000..df07c78
--- /dev/null
+++ b/deployment/docker/REQUIREMENTS.txt
@@ -0,0 +1,42 @@
+celery==3.1
+Django==1.10
+psycopg2
+django-compressor
+icalendar==3.0.1b2
+geopy==0.95.1
+filebrowser-safe==0.4.5
+# https://github.com/getsentry/raven-python/issues/337
+raven==5.8.1
+django-sentry==1.13.5
+requests==2.13.0
+
+#cartridge requirement
+cartridge==0.12.0
+
+
+django-appconf==1.0.1
+django-model-utils==2.3.1
+django-reversion==1.9.3
+django-sitetree==1.5.1
+django-taggit==0.21.5
+django-timezone-field==1.3
+django-user-accounts==1.2.0
+easy-thumbnails==2.2
+html5lib==0.999999999
+markdown==2.6.2
+pytz==2015.6
+pyyaml==3.11
+ruamel.yaml==0.13.14
+bleach==2.0.0
+
+
+#geonode
+django-geonode-client
+git+https://github.com/GeoNode/django-osgeo-importer.git
+django-jsonfield
+
+
+python-dateutil
+gdal==1.10.0
+git+https://github.com/meomancer/GeoNode-1.git
+django-tastypie
diff --git a/deployment/docker/bashrc b/deployment/docker/bashrc
new file mode 100644
index 0000000..0c2ee35
--- /dev/null
+++ b/deployment/docker/bashrc
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+# This is intended to be placed in the docker dev environment so
+# that the django project is in the path when you log in
+
+if [ -f /etc/bashrc ]; then
+ . /etc/bashrc
+fi
+export PYTHONPATH=/home/web/django_project:$PYTHONPATH
+export DJANGO_SETTINGS_MODULE=core.settings.dev_docker
+cd /home/web/django_project
diff --git a/deployment/docker/build.sh b/deployment/docker/build.sh
new file mode 100755
index 0000000..0ecb6a3
--- /dev/null
+++ b/deployment/docker/build.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+ docker build -t kartoza/mezzanine .
diff --git a/deployment/docker/uwsgi.conf b/deployment/docker/uwsgi.conf
new file mode 100644
index 0000000..be68d6b
--- /dev/null
+++ b/deployment/docker/uwsgi.conf
@@ -0,0 +1,19 @@
+[uwsgi]
+
+# Touch this file to reload uwsgi
+touch-reload = /tmp/touch-me-to-reload
+chdir = /home/web/django_project
+module = core.wsgi
+master = true
+pidfile=/tmp/django.pid
+socket = 0.0.0.0:49360
+workers = 4
+cheaper = 2
+env = DJANGO_SETTINGS_MODULE=core.settings.prod_docker
+# disabled so we run in the foreground for docker
+#daemonize = /tmp/django.log
+reload-os-env
+#uid = 1000
+#gid = 1000
+memory-report = true
+harakiri = 20
diff --git a/deployment/fresh-backups/fresh-database.dmp b/deployment/fresh-backups/fresh-database.dmp
new file mode 100755
index 0000000..777fb1b
Binary files /dev/null and b/deployment/fresh-backups/fresh-database.dmp differ
diff --git a/deployment/load-test/simple_http_get.py b/deployment/load-test/simple_http_get.py
new file mode 100644
index 0000000..4cba7e7
--- /dev/null
+++ b/deployment/load-test/simple_http_get.py
@@ -0,0 +1,21 @@
+from locust import HttpLocust, TaskSet, task
+
+
+class HaitiData(TaskSet):
+ def on_start(self):
+ response = self.client.get("/account/login")
+ csrftoken = response.cookies['csrftoken']
+ self.client.post("/account/login/",
+ {"username": "admin",
+ "password": "admin"},
+ headers={"X-CSRFToken": csrftoken})
+
+ @task
+ def index(self):
+ self.client.get("/layers/geonode:madagascar_earthquake_cqmtpiu_tif_2017_08_23_08_59_10")
+
+
+class HaitiUser(HttpLocust):
+ task_set = HaitiData
+ min_wait = 5000
+ max_wait = 15000
\ No newline at end of file
diff --git a/haitidata.egg-info/dependency_links.txt b/deployment/logs/uwsgi-
old mode 100644
new mode 100755
similarity index 100%
rename from haitidata.egg-info/dependency_links.txt
rename to deployment/logs/uwsgi-
diff --git a/deployment/manual_backup.sh b/deployment/manual_backup.sh
new file mode 100755
index 0000000..b9d8d48
--- /dev/null
+++ b/deployment/manual_backup.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+MYDATE=`date +%d-%B-%Y`
+MONTH=$(date +%B)
+YEAR=$(date +%Y)
+cd /home/web/mezzanine.kartoza.com/deployment
+MYBASEDIR=`pwd`/backups
+MYBACKUPDIR=${MYBASEDIR}/${YEAR}/${MONTH}
+mkdir -p ${MYBACKUPDIR}
+
+cd ${MYBACKUPDIR}
+docker exec -ti mezzanine-db /bin/bash -c "PGPASSWORD=docker pg_dump -Fc -f /tmp/latest.dmp -h localhost -U docker gis"
+docker cp mezzanine-db:/tmp/latest.dmp PG_mezzanine-${MYDATE}.dmp
+
+cd -
+rm backups/latest.dmp
+
+cd backups
+ln -s ${MYBACKUPDIR}/PG_mezzanine-${MYDATE}.dmp latest.dmp
+
+cd ..
diff --git a/haitidata.egg-info/top_level.txt b/deployment/playbook/haiti-ansible.retry
similarity index 100%
rename from haitidata.egg-info/top_level.txt
rename to deployment/playbook/haiti-ansible.retry
diff --git a/deployment/playbook/haiti-ansible.yaml b/deployment/playbook/haiti-ansible.yaml
new file mode 100644
index 0000000..bda9a84
--- /dev/null
+++ b/deployment/playbook/haiti-ansible.yaml
@@ -0,0 +1,18 @@
+---
+- hosts: haitidata_swarm
+ vars:
+ http_port: 80
+ max_clients: 200
+ tasks:
+ - name: pull haiti source code from github
+ git:
+ repo: https://github.com/euclidian/haitidata.git
+ dest: /tmp/web_haiti
+ - name: run migrate
+ make:
+ chdir: /tmp/web_haiti/deployment
+ target: migrate
+ - name: run collect static
+ make:
+ chdir: /tmp/web_haiti/deployment
+ target: collectstatic
\ No newline at end of file
diff --git a/deployment/playbook/hosts b/deployment/playbook/hosts
new file mode 100644
index 0000000..c7222d7
--- /dev/null
+++ b/deployment/playbook/hosts
@@ -0,0 +1,2 @@
+[haitidata_swarm]
+haitidata
\ No newline at end of file
diff --git a/deployment/qgisug.nginx.conf b/deployment/qgisug.nginx.conf
new file mode 100644
index 0000000..624748c
--- /dev/null
+++ b/deployment/qgisug.nginx.conf
@@ -0,0 +1,53 @@
+upstream qgisug {
+ server 127.0.0.1:63300;
+}
+
+server {
+ # OTF gzip compression
+ gzip on;
+ gzip_min_length 860;
+ gzip_comp_level 5;
+ gzip_proxied expired no-cache no-store private auth;
+ gzip_types text/plain application/xml application/x-javascript text/xml text/css application/json;
+ gzip_disable “MSIE [1-6].(?!.*SV1)”;
+
+ # the port your site will be served on
+ listen 443 ssl;
+ # the domain name it will serve for
+ server_name qgis.org.za;
+
+ ssl on;
+ ssl_certificate /etc/letsencrypt/live/qgis.org.za/fullchain.pem;
+ ssl_certificate_key /etc/letsencrypt/live/qgis.org.za/privkey.pem;
+ ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
+ ssl_prefer_server_ciphers on;
+ ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
+
+ location /.well-known/acme-challenge {
+ default_type "text/plain";
+ # set to webroot path
+ root /home/web/qgis.org.za/deployment/webroot-path;
+ }
+
+ charset utf-8;
+
+ # max upload size, adjust to taste
+ client_max_body_size 15M;
+
+ location / {
+ proxy_pass http://qgisug;
+ proxy_redirect off;
+ proxy_set_header Host $host;
+ proxy_set_header X-Forwarded-For $remote_addr;
+ }
+
+}
+
+server {
+ listen 80;
+ server_name qgis.org.za, foss4g-africa.org, www.foss4g-africa.org;
+ if ($host = 'www.foss4g-africa.org') {
+ return 301 https://foss4g-africa.org$request_uri;
+ }
+ return 301 https://$host$request_uri;
+}
diff --git a/deployment/rabbitmq.config b/deployment/rabbitmq.config
new file mode 100644
index 0000000..3121dbd
--- /dev/null
+++ b/deployment/rabbitmq.config
@@ -0,0 +1,7 @@
+[
+{rabbit, [
+{default_user, <<“rabbit_admin”>>},
+{default_pass, <<“rabbit_password”>>},
+{tcp_listeners,[{“0.0.0.0″,5672}]}
+]}
+]
diff --git a/deployment/rancher-compose.yml b/deployment/rancher-compose.yml
new file mode 100644
index 0000000..3d2261c
--- /dev/null
+++ b/deployment/rancher-compose.yml
@@ -0,0 +1,2 @@
+uwsgi:
+ scale: 3
\ No newline at end of file
diff --git a/deployment/rancher-docker-compose.yml b/deployment/rancher-docker-compose.yml
new file mode 100644
index 0000000..dc2906f
--- /dev/null
+++ b/deployment/rancher-docker-compose.yml
@@ -0,0 +1,197 @@
+#
+# Production server with UWSGI configured to run on port 8080
+#
+# docker-compose build
+# docker-compose up -d web
+#
+# See accompanying Make commands for easy collectstatic etc.
+
+rabbitmq:
+ image: library/rabbitmq
+ hostname: rabbitmq
+ environment:
+ - RABBIT_PASSWORD=rabbit_test_password
+ - USER=rabbit_user
+ - RABBITMQ_NODENAME=rabbit
+
+
+smtp:
+ # Note you cannot scale if you use conteiner_name
+ container_name: haitidata-smtp
+ image: catatnight/postfix
+ hostname: postfix
+ environment:
+ # You could change this to something more suitable
+ - maildomain=kartoza.com
+ - smtp_user=noreply:docker
+ restart: always
+
+db:
+ # Note you cannot scale if you use conteiner_name
+ container_name: haitidata-db
+ image: kartoza/postgis:9.4-2.1
+ volumes:
+ - ./pg/postgres_data:/var/lib/postgresql
+ - ./backups:/backups
+ - ./fresh-backups:/fresh-backups
+ environment:
+ - USERNAME=docker
+ - PASS=docker
+ restart: always
+ ports:
+ - "33305:5432"
+
+uwsgi-ephemeral:
+ image: muhammadanis/haitidata_uwsgi
+ environment:
+ - DATABASE_NAME=gis
+ - DATABASE_USERNAME=docker
+ - DATABASE_PASSWORD=docker
+ - DATABASE_HOST=db
+ - RABBITMQ_HOST=rabbitmq
+ - DJANGO_SETTINGS_MODULE=core.settings.prod_docker
+ - VIRTUAL_HOST=haitidata.com
+ - VIRTUAL_PORT=8080
+ - GEOSERVER_PUBLIC_LOCATION=http://0.0.0.0:33300/api/geoserver/
+ # Set your locale - you need to ensure this is created in Dockerfile too...
+ - LC_ALL=en_ZA.UTF-8
+ links:
+ - smtp:smtp
+ - db:db
+ user: root
+ restart: on-failure:5
+
+uwsgi:
+ # Note you cannot scale if you use conteiner_name
+ image: muhammadanis/haitidata_uwsgi
+ environment:
+ - DATABASE_NAME=gis
+ - DATABASE_USERNAME=docker
+ - DATABASE_PASSWORD=docker
+ - DATABASE_HOST=db
+ - RABBITMQ_HOST=rabbitmq
+ - DJANGO_SETTINGS_MODULE=core.settings.prod_docker
+ - VIRTUAL_HOST=haitidata.com
+ - VIRTUAL_PORT=8080
+ - GEOSERVER_PUBLIC_LOCATION=http://0.0.0.0:33300/api/geoserver/
+ # Set your locale - you need to ensure this is created in Dockerfile too...
+ - LC_ALL=en_ZA.UTF-8
+ user: root
+ links:
+ - smtp:smtp
+ - db:db
+ - geoserver:geoserver
+ restart: always
+
+dbbackups:
+ # Note you cannot scale if you use conteiner_name
+ container_name: haitidata-db-backups
+ image: kartoza/pg-backup:9.4
+ hostname: pg-backups
+ volumes:
+ - ./backups:/backups
+ links:
+ - db:db
+ environment:
+ # take care to let the project name below match that
+ # declared in the top of the makefile
+ - DUMPPREFIX=PG_haiti
+ # These are all defaults anyway, but setting explicitly in
+ # case we ever want to ever use different credentials
+ - PGUSER=docker
+ - PGPASSWORD=docker
+ - PGPORT=5432
+ - PGHOST=db
+ - PGDATABASE=gis
+ restart: always
+
+# This is normally the main entry point for a production server
+web:
+ # Note you cannot scale if you use conteiner_name
+ container_name: haitidata-web
+ image: nginx
+ hostname: nginx
+ volumes:
+ - ./sites-enabled:/etc/nginx/conf.d:ro
+ # I dont use volumes_from as I want to use the ro modifier
+ - ./static:/home/web/static:ro
+ - ./media:/home/web/media:ro
+ - ./logs:/var/log/nginx
+ # - /etc/letsencrypt:/etc/letsencrypt
+ - ./webroot-path:/home/web/webroot-path
+ links:
+ - uwsgi:uwsgi
+ - geoserver:geoserver
+ ports:
+ - "33300:8080"
+ restart: always
+
+# This is the entry point for a development server.
+# Run with --no-deps to run attached to the services
+# from produ environment if wanted
+devweb:
+ # Note you cannot scale if you use conteiner_name
+ container_name: haitidata-dev-web
+ build: docker
+ dockerfile: Dockerfile-dev
+ hostname: haitidata-dev-web
+ environment:
+ - DATABASE_NAME=gis
+ - DATABASE_USERNAME=docker
+ - DATABASE_PASSWORD=docker
+ - DATABASE_HOST=db
+ - RABBITMQ_HOST=rabbitmq
+ - DJANGO_SETTINGS_MODULE=core.settings.prod_docker
+ - PYTHONPATH=/home/web/django_project
+ - VIRTUAL_HOST=haitidata.com
+ - VIRTUAL_PORT=8080
+ - GEOSERVER_PUBLIC_LOCATION=http://0.0.0.0:33303/api/geoserver/
+ volumes:
+ - ../django_project:/home/web/django_project
+ - ./static:/home/web/static
+ - ./media:/home/web/media
+ - ./reports:/home/web/reports
+ - ./logs:/var/log/
+ links:
+ - smtp:smtp
+ - db:db
+ - rabbitmq:rabbitmq
+ - geoserver:geoserver
+ ports:
+ # for django test server
+ - "33303:8080"
+ # for ssh
+ - "33302:22"
+
+worker:
+ build: docker
+ hostname: worker
+ command: celery worker -A config.celery -l info --beat
+ environment:
+ - DATABASE_NAME=gis
+ - DATABASE_USERNAME=docker
+ - DATABASE_PASSWORD=docker
+ - DATABASE_HOST=db
+ - DATABASE_QGIS_HOST=db_gis
+ - RABBITMQ_HOST=rabbitmq
+ - DJANGO_SETTINGS_MODULE=core.settings.prod_docker
+ - VIRTUAL_HOST=haitidata.com
+ - VIRTUAL_PORT=8080
+ - C_FORCE_ROOT=true
+ volumes:
+ - ../django_project:/home/web/django_project
+ - ./static:/home/web/static
+ - ./media:/home/web/media
+ - ./reports:/home/web/reports
+ - ./logs:/var/log/
+ links:
+ - smtp:smtp
+ - db:db
+ - rabbitmq:rabbitmq
+ restart: on-failure:5
+
+geoserver:
+ image: kartoza/geoserver
+ container_name: haitidata-geoserver
+ ports:
+ - "33308:8080"
diff --git a/deployment/sites-enabled/README.md b/deployment/sites-enabled/README.md
new file mode 100644
index 0000000..1372cc7
--- /dev/null
+++ b/deployment/sites-enabled/README.md
@@ -0,0 +1,4 @@
+This directory is used to contain nginx configuration
+when using a non dockergen nginx configuration.
+
+See docker-compose.yml to see how it is used.
diff --git a/deployment/sites-enabled/default.conf b/deployment/sites-enabled/default.conf
new file mode 100644
index 0000000..1d4fc7b
--- /dev/null
+++ b/deployment/sites-enabled/default.conf
@@ -0,0 +1,69 @@
+# Define connection details for connecting to django running in
+# a docker container.
+upstream uwsgi {
+ server uwsgi:8080;
+}
+
+upstream geoserver {
+ server geoserver:8080;
+}
+
+server {
+ # OTF gzip compression
+ gzip on;
+ gzip_min_length 860;
+ gzip_comp_level 5;
+ gzip_proxied expired no-cache no-store private auth;
+ gzip_types text/plain application/xml application/x-javascript text/xml text/css application/json;
+ gzip_disable “MSIE [1-6].(?!.*SV1)”;
+
+ access_log /var/log/nginx/access.log;
+ error_log /var/log/nginx/error.log;
+
+ # the port your site will be served on
+ listen 8080;
+ # the domain name it will serve for
+ # server_name staging.foss4g-africa.org;
+ charset utf-8;
+
+ # max upload size, adjust to taste
+ client_max_body_size 15M;
+ # Django media
+ location /media {
+ # your Django project's media files - amend as required
+ alias /home/web/media;
+ expires 21d; # cache for 71 days
+ }
+ location /static {
+ # your Django project's static files - amend as required
+ alias /home/web/static;
+ expires 21d; # cache for 21 days
+ }
+
+ location /api/geoserver/ {
+ proxy_pass http://geoserver/geoserver/;
+ }
+ # Finally, send all non-media requests to the Django server.
+ location / {
+ uwsgi_pass uwsgi;
+ # the uwsgi_params file you installed needs to be passed with each
+ # request.
+ # the uwsgi_params need to be passed with each uwsgi request
+ uwsgi_param QUERY_STRING $query_string;
+ uwsgi_param REQUEST_METHOD $request_method;
+ uwsgi_param CONTENT_TYPE $content_type;
+ uwsgi_param CONTENT_LENGTH $content_length;
+
+ uwsgi_param REQUEST_URI $request_uri;
+ uwsgi_param PATH_INFO $document_uri;
+ uwsgi_param DOCUMENT_ROOT $document_root;
+ uwsgi_param SERVER_PROTOCOL $server_protocol;
+ uwsgi_param HTTPS $https if_not_empty;
+
+ uwsgi_param REMOTE_ADDR $remote_addr;
+ uwsgi_param REMOTE_PORT $remote_port;
+ uwsgi_param SERVER_PORT $server_port;
+ uwsgi_param SERVER_NAME $server_name;
+ }
+
+}
diff --git a/deployment/staging.qgisug.nginx.conf b/deployment/staging.qgisug.nginx.conf
new file mode 100644
index 0000000..657515e
--- /dev/null
+++ b/deployment/staging.qgisug.nginx.conf
@@ -0,0 +1,29 @@
+upstream qgisug {
+ server 127.0.0.1:63300;
+}
+
+server {
+ # OTF gzip compression
+ gzip on;
+ gzip_min_length 860;
+ gzip_comp_level 5;
+ gzip_proxied expired no-cache no-store private auth;
+ gzip_types text/plain application/xml application/x-javascript text/xml text/css application/json;
+ gzip_disable “MSIE [1-6].(?!.*SV1)”;
+
+ # the port your site will be served on
+ listen 80
+ # the domain name it will serve for
+ # server_name staging.foss4g-africa.org;
+
+ charset utf-8;
+
+ # max upload size, adjust to taste
+ client_max_body_size 15M;
+
+ location / {
+ proxy_pass http://qgisug;
+ proxy_set_header Host $host;
+ proxy_set_header X-Forwarded-For $remote_addr;
+ }
+}
diff --git a/deployment/tag_and_deploy.sh b/deployment/tag_and_deploy.sh
new file mode 100755
index 0000000..9fb0fbc
--- /dev/null
+++ b/deployment/tag_and_deploy.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+echo "Use this to tag a version on your local"
+echo "machine, push the tag upstream and then"
+echo "deploy it to the remote"
+echo "e.g."
+echo "$0 version-1.2.3"
+VERSION=$1
+make dbbackup
+make mediasync
+git tag $VERSION
+git push --tags upstream
+ssh kartoza4 "cd /home/web/kartoza.com/deployment && git fetch --tags && git checkout $VERSION && make build && make kill && make web && make migrate && make collectstatic && make reload"
diff --git a/django_project/README.rst b/django_project/README.rst
new file mode 100644
index 0000000..c8492e3
--- /dev/null
+++ b/django_project/README.rst
@@ -0,0 +1,30 @@
+# Haitidata
+
+You should write some docs, it's good for the soul.
+
+# Docker installation
+
+## Install docker
+This will install an Haitidata container
+
+Makes sure to have docker-compose installed
+```
+sudo apt-get install python-pip
+sudo pip install docker-compose
+```
+
+## Get project code
+Clone the repo:
+```
+git clone https://github.com/HaitiData/haitidata.git
+```
+
+## Run project
+Run the docker container:
+```
+cd deployment
+make deploy
+make update-migrations-localization:
+```
+
+then you can visit http://0.0.0.0:33300```
\ No newline at end of file
diff --git a/haitidata/__init__.py b/django_project/__init__.py
similarity index 100%
rename from haitidata/__init__.py
rename to django_project/__init__.py
diff --git a/haitidata/static/css/bootstrap/mixins.css b/django_project/charts-prj/__init__.py
similarity index 100%
rename from haitidata/static/css/bootstrap/mixins.css
rename to django_project/charts-prj/__init__.py
diff --git a/django_project/charts-prj/settings.py b/django_project/charts-prj/settings.py
new file mode 100644
index 0000000..19b5894
--- /dev/null
+++ b/django_project/charts-prj/settings.py
@@ -0,0 +1,58 @@
+"""
+Django settings for charts project.
+
+Generated by 'django-admin startproject' using Django 1.8.7.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/1.8/topics/settings/
+
+For the full list of settings and their values, see
+https://docs.djangoproject.com/en/1.8/ref/settings/
+"""
+
+# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
+import os
+from geonode.settings import *
+
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+SITENAME = 'charts-prj'
+
+LOCAL_ROOT = os.path.abspath(os.path.dirname(__file__))
+
+# Quick-start development settings - unsuitable for production
+# See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/
+
+# SECURITY WARNING: keep the secret key used in production secret!
+SECRET_KEY = '*u(5zzp_wjj!^!w4$h@e#jv!*y02z17lb8gu-l)j+*79p^r8%('
+
+# SECURITY WARNING: don't run with debug turned on in production!
+DEBUG = True
+
+# Application definition
+
+INSTALLED_APPS = INSTALLED_APPS + (
+ 'charts_app',
+ 'wfs_harvest'
+)
+
+WSGI_APPLICATION = 'charts-prj.wsgi.application'
+
+# Additional directories which hold static files
+STATICFILES_DIRS.append(
+ os.path.join(LOCAL_ROOT, "static"),
+)
+
+# Location of url mappings
+ROOT_URLCONF = 'charts-prj.urls'
+
+# Location of locale files
+LOCALE_PATHS = (
+ os.path.join(LOCAL_ROOT, 'locale'),
+ ) + LOCALE_PATHS
+
+TEMPLATES[0]['DIRS'].insert(0, os.path.join(LOCAL_ROOT, "templates"))
+
+MAX_CSV_RECORDS = 20000
+
+ALLOWED_HOSTS = ['*']
+PROXY_ALLOWED_HOSTS = ['*']
diff --git a/haitidata/static/README b/django_project/charts-prj/static/README
similarity index 100%
rename from haitidata/static/README
rename to django_project/charts-prj/static/README
diff --git a/haitidata/static/css/bootstrap/mixins/alerts.css b/django_project/charts-prj/static/css/site_base.css
similarity index 100%
rename from haitidata/static/css/bootstrap/mixins/alerts.css
rename to django_project/charts-prj/static/css/site_base.css
diff --git a/haitidata/static/img/README b/django_project/charts-prj/static/img/README
similarity index 100%
rename from haitidata/static/img/README
rename to django_project/charts-prj/static/img/README
diff --git a/haitidata/static/js/README b/django_project/charts-prj/static/js/README
similarity index 100%
rename from haitidata/static/js/README
rename to django_project/charts-prj/static/js/README
diff --git a/django_project/charts-prj/templates/_actions.html b/django_project/charts-prj/templates/_actions.html
new file mode 100644
index 0000000..7e96144
--- /dev/null
+++ b/django_project/charts-prj/templates/_actions.html
@@ -0,0 +1,24 @@
+{% load i18n %}
+
+{% endcomment %}
+{% endblock %}
diff --git a/django_project/charts-prj/templates/site_index.html b/django_project/charts-prj/templates/site_index.html
new file mode 100644
index 0000000..b0d3f4e
--- /dev/null
+++ b/django_project/charts-prj/templates/site_index.html
@@ -0,0 +1,15 @@
+{% extends 'index.html' %}
+{% load i18n %}
+{% comment %}
+This is where you can override the hero area block. You can simply modify the content below or replace it wholesale to meet your own needs.
+{% endcomment %}
+ {% block hero %}
+
+
+
{% trans "Welcome to the charts GeoNode" %}
+
{% blocktrans %}GeoNode is an open source platform for sharing geospatial data and maps.{% endblocktrans %}
+
{% blocktrans %}If you have any questions about the software or service, join our mailing list.{% endblocktrans %}