This commit is contained in:
2026-01-21 15:58:45 -05:00
parent 93be937e67
commit 7019e34b7a
6 changed files with 275 additions and 22 deletions

View File

@ -6,3 +6,59 @@ DOMAIN=umap.example.com
#EXTRA_DOMAINS=', `www.umap.example.com`'
LETS_ENCRYPT_ENV=production
SECRET_SECRET_KEY_VERSION=v1 # length=100 charset=hex
SITE_URL=https://$DOMAIN
SITE_NAME=My UMap Server
SITE_DESCRIPTION=Welcome to my map of the world. No borders, no nations.
#UMAP_HELP_URL=http://mysite.com/documentation
#UMAP_HOME_FEED="highlighted"
## Account/Permissions
#ENABLE_ACCOUNT_LOGIN=1
#UMAP_ALLOW_ANONYMOUS=1
#UMAP_ALLOW_EDIT_PROFILE=0
#UMAP_DEFAULT_EDIT_STATUS=3
#UMAP_DEFAULT_SHARE_STATUS=3
## Language/Localization
#USE_I18N=false
#LANGUAGE_CODE="it"
#LEAFLET_LONGITUDE="15"
#LEAFLET_LATITUDE="15"
#LEAFLET_ZOOM="5"
#UMAP_DEMO_SITE=1
#UMAP_READONLY=1
#UMAP_MAPS_PER_PAGE=10
#UMAP_MAPS_PER_SEARCH=10
#UMAP_MAPS_PER_PAGE_OWNER=10
#UMAP_LABEL_KEYS='["name", "title"]'
#DEBUG=true
#UMAP_GZIP=1
#SHORT_SITE_URL=
#UMAP_KEEP_VERSIONS=10
# OPENROUTESERVICE_APIKEY=WIP
## Email Settings
#DEFAULT_FROM_EMAIL = "youradmin@email.org"
#EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
#EMAIL_HOST = "smtp.provider.org"
#EMAIL_PORT = 456
#EMAIL_HOST_USER = "username"
#EMAIL_HOST_PASSWORD = "xxxx"
#EMAIL_USE_TLS = True
#EMAIL_USE_SSL = True
## OpenStreetMaps OAuth
# WIP
#SOCIAL_AUTH_OPENSTREETMAP_OAUTH2_KEY, SOCIAL_AUTH_OPENSTREETMAP_OAUTH2_SECRET
## General OAuth
# WIP
#https://python-social-auth.readthedocs.io/en/latest/configuration/django.html
#USER_DISPLAY_NAME=
#USER_URL_FIELD=

View File

@ -1,2 +1,6 @@
# Set any config versions here
# Docs: https://docs.coopcloud.tech/maintainers/handbook/#manage-configs
export CONFIG_VERSION=v1
export NGINX_VERSION=v1
export NGINX_UMAP_VERSION=v1

View File

