From 07e6b62012572a2b5dbbba09d3d95a01ee988fc8 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Sat, 10 Sep 2016 16:21:09 +0200 Subject: [PATCH] Ubuntu installation turorial draft --- docs/ubuntu.md | 304 ++++++++++++++++++++++++++++++++++ mkdocs.yml | 2 + umap/settings/base.py | 2 + umap/settings/local.py.sample | 15 +- umap/wsgi.py | 2 +- 5 files changed, 318 insertions(+), 7 deletions(-) create mode 100644 docs/ubuntu.md diff --git a/docs/ubuntu.md b/docs/ubuntu.md new file mode 100644 index 00000000..cdbfb278 --- /dev/null +++ b/docs/ubuntu.md @@ -0,0 +1,304 @@ +# Tutorial + +This tutorial will cover an installation from scratch of a uMap instance in an Ubuntu server. + +You need sudo grants on this server, and it must be connected to Internet. + +## Install system dependencies + + sudo apt install python3.5 python3.5-dev python-virtualenv wget nginx uwsgi uwsgi-plugin-python3 postgresql-9.5 postgresql-9.5-postgis-2.2 git + + +*Note: uMap also works with python 2.7 and 3.4, so adapt the package names if you work with another version.* + + +## Create a deployment directory: + + sudo mkdir -p /srv/umap + +*You can change this path, but then remember to adapt the other steps accordingly.* + + +## Create a Unix user + + sudo useradd -N umap -d /srv/umap/ + +*Here we use the name `umap`, but this name is up to you. Remember to change it +on the various commands and configuration files if you go with your own.* + + +## Create a postgresql user + + sudo -u postgres createuser umap + + +## Create a postgresql database + + sudo -u postgres createdb umap -O umap + + +## Activate PostGIS extension + + sudo -u postgres psql umap -c "CREATE EXTENSION postgis" + + +## Login as umap Unix user + + sudo -u umap -i + +From now on, unless we say differently, the commands are run as `umap` user. + + +## Create a virtualenv and activate it + + virtualenv /srv/umap/venv --python=/usr/bin/python3.5 + source /srv/umap/venv/bin/activate + +*Note: this activation is not persistent, so if you open a new terminal window, +you will need to run again this last line.* + + +## Install umap + + pip install umap + + +## Create a local configuration file + + wget https://raw.githubusercontent.com/umap-project/umap/master/umap/settings/local.py.sample -O /srv/umap/local.py + +Now we need to inform umap about it. +We'll create an environment variable for that: + + export UMAP_SETTINGS=/srv/umap/local.py + +*Note: this variable will not be persistent if you quit your current terminal session, so +remember to rerun this command if you open a new terminal window.* + +## Create the tables + + umap migrate + +## Collect the statics + + umap collectstatic + +## Create a superuser + + umap createsuperuser + +## Start the demo server + + umap runserver 0.0.0.0:8000 + +## Add at least one license + +Go to [http://localhost:8000/admin/leaflet_storage/licence/add/](http://localhost:8000/admin/leaflet_storage/licence/add/) and create +a new Licence object. +For example: + +- name: `ODbL` +- URL: `http://opendatacommons.org/licenses/odbl/` + +## Add at least one tilelayer + +Go to [http://localhost:8000/admin/leaflet_storage/tilelayer/add/](http://localhost:8000/admin/leaflet_storage/tilelayer/add/) and create +a new TileLayer object. + +For example: + +- name: `Positron` +- URL template: `https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png` +- attribution: `© [[http://www.openstreetmap.org/copyright|OpenStreetMap]] contributors, © [[https://carto.com/attributions|CARTO]]` + +You can now go to [http://localhost:8000/](http://localhost:8000/) and try to create a map for testing. + +When you're done with testing, quit the demo server (type Ctrl-C). + + +## Configure the HTTP API + +Now let's configure a proper HTTP server. + +### uWSGI + +Create a file named `/srv/umap/uwsgi_params`, with this content +(without making any change on it): + +``` +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 REQUEST_SCHEME $scheme; +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; +``` + +Then create a configuration file for uWSGI: + + nano /srv/umap/uwsgi.ini + +And paste this content. Double check paths and user name in case you +have customized some of them during this tutorial. If you followed all the bits of the +tutorial without making any change, you can use it as is: + +``` +[uwsgi] +uid = umap +gid = users +# Python related settings +# the base directory (full path) +chdir = /srv/umap/ +# umap's wsgi module +module = umap.wsgi +# the virtualenv (full path) +home = /srv/umap/venv +# the local settings path +env = UMAP_SETTINGS=/srv/umap/local.py + +# process-related settings +# master +master = true +# maximum number of worker processes +processes = 4 +# the socket (use the full path to be safe +socket = /srv/umap/uwsgi.sock +# ... with appropriate permissions - may be needed +chmod-socket = 666 +stats = /srv/umap/stats.sock +# clear environment on exit +vacuum = true +plugins = python3 + +``` + +### Nginx + +Create a new file: + + nano /srv/umap/nginx.conf + +with this content: + +``` +# the upstream component nginx needs to connect to +upstream umap { + server unix:///srv/umap/uwsgi.sock; +} + +# configuration of the server +server { + # the port your site will be served on + listen 80; + listen [::]:80; + listen 443 ssl; + listen [::]:443 ssl; + # the domain name it will serve for + server_name your-domain.org; + charset utf-8; + + # max upload size + client_max_body_size 5M; # adjust to taste + + # Finally, send all non-media requests to the Django server. + location / { + uwsgi_pass umap; + include /srv/umap/uwsgi_params; + } +} +``` + +Remember to adapt the domain name. + +### Activate and restart the services + +Now quit the `umap` session, simply by typing ctrl+D. + +You should now be logged in as your normal user, which is sudoer. + +- Activate the Nginx configuration file: + + sudo ln -s /srv/umap/nginx.conf /etc/nginx/sites-enabled/umap + +- Activate the uWSGI configuration file: + + sudo ln -s /srv/umap/uwsgi.ini /etc/uwsgi/apps-enabled/umap.ini + +- Restart both services: + + sudo systemctl restart uwsgi nginx + + +Now you should access your server through your url and create maps: + + http://yourdomain.org/ + + +Congratulations! + +- - - + +## Troubleshooting + +- Nginx logs are in /var/log/nginx/: + + sudo tail -f /var/log/nginx/error.log + sudo tail -f /var/log/nginx/access.log + +- uWSGI logs are in /var/log/uwsgi: + + sudo tail -f /var/log/uwsgi/umap.log + + +## Before going live + +### Add a real SECRET_KEY + +In your local.py file, add a real secret and unique `SECRET_KEY`, and do +not share it. + +### Remove DEMO flag + +In your local.py: + + UMAP_DEMO_SITE = False + DEBUG = False + +### Configure social auth + +Now you can login with your superuser, but you may allow users to user social +authentication. + +### Configure default map center + +In your local.py change those settings: + + LEAFLET_LONGITUDE = 2 + LEAFLET_LATITUDE = 51 + LEAFLET_ZOOM = 6 + +### Activate statics compression + +In your local.py, set `COMPRESS_ENABLED = True`, and then run the following command + + umap compress + + +### Configure the site URL and short URL + +In your local.py: + + SITE_URL = "http://localhost:8019" + SHORT_SITE_URL = "http://s.hort" + +Also adapt `ALLOWED_HOSTS` accordingly. diff --git a/mkdocs.yml b/mkdocs.yml index b98b75b2..8f69ea69 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -3,4 +3,6 @@ pages: - Home: index.md - Installation: install.md - Contributing: contributing.md +- how-tos: + - Ubuntu from scratch: ubuntu.md theme: readthedocs diff --git a/umap/settings/base.py b/umap/settings/base.py index 1cbe5cfd..501af645 100644 --- a/umap/settings/base.py +++ b/umap/settings/base.py @@ -75,6 +75,7 @@ PROJECT_DIR = os.path.dirname(os.path.realpath(project_module.__file__)) # ============================================================================= ROOT_URLCONF = 'umap.urls' +WSGI_APPLICATION = 'umap.wsgi.application' LOGIN_URL = '/login/' LOGOUT_URL = '/logout/' @@ -86,6 +87,7 @@ MEDIA_URL = '/uploads/' STATIC_ROOT = os.path.join('static') MEDIA_ROOT = os.path.join('uploads') + STATICFILES_DIRS = ( os.path.join(PROJECT_DIR, 'static'), ) diff --git a/umap/settings/local.py.sample b/umap/settings/local.py.sample index c74756fa..16fd030e 100644 --- a/umap/settings/local.py.sample +++ b/umap/settings/local.py.sample @@ -11,7 +11,7 @@ your code repository. from umap.settings.base import * # pylint: disable=W0614,W0401 -SECRET_KEY = '' +SECRET_KEY = '!!change me!!' INTERNAL_IPS = ('127.0.0.1', ) ALLOWED_HOSTS = ['*', ] @@ -30,8 +30,6 @@ DATABASES = { } } -WSGI_APPLICATION = 'umap.wsgi.application' - COMPRESS_ENABLED = False COMPRESS_OFFLINE = True @@ -64,11 +62,16 @@ MIDDLEWARE_CLASSES += ( SOCIAL_AUTH_RAISE_EXCEPTIONS = False SOCIAL_AUTH_BACKEND_ERROR_URL = "/" +# If you want to add a playgroud map, add its primary key # UMAP_DEMO_PK = 204 +# If you want to add a showcase map on the home page, add its primary key # UMAP_SHOWCASE_PK = 1156 -LEAFLET_STORAGE_ALLOW_ANONYMOUS = True +# Add a baner to warn people this instance is not production ready. UMAP_DEMO_SITE = True +# Whether to allow non authenticated people to create maps. +LEAFLET_STORAGE_ALLOW_ANONYMOUS = True + # This setting will exclude empty maps (in fact, it will exclude all maps where # the default center has not been updated) UMAP_EXCLUDE_DEFAULT_MAPS = False @@ -97,10 +100,10 @@ EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' UMAP_USE_UNACCENT = False # For static deployment -STATIC_ROOT = '/home/umap/.virtualenvs/umap/var/static' +STATIC_ROOT = '/home/srv/var/static' # For users' statics (geojson mainly) -MEDIA_ROOT = '/home/umap/.virtualenvs/umap/var/uploads' +MEDIA_ROOT = '/home/srv/umap/var/data' # Default map location for new maps LEAFLET_LONGITUDE = 2 diff --git a/umap/wsgi.py b/umap/wsgi.py index 0db32cfa..89db657f 100644 --- a/umap/wsgi.py +++ b/umap/wsgi.py @@ -16,7 +16,7 @@ framework. import os os.environ.setdefault("DJANGO_SETTINGS_MODULE", - "umap.settings.local") + "umap.settings") # This application object is used by any WSGI server configured to use this # file. This includes Django's development server, if the WSGI_APPLICATION