uMap 開源版「我的地圖」伺服器架設教學 (Docker compose) === ###### tags: `Linux` `uMap` `Docker` 作者:魏礼謙 撰寫於 2025.07.18 本文採用 [CC-BY-NC-SA 4.0 條款授權](https://creativecommons.org/licenses/by-nc-sa/4.0/),文內引用的參考資料著作權屬於原作者。 ## Preface 前言 uMap 是一款開源的地圖伺服器,可以用來瀏覽及存放個人的地理資料,也可以簡單理解成「Google 我的地圖」的開源版替代方案。 第一次接觸 uMap 的朋友,可以先去 [uMap 的官網](https://umap-project.org/)逛逛,還有試用看看其他單位建立好的地圖伺服器,如果看完確定想要自己搭建一個私人地圖資料庫,再請繼續讀本文。 其實對大多數人而言,比起 uMap,「Google 我的地圖」是個相當容易上手的工具,因為: 1. 是 Google 的服務,可以直接用網頁或 Google 地圖 App 瀏覽,很方便。 2. 地圖資料編輯介面非常簡單。 但是,(對我來說的) 缺點是: 1. 各圖層的資料比數上限太小 (我的資料量很大)。 2. 資料點打開後的檢視效果不佳,尤其是附加圖片資料,或是在手機 App 上瀏覽的效果。 因此,我決定採用 uMap 自架伺服器的方式,管理手上數量龐大的地理資料。如果你的需求跟我很類似,也推薦你嘗試看看。 ## Requirement 需求 以下是架設 uMap 伺服器需要的東西: - 準備一台要用來安裝 uMap 伺服器的電腦 - 需具有 Docker compose 環境 - 一個給 uMap 伺服器用的網域名稱 - 例如:umap.your.domain - 有網路連線 (廢話) ## Server Installation 伺服器安裝 這邊採用 Docker compose 的方式安裝,首先要準備好相關的資料夾和 docker-compose.yml 其中,`app` 的 `SECRET_KEY` 密鑰要自行產生: ``` python3 -c 'import secrets; print(secrets.token_hex(100))' ``` ### ==docker-compose.yml== 參考:[官方 Github 的 docker-compose.yml 模板文件](https://github.com/umap-project/umap/blob/master/docker-compose.yml) <details> <summary>docker-compose.yml 的內容</summary> ```yaml= # 這是最主要的 docker-compose.yml 檔案內容,請按個人需求自行調整。 services: # Usefull only to use the real time collaboration redis: image: redis:latest healthcheck: test: ["CMD-SHELL", "redis-cli ping | grep PONG"] interval: 1s timeout: 3s retries: 5 command: ["redis-server"] db: healthcheck: test: [ "CMD-SHELL", "pg_isready -U postgres" ] interval: 2s image: postgis/postgis:17-master environment: - POSTGRES_HOST_AUTH_METHOD=trust volumes: - db:/var/lib/postgresql/data app: depends_on: db: condition: service_healthy redis: condition: service_healthy image: umap/umap:3.2.0 environment: - STATIC_ROOT=/srv/umap/static - MEDIA_ROOT=/srv/umap/uploads - DATABASE_URL=postgis://postgres@db/postgres - SECRET_KEY= # 這邊填入你生成的密鑰 - SITE_URL=http://umap.your.domain # 這邊要改成你的網域名稱,還有下面一行 - CSRF_TRUSTED_ORIGINS=http://umap.your.domain:4433 # 如果有改對外的 port 就要加這行,這是為了防止 Django CSRF警告 - UMAP_ALLOW_ANONYMOUS=True - DEBUG=1 - REALTIME_ENABLED=1 - REDIS_URL=redis://redis:6379 volumes: - data:/srv/umap/uploads - static:/srv/umap/static proxy: image: nginx:latest ports: - "4433:443" # Custom HTTPS port exposed from container volumes: - ./docker/nginx.conf:/etc/nginx/nginx.conf:ro - ./docker/certs:/etc/nginx/ssl:ro - static:/static:rw - data:/data:rw depends_on: - app volumes: data: static: db: ``` </details> ### ==nginx.conf== 參考:[官方 Github 的 nginx.conf 模板文件](https://github.com/umap-project/umap/blob/master/docker/nginx.conf) 注意:這個設定檔是採用 https 協定,請自備網站憑證檔。 <details> <summary>nginx.conf 的內容</summary> ```bash= 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 umap.your.domain; # 這邊要改成你的網域名稱 return 301 https://$host:4430$request_uri; } server { listen 443 ssl; http2 on; server_name umap.your.domain; # 這邊要改成你的網域名稱 ssl_certificate /etc/nginx/ssl/server.crt; # 這邊要改成你的網站憑證檔 ssl_certificate_key /etc/nginx/ssl/private.key; # 這邊要改成你的網站憑證檔 ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; # 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; } # Proxy pass to ASGI server location / { proxy_pass http://app: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; } } } ``` </details> 設定檔弄好之後,啟動 Docker compose ```bash docker compose build docker compose up -d ``` ## Server Settings 伺服器設定 伺服器第一次成功啟動之後,要先設定管理員帳號 ```bash docker exec -it umap-app-1 /bin/bash umap createsuperuser ``` 設定完成後,用剛剛設定的帳密登入 uMap 伺服器的網頁後台, 網址是網域名稱後加 admin,如:`http://umap.your.domain/admin` 登入之後就可以管理伺服器各項功能。 ![image](https://hackmd.io/_uploads/BkjwKODIxl.png) ### 地圖圖層 ![image](https://hackmd.io/_uploads/SyacKuDIeg.png) 一些不錯的圖層: - [Raster tile providers](https://wiki.openstreetmap.org/wiki/Raster_tile_providers) - [Thunderforest](https://www.thunderforest.com/) (註冊帳號後免費使用) ## Notes 後記 - 網站沒有走 https 的話,地圖的編輯功能會無法正常運作。 - self-signed: `openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/C=TW/ST=NC/L=Local/O=Dev/CN=umap.your.domain" -keyout server.key -out server.crt` - 在地圖資料中插入圖片 - https://wiki.openstreetmap.org/wiki/UMap/Guide/Text_formatting - https://dataportal.wiserd.ac.uk/static/pmp/resources/uMap-tutorial-linking-images-videos-and-websites.d0cc4527d36b.pdf - Popup shape (large) 的圖片最大寬度: - 電腦版:500px - 手機板:300px ## Reference 參考資料 - [uMap documentation (官方文件)](https://docs.umap-project.org/en/stable/deploy/docker/) - [umap-project/umap (Github repo)](https://github.com/umap-project/umap) - [uMap selfhost 自架 (廖聖郝 frakw)](https://hackmd.io/@frakw/Bk36Ld-Cyl) - [OpenStreetMap的基本介紹與臺灣成果展示 (陳瑞霖)](https://hackmd.io/@osm-tw/BJDuNapGel#/) - [uMap/Guide (OpenStreetMap wiki)](https://wiki.openstreetmap.org/wiki/UMap/Guide)