commit 4cb30fca865a1c5b8570642dfcef71f5a974ac93 Author: Pim van den Berg Date: Fri Nov 18 16:06:31 2022 +0100 init diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..4305edb --- /dev/null +++ b/Dockerfile @@ -0,0 +1,38 @@ +FROM python:3.8-slim + +RUN set -eux && \ + mkdir -p /srv/umap /etc/umap /srv/umap/data /srv/umap/uploads && \ + useradd -N umap -d /srv/umap/ -s /bin/bash && \ + chown -R umap:users /etc/umap /srv/umap && \ + apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + python3-virtualenv \ + build-essential \ + libpq-dev \ + python3.9-dev \ + gdal-bin \ + uwsgi \ + uwsgi-plugin-python3 \ + && \ + su - umap -c "virtualenv /srv/umap/venv --python=/usr/bin/python3.9" && \ + su - umap -c "source /srv/umap/venv/bin/activate; pip install umap-project django-environ==0.9.0 django-redis==4.7.0" && \ + sed -i 's/ value="{{ q|default:"" }}"//' /srv/umap/venv/lib/python3.9/site-packages/umap/templates/umap/search_bar.html && \ + apt-get purge -y build-essential libpq-dev python3.9-dev && \ + apt-get autoremove --purge -y && \ + rm -rf /var/lib/apt/lists/* + +ADD umap.conf /etc/umap/umap.conf +ADD uwsgi.ini /srv/umap/uwsgi.ini +ADD drop-privileges.sh /srv/umap/drop-privileges.sh +ADD docker-entrypoint.sh /srv/umap/docker-entrypoint.sh + +EXPOSE 8000/tcp + +# Add Tini +ENV TINI_VERSION v0.14.0 +ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini +RUN chmod +x /tini + +ENTRYPOINT ["/tini", "--"] + +CMD ["/srv/umap/docker-entrypoint.sh"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..40cdcca --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,31 @@ +version: '3' +services: + db: + image: postgis/postgis:12-3.3 + environment: + - POSTGRES_HOST_AUTH_METHOD=trust + volumes: + - db:/var/lib/postgresql/data + + redis: + image: redis:latest + + app: + image: pommib/umap:1.2.3 + ports: + - "8000:8000" + environment: + - DATABASE_URL=postgis://postgres@db/postgres + - REDIS_URL=redis://redis:6379/0 + - SECRET_KEY=some-long-and-weirdly-unrandom-secret-key + - ALLOWED_HOSTS=* + - SITE_URL=https://umap.somewhere.nl/ + - LEAFLET_STORAGE_ALLOW_ANONYMOUS=True + depends_on: + - db + - redis + # command: "tail -F anything" + +volumes: + db: + uploads: diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh new file mode 100755 index 0000000..12db2aa --- /dev/null +++ b/docker-entrypoint.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +set -eo pipefail + +# default variables +: "${SLEEP:=1}" +: "${TRIES:=60}" + +function wait_for_database {( + echo "Waiting for database to respond..." + tries=0 + while true; do + [[ $tries -lt $TRIES ]] || return + (echo "from django.db import connection; connection.connect()" | umap shell) >/dev/null + [[ $? -eq 0 ]] && return + sleep $SLEEP + tries=$((tries + 1)) + done +)} + +source /srv/umap/venv/bin/activate + +# first wait for the database +wait_for_database +# then migrate the database +umap migrate +# then collect static files +umap collectstatic --noinput +# create languagae files +#umap storagei18n +# compress static files +umap compress +# run uWSGI +exec uwsgi --ini /srv/umap/uwsgi.ini diff --git a/drop-privileges.sh b/drop-privileges.sh new file mode 100755 index 0000000..f750bcf --- /dev/null +++ b/drop-privileges.sh @@ -0,0 +1,2 @@ +#!/bin/sh +exec su -l umap -c "/bin/bash /srv/umap/docker-entrypoint.sh" diff --git a/umap.conf b/umap.conf new file mode 100644 index 0000000..097a35d --- /dev/null +++ b/umap.conf @@ -0,0 +1,155 @@ +# -*- coding:utf-8 -*- +""" +Settings for Docker development + +Use this file as a base for your local development settings and copy +it to umap/settings/local.py. It should not be checked into +your code repository. +""" +import environ +from umap.settings.base import * # pylint: disable=W0614,W0401 + +env = environ.Env() + +SECRET_KEY = env('SECRET_KEY') +INTERNAL_IPS = env.list('INTERNAL_IPS', default='127.0.0.1') +ALLOWED_HOSTS = env.list('ALLOWED_HOSTS', default='*') + +DEBUG = env.bool('DEBUG', default=False) + +ADMIN_EMAILS = env.list('ADMIN_EMAIL', default='') +ADMINS = [(email, email) for email in ADMIN_EMAILS] +MANAGERS = ADMINS + +DATABASES = { + 'default': env.db(default='postgis://localhost:5432/umap') +} + +COMPRESS_ENABLED = True +COMPRESS_OFFLINE = True + +LANGUAGE_CODE = 'en' + +# Set to False if login into django account should not be possible. You can +# administer accounts in the admin interface. +ENABLE_ACCOUNT_LOGIN = env.bool('ENABLE_ACCOUNT_LOGIN', default=True) + +AUTHENTICATION_BACKENDS = () + +# We need email to associate with other Oauth providers +SOCIAL_AUTH_GITHUB_SCOPE = ['user:email'] +SOCIAL_AUTH_GITHUB_KEY = env('GITHUB_KEY', default='') +SOCIAL_AUTH_GITHUB_SECRET = env('GITHUB_SECRET', default='') +if SOCIAL_AUTH_GITHUB_KEY and SOCIAL_AUTH_GITHUB_SECRET: + AUTHENTICATION_BACKENDS += ( + 'social_core.backends.github.GithubOAuth2', + ) +SOCIAL_AUTH_BITBUCKET_KEY = env('BITBUCKET_KEY', default='') +SOCIAL_AUTH_BITBUCKET_SECRET = env('BITBUCKET_SECRET', default='') +if SOCIAL_AUTH_BITBUCKET_KEY and SOCIAL_AUTH_BITBUCKET_SECRET: + AUTHENTICATION_BACKENDS += ( + 'social_core.backends.bitbucket.BitbucketOAuth', + ) + +SOCIAL_AUTH_TWITTER_KEY = env('TWITTER_KEY', default='') +SOCIAL_AUTH_TWITTER_SECRET = env('TWITTER_SECRET', default='') +if SOCIAL_AUTH_TWITTER_KEY and SOCIAL_AUTH_TWITTER_SECRET: + AUTHENTICATION_BACKENDS += ( + 'social_core.backends.twitter.TwitterOAuth', + ) +SOCIAL_AUTH_OPENSTREETMAP_KEY = env('OPENSTREETMAP_KEY', default='') +SOCIAL_AUTH_OPENSTREETMAP_SECRET = env('OPENSTREETMAP_SECRET', default='') +if SOCIAL_AUTH_OPENSTREETMAP_KEY and SOCIAL_AUTH_OPENSTREETMAP_SECRET: + AUTHENTICATION_BACKENDS += ( + 'social_core.backends.openstreetmap.OpenStreetMapOAuth', + ) + +AUTHENTICATION_BACKENDS += ( + 'django.contrib.auth.backends.ModelBackend', +) + +# MIDDLEWARE_CLASSES += ( +# 'social_django.middleware.SocialAuthExceptionMiddleware', +# ) + +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 +# Add a baner to warn people this instance is not production ready. +UMAP_DEMO_SITE = False + +# Whether to allow non authenticated people to create maps. +LEAFLET_STORAGE_ALLOW_ANONYMOUS = env.bool( + 'LEAFLET_STORAGE_ALLOW_ANONYMOUS', + default=False, +) + +# 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 + +# How many maps should be showcased on the main page resp. on the user page +UMAP_MAPS_PER_PAGE = 0 +# How many maps should be showcased on the user page, if owner +UMAP_MAPS_PER_PAGE_OWNER = 10 + +SITE_URL = env('SITE_URL') +SHORT_SITE_URL = env('SHORT_SITE_URL', default=None) + +CACHES = {'default': env.cache('REDIS_URL', default='locmem://')} + +# POSTGIS_VERSION = (2, 1, 0) +EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' + +# You need to unable accent extension before using UMAP_USE_UNACCENT +# python manage.py dbshell +# CREATE EXTENSION unaccent; +UMAP_USE_UNACCENT = False + +# For static deployment +STATIC_ROOT = '/srv/umap/static' + +# For users' statics (geojson mainly) +MEDIA_ROOT = '/srv/umap/uploads' + +# Default map location for new maps +LEAFLET_LONGITUDE = env.int('LEAFLET_LONGITUDE', default=2) +LEAFLET_LATITUDE = env.int('LEAFLET_LATITUDE', default=51) +LEAFLET_ZOOM = env.int('LEAFLET_ZOOM', default=6) + +# Number of old version to keep per datalayer. +LEAFLET_STORAGE_KEEP_VERSIONS = env.int( + 'LEAFLET_STORAGE_KEEP_VERSIONS', + default=10, +) + +import sys + +LOGGING = { + 'version': 1, + 'disable_existing_loggers': False, + 'formatters': { + 'verbose': { + 'format': '[django] %(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s' + } + }, + 'handlers': { + 'console': { + 'level': 'DEBUG', + 'class': 'logging.StreamHandler', + 'stream': sys.stdout, + 'formatter': 'verbose' + }, + }, + 'loggers': { + 'django': { + 'handlers': ['console'], + 'level': 'DEBUG', + 'propagate': True, + }, + }, +} diff --git a/uwsgi.ini b/uwsgi.ini new file mode 100644 index 0000000..755cb81 --- /dev/null +++ b/uwsgi.ini @@ -0,0 +1,25 @@ +[uwsgi] +uid = umap +gid = users +enable-threads = true +http-socket = :8000 + +# 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 + +static-map = /static=/srv/umap/static +static-map = /uploads=/srv/umap/uploads + +# process-related settings +# master +master = true +# maximum number of worker processes +processes = 4 +# clear environment on exit +vacuum = true +plugins = python3