Deploying uMap with Dokku⚓︎
You must have a Dokku host up and running. This can be either self hosted, or from a provider.
To set up Dokku on your own server, see https://dokku.com/docs/getting-started/installation/
Dokku has several deployement method, in this guide we'll use the Docker based one, using our maintained Dockerfile.
Installation⚓︎
Prepare the host⚓︎
We need postgres and redis plugins:
sudo dokku plugin:install https://github.com/dokku/dokku-postgres.git --name postgres
sudo dokku plugin:install https://github.com/dokku/dokku-redis.git --name redis
Note: if you do not use the real time collaboration feature, you can skip the redis part.
Create the umap app (or name it as you prefer), and posgis and redis services:
dokku apps:create umap
dokku postgres:create umap --image "postgis/postgis" --image-version "18-3.6-alpine"
dokku postgres:link umap umap
dokku redis:create umap
dokku redis:link umap umap
Create a folder for user data (mainly layers) and static files:
sudo mkdir /var/lib/dokku/data/storage/umap-data
dokku storage:mount umap /var/lib/dokku/data/storage/umap-data:/srv/umap/uploads
sudo mkdir /var/lib/dokku/data/storage/umap-static
dokku storage:mount umap /var/lib/dokku/data/storage/umap-static:/srv/umap/static
Expose the app to the Internet and add a SSL certificate:
dokku domains:set-global dokku.yourdoma.in
dokku config:set umap CSRF_TRUSTED_ORIGINS=https://umap.dokku.yourdoma.in
dokku ports:set umap http:80:8000
sudo dokku plugin:install https://github.com/dokku/dokku-letsencrypt.git
dokku letsencrypt:enable umap
dokku letsencrypt:cron-job --add
Note: we are using Letsencrypt here, see Dokku's doc for a custom certificate.
Configure via env vars:
dokku config:set --no-restart umap SECRET_KEY=something-random-and-unique
Nginx configuration⚓︎
Nginx configuration for uMap is a bit tricky, and we don't want to replace the nginx conf managed by Dokku, so it requires some manual changes.
Some changes need to be added to the http section of the nginx conf.
Create a file at /etc/nginx/conf.d/umap-http.conf with this content:
proxy_cache_path /tmp/nginx_ajax_proxy_cache levels=1:2 keys_zone=ajax_proxy:10m inactive=60m;
proxy_cache_key "$uri$is_args$args";
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
Other need to be integrated in the server section.
So, create a file at /home/dokku/umap/nginx.conf.d/umap.conf, with this content, but
adapt the alias to match the volumes created above (/static/ => /var/lib/dokku/data/storage/umap-static,
/data/ => /var/lib/dokku/data/storage/umap-data):
# Static file serving
location /static/ {
alias /static/;
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_types text/plain application/javascript application/x-javascript text/javascript text/xml text/css;
expires 365d;
access_log /dev/null;
}
# Geojson files
location /uploads/ {
alias /data/;
expires 30d;
}
location /favicon.ico {
alias /static/favicon.ico;
}
# X-Accel-Redirect
location /internal/ {
internal;
gzip_vary on;
gzip_static on;
add_header X-DataLayer-Version $upstream_http_x_datalayer_version;
alias /data/;
}
# Ajax proxy
location ~ ^/proxy/(.*) {
internal;
add_header X-Proxy-Cache $upstream_cache_status always;
proxy_cache_background_update on;
proxy_cache_use_stale updating;
proxy_cache ajax_proxy;
proxy_cache_valid 1m; # Default. Umap will override using X-Accel-Expires
set $target_url $1;
# URL is encoded, so we need a few hack to clean it back.
if ( $target_url ~ (.+)%3A%2F%2F(.+) ){ # fix :// between scheme and destination
set $target_url $1://$2;
}
if ( $target_url ~ (.+?)%3A(.*) ){ # fix : between destination and port
set $target_url $1:$2;
}
if ( $target_url ~ (.+?)%2F(.*) ){ # fix / after port, the rest will be decoded by proxy_pass
set $target_url $1/$2;
}
resolver 8.8.8.8;
add_header X-Proxy-Target $target_url; # For debugging
proxy_pass_request_headers off;
proxy_set_header Content-Type $http_content_type;
proxy_set_header Content-Encoding $http_content_encoding;
proxy_set_header Content-Length $http_content_length;
proxy_read_timeout 10s;
proxy_connect_timeout 5s;
proxy_ssl_server_name on;
proxy_pass $target_url;
proxy_intercept_errors on;
error_page 301 302 307 = @handle_proxy_redirect;
}
location @handle_proxy_redirect {
resolver 8.8.8.8;
set $saved_redirect_location '$upstream_http_location';
proxy_pass $saved_redirect_location;
}
OAuth configuration⚓︎
As an example, we'll use OpenStreetMap OAuth, but it's possible to use whatever service supported by python-social-auth.
You need to create an OAuth client here:
https://www.openstreetmap.org/oauth2/applications
The redirect URL should look like:
https://umap.dokku.yourdoma.in/complete/openstreetmap-oauth2/
You must select Read user preferences and Sign in using OpenStreetMap permissions.
And get the client key and secret and set them in Dokku like this:
dokku config:set --no-restart umap SOCIAL_AUTH_OPENSTREETMAP_OAUTH2_KEY=somekey
dokku config:set --no-restart umap SOCIAL_AUTH_OPENSTREETMAP_OAUTH2_SECRET=somesecret
dokku config:set umap SOCIAL_AUTH_REDIRECT_IS_HTTPS=1
More settings⚓︎
If you want real time collaboration:
dokku config:set umap REALTIME_ENABLED=1
If you want to control whether anonymous users can create maps:
dokku config:set umap UMAP_ALLOW_ANONYMOUS=0/1
See settings.
On your local machine⚓︎
To deploy, you need to clone umap locally, and push to Dokku, just like you'd push to github or the like.
On uMap git repository, add a remote (here name dokku, but it's up to you)
and push there the master branch (or whatever branch you want):
git remote add dokku dokku@yourdokku.com:yourproject
git push dokku master
Troubleshooting⚓︎
See the logs, on the host:
dokku logs umap
Start a shell session on the umap Docker container:
dokku enter umap