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`
登入之後就可以管理伺服器各項功能。

### 地圖圖層

一些不錯的圖層:
- [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)