背景
在现代地理信息系统 (GIS) 和基于位置的服务中,PostGIS 和 pgRouting 是两个不可或缺的开源工具。PostGIS 为 PostgreSQL 数据库提供了强大的空间数据处理能力,而 pgRouting 则在此基础上增加了高级的路径规划和网络分析功能。通过 Docker 将它们容器化,可以极大地简化部署和管理过程。本文将介绍 PostGIS 和 pgRouting 的基本概念、用途,并提供一个 Dockerfile 示例来构建一个包含这两个扩展的 PostgreSQL 镜像。
PostGIS 是 PostgreSQL 对象关系数据库的一个扩展,它允许 PostgreSQL 数据库管理和查询地理对象。简而言之,PostGIS 为 PostgreSQL 增加了对空间数据类型(如点、线、面、栅格等)的支持,以及一系列用于空间分析和处理的空间函数。这使得 PostgreSQL 成为了一个功能完备的空间数据库,能够存储、索引和查询大规模的地理空间数据。
主要特性包括:
pgRouting 是 PostGIS/PostgreSQL 的另一个扩展,它专注于网络分析和路径规划。基于 PostGIS 存储的地理网络数据(如道路网、河流网络等),pgRouting 可以执行复杂的路由算法,例如:
PostGIS 的应用场景非常广泛,主要包括:
pgRouting 主要用于解决与网络和路径相关的问题:
以下是一个用于构建包含 PostGIS 和 pgRouting 的 PostgreSQL 镜像的 Dockerfile。这个 Dockerfile 基于 postgres:15-alpine3.18 镜像,并安装了 PostGIS 3.4.2 和 pgRouting 3.7.1
CNB代码仓库: https://cnb.cool/srebro/docker-images/-/tree/main/Middleware/postgres
参考: https://github.com/postgis/docker-postgis/blob/master/15-3.4/alpine/Dockerfile 和 https://github.com/postgis/docker-postgis/issues/399
#
# NOTE: THIS DOCKERFILE IS GENERATED VIA "make update"! PLEASE DO NOT EDIT IT DIRECTLY.
#
ARG BASE_IMAGE=postgres:15-alpine3.18
FROM ${BASE_IMAGE}
LABEL maintainer="PostGIS Project - https://postgis.net" \
org.opencontainers.image.description="PostGIS 3.4.2 spatial database extension with PostgreSQL 15 Alpine" \
org.opencontainers.image.source="https://github.com/postgis/docker-postgis"
ENV POSTGIS_VERSION 3.4.2
ENV POSTGIS_SHA256 17aa8760a5c4fcb9a1fdc750c1c9aca0198a35dd1e320628064c43f178eefed2
ENV PGROUTING_VERSION 3.7.1
RUN set -eux \
# 使用国内镜像源
# && sed -i 's/dl-cdn.alpinelinux.org/mirrors.nju.edu.cn/g' /etc/apk/repositories \
&& sed -i 's@dl-cdn.alpinelinux.org@mirrors.cloud.tencent.com@g' /etc/apk/repositories \
# 更新并安装依赖
&& apk update && apk upgrade \
&& apk add --no-cache \
boost-dev \
cmake \
ca-certificates \
openssl \
tar \
wget \
gdal-dev \
geos-dev \
proj-dev \
proj-util \
sfcgal-dev \
autoconf \
automake \
cunit-dev \
file \
g++ \
gcc \
gettext-dev \
git \
json-c-dev \
libtool \
libxml2-dev \
make \
pcre2-dev \
perl \
protobuf-c-dev \
&& apk add --no-cache --virtual .build-deps \
$DOCKER_PG_LLVM_DEPS \
# 下载pgrouting源代码
&& wget -O pgrouting.tar.gz "https://cnb.cool/srebro/docker-images/-/releases/download/V1.0.0/pgrouting-${PGROUTING_VERSION}.tar.gz" \
&& echo "Extracting pgrouting" \
&& tar -xvzf pgrouting.tar.gz \
&& cd pgrouting-* \
&& mkdir build \
&& cd build \
&& cmake -DCMAKE_CXX_FLAGS="-include cstdint" .. \
&& make -j4 \
&& make install \
&& cd ../.. \
&& rm -rf pgrouting* \
# 下载和校验 PostGIS 源代码
&& wget -O postgis.tar.gz "https://cnb.cool/srebro/docker-images/-/releases/download/V1.0.0/postgis-${POSTGIS_VERSION}.tar.gz" \
&& echo "${POSTGIS_SHA256} *postgis.tar.gz" | sha256sum -c - \
&& mkdir -p /usr/src/postgis \
&& tar --extract --file postgis.tar.gz --directory /usr/src/postgis --strip-components 1 \
&& rm postgis.tar.gz \
# 构建和安装 PostGIS
&& cd /usr/src/postgis \
&& gettextize \
&& ./autogen.sh \
&& ./configure --enable-lto \
&& make -j$(nproc) \
&& make install \
# 刷新 proj 数据并执行回归测试
&& projsync --system-directory --file ch_swisstopo_CHENyx06_ETRS \
&& projsync --system-directory --file us_noaa_eshpgn \
&& projsync --system-directory --file us_noaa_prvi \
&& projsync --system-directory --file us_noaa_wmhpgn \
&& mkdir /tempdb \
&& chown -R postgres:postgres /tempdb \
&& su postgres -c 'pg_ctl -D /tempdb init' \
&& su postgres -c 'pg_ctl -D /tempdb start -l /tmp/logfile -o "-F"' \
&& cd regress \
&& make -j$(nproc) check RUNTESTFLAGS=--extension PGUSER=postgres \
&& su postgres -c 'psql -c "CREATE EXTENSION IF NOT EXISTS postgis;"' \
&& su postgres -c 'psql -c "CREATE EXTENSION IF NOT EXISTS postgis_raster;"' \
&& su postgres -c 'psql -c "CREATE EXTENSION IF NOT EXISTS postgis_sfcgal;"' \
&& su postgres -c 'psql -c "CREATE EXTENSION IF NOT EXISTS fuzzystrmatch;"' \
&& su postgres -c 'psql -c "CREATE EXTENSION IF NOT EXISTS address_standardizer;"' \
&& su postgres -c 'psql -c "CREATE EXTENSION IF NOT EXISTS address_standardizer_data_us;"' \
&& su postgres -c 'psql -c "CREATE EXTENSION IF NOT EXISTS postgis_tiger_geocoder;"' \
&& su postgres -c 'psql -c "CREATE EXTENSION IF NOT EXISTS postgis_topology;"' \
&& su postgres -c 'psql -c "CREATE EXTENSION IF NOT EXISTS pgrouting;"' \
&& su postgres -c 'pg_ctl -D /tempdb --mode=immediate stop' \
&& rm -rf /tempdb /tmp/logfile \
# 安装运行时依赖
&& apk add --no-cache \
gdal \
geos \
proj \
sfcgal \
json-c \
libstdc++ \
pcre2 \
protobuf-c \
ca-certificates \
# 清理构建依赖
&& apk del .build-deps \
&& rm -rf /usr/src/postgis /var/cache/apk/*
COPY ./initdb-postgis.sh /docker-entrypoint-initdb.d/10_postgis.sh
COPY ./update-postgis.sh /usr/local/bin
docker build -t XXXX -f Dockerfile .
或者使用我构建好的镜像: docker.cnb.cool/srebro/docker-images/postgis:15.5-3.4
1、创建目录
mkdir -p /home/application/Database/postgres/{data,init}
2、创建docker-compose.yaml 文件,见 docker-compose.yaml 文件
vim /home/application/Database/postgres/docker-compose.yml
version: "3"
services:
postgres:
container_name: postgres
image: docker.cnb.cool/srebro/docker-images/postgis:15.5-3.4
networks:
- srebro
environment:
POSTGRES_HOST_AUTH_METHOD: md5
POSTGRES_PASSWORD: xxxxxxx
#ALLOW_IP_RANGE: 0.0.0.0/0
volumes:
- /home/application/Database/postgres/data:/var/lib/postgresql/data
- /home/application/Database/postgres/init:/docker-entrypoint-initdb.d/ ##可初始化SQL文件
command: -c max_connections=2000
ports:
- "5432:5432"
restart: always
networks:
srebro:
external: true
4、运行docker-compose创建容器
docker-compose up -d
之后,你就可以连接到这个 PostgreSQL 实例,并开始使用 PostGIS 和 pgRouting 的强大功能了。
希望这篇文章对你有所帮助!