@ -1,39 +1,116 @@
---
services:
app:
image: nginx:1.27.5
proxy:
image: nginx:1.29.4
deploy:
labels:
- "traefik.enable=true"
- "traefik.docker.network=proxy"
- "traefik.http.services.${STACK_NAME}.loadbalancer.server.port=80"
- "traefik.http.routers.${STACK_NAME}.rule=Host(`${DOMAIN}`${EXTRA_DOMAINS})"
- "traefik.http.routers.${STACK_NAME}.entrypoints=web-secure"
- "traefik.http.routers.${STACK_NAME}.tls.certresolver=${LETS_ENCRYPT_ENV}"
## Edit the following line if you are using one, but not both, "Redirect" sections below
#- "traefik.http.routers.${STACK_NAME}.middlewares=${STACK_NAME}-redirectscheme,${STACK_NAME}-redirecthostname"
## Redirect from EXTRA_DOMAINS to DOMAIN
# - "traefik.http.middlewares.${STACK_NAME}-redirecthostname.redirectregex.regex=^http[s]?://([^/]*)/(.*)"
# - "traefik.http.middlewares.${STACK_NAME}-redirecthostname.redirectregex.replacement=https://${DOMAIN}/$${2}"
# - "traefik.http.middlewares.${STACK_NAME}-redirecthostname.redirectregex.permanent=true"
## Redirect HTTP to HTTPS
# - "traefik.http.middlewares.${STACK_NAME}-redirectscheme.redirectscheme.scheme=https"
# - "traefik.http.middlewares.${STACK_NAME}-redirectscheme.redirectscheme.permanent=true"
volumes:
- static:/static:ro
- data:/data:ro
configs:
- source: nginx
target: /etc/nginx/nginx.conf
mode: 0600
- source: nginx_umap
target: /etc/nginx/snippets/umap.conf
mode: 0600
networks:
- proxy
- umap
umap:
image: umap/umap:3.5.0
networks:
- umap
deploy:
restart_policy:
condition: on-failure
labels:
- "traefik.enable=true"
- "traefik.http.services.${STACK_NAME}.loadbalancer.server.port=80"
- "traefik.http.routers.${STACK_NAME}.rule=Host(`${DOMAIN}`${EXTRA_DOMAINS})"
- "traefik.http.routers.${STACK_NAME}.entrypoints=web-secure"
- "traefik.http.routers.${STACK_NAME}.tls.certresolver=${LETS_ENCRYPT_ENV}"
## Edit the following line if you are using one, but not both, "Redirect" sections below
#- "traefik.http.routers.${STACK_NAME}.middlewares=${STACK_NAME}-redirectscheme,${STACK_NAME}-redirecthostname"
## Redirect from EXTRA_DOMAINS to DOMAIN
# - "traefik.http.middlewares.${STACK_NAME}-redirecthostname.redirectregex.regex=^http[s]?://([^/]*)/(.*)"
# - "traefik.http.middlewares.${STACK_NAME}-redirecthostname.redirectregex.replacement=https://${DOMAIN}/$${2}"
# - "traefik.http.middlewares.${STACK_NAME}-redirecthostname.redirectregex.permanent=true"
## Redirect HTTP to HTTPS
# - "traefik.http.middlewares.${STACK_NAME}-redirectscheme.redirectscheme.scheme=https"
# - "traefik.http.middlewares.${STACK_NAME}-redirectscheme.redirectscheme.permanent=true"
## When you're ready for release, run "abra recipe sync <name>" to set this
- "coop-cloud.${STACK_NAME}.version="
- "coop-cloud.${STACK_NAME}.version=0.0.1+2.9.3"
## Enable backups: https://docs.coopcloud.tech/maintainers/handbook/#how-do-i-configure-backuprestore
# - "backupbot.backup=true"
# - "backupbot.backup.path=/some/path"
environment:
DATABASE_URL: postgis://postgres@db/postgres
STATIC_ROOT: /srv/umap/static
MEDIA_ROOT: /srv/umap/uploads
REALTIME_ENABLED: 1
REDIS_URL: redis://redis:6379
ALLOWED_HOSTS: $DOMAIN
volumes:
- data:/srv/umap/uploads
- static:/srv/umap/static
configs:
- source: config
target: /etc/umap/umap.conf
mode: 0600
secrets:
- secret_key
# healthcheck:
# test: ["CMD", "curl", "-f", "http://localhost:9000"]
# interval: 30s
# timeout: 10s
# retries: 10
# start_period: 1m
db:
image: postgis/postgis:14-3.4-alpine
networks:
- umap
environment:
- POSTGRES_HOST_AUTH_METHOD=trust
volumes:
- db:/var/lib/postgresql/data
redis:
image: redis:8.4.0
command: ["redis-server"]
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 30s
timeout: 10s
retries: 10
start_period: 1m
test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
networks:
- umap
volumes:
data:
static:
db:
secrets:
secret_key:
external: true
name: ${STACK_NAME}_secret_key_${SECRET_SECRET_KEY_VERSION}
configs:
config:
name: ${STACK_NAME}_config_${CONFIG_VERSION}
file: ./umap.conf.tmpl
template_driver: golang
nginx:
name: ${STACK_NAME}_nginx_${NGINX_VERSION}
file: ./nginx.conf.tmpl
template_driver: golang
nginx_umap:
name: ${STACK_NAME}_nginx_umap_${NGINX_UMAP_VERSION}
file: ./nginx-umap.conf
template_driver: golang
networks:
umap:
proxy:
external: true

67
nginx-umap.conf Normal file
View File

@ -0,0 +1,67 @@
# 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;
}

47
nginx.conf.tmpl Normal file
View File

@ -0,0 +1,47 @@
events {
worker_connections 1024; # Adjust this to your needs
}
http {
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;
}
types {
application/javascript mjs;
}
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
# Server block
server {
listen 80;
server_name localhost;
include "/etc/nginx/snippets/umap.conf";
# Proxy pass to ASGI server
location / {
proxy_pass http://umap:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_redirect off;
proxy_buffering off;
}
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log warn;
}
}

2
umap.conf.tmpl Normal file
View File

@ -0,0 +1,2 @@
SECRET_KEY='{{ secret "secret_key" }}'
ALLOWED_HOSTS=[ '{{ env "DOMAIN" }}{{ env "EXTRA_DOMAINS" }}' ]