Compare commits

..

No commits in common. "master" and "v1.0" have entirely different histories.
master ... v1.0

18 changed files with 117 additions and 1403 deletions

View File

@ -1,6 +0,0 @@
/.github/
/.travis.yml
/docker-compose.yml
/LICENSE
/Makefile
/README.md

View File

@ -1,189 +0,0 @@
name: Build and test image
on:
push:
branches:
- master
tags:
- 'v[0-9]+.[0-9]+.[0-9]+'
pull_request:
branches:
- master
# cancel outdated jobs for the same reference
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
IMAGE : ${{ github.repository_owner }}/openstreetmap-tile-server
TAG : ${{ github.sha }}
jobs:
build:
strategy:
matrix:
include:
- arch : amd64
mode : build-and-test
- arch : arm64
variant : v8
mode : build-only
runs-on: ubuntu-latest
env:
VOLUME : osm-db
CONTAINER : osm-www
MOUNT : /data/database/
PLATFORM : linux/${{ matrix.arch }}${{ (matrix.variant != '' && format('/{0}', matrix.variant)) || '' }}
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up QEMU
uses: docker/setup-qemu-action@v2
with:
platforms: ${{ matrix.arch }}
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Environment
run : |
echo IMAGE=$(echo ${{ env.IMAGE }} | tr '[:upper:]' '[:lower:]') >>$GITHUB_ENV
-
name: Docker build
uses: docker/build-push-action@v3
with:
pull : true
load : ${{ matrix.mode == 'build-and-test' }}
platforms : ${{ env.PLATFORM }}
context : .
file : ./Dockerfile
tags : ${{ env.IMAGE }}:${{ env.TAG }}
cache-from : type=gha,scope=${{ github.workflow }}:${{ env.PLATFORM }}
cache-to : type=gha,scope=${{ github.workflow }}:${{ env.PLATFORM }},mode=max
-
name: Import Luxembourg
if : ${{ matrix.mode == 'build-and-test' }}
run : |
docker volume create ${VOLUME}
docker run --rm --shm-size=128M -v ${VOLUME}:${MOUNT} -e UPDATES=enabled ${IMAGE}:${TAG} import
-
name: Start server
if : ${{ matrix.mode == 'build-and-test' }}
run : |
docker run --shm-size=128M -v ${VOLUME}:${MOUNT} -e UPDATES=enabled -p 80:80 -d --name ${CONTAINER} ${IMAGE}:${TAG} run
sleep 30
docker logs ${CONTAINER}
-
name: Download tiles
if : ${{ matrix.mode == 'build-and-test' }}
run : |
curl http://localhost/tile/0/0/0.png --fail -o 000.png
curl http://localhost/tile/1/0/0.png --fail -o 100.png
curl http://localhost/tile/1/0/1.png --fail -o 101.png
curl http://localhost/tile/1/1/0.png --fail -o 110.png
curl http://localhost/tile/1/1/1.png --fail -o 111.png
curl http://localhost/tile/18/138474/85459.png --fail -o empty.png
curl http://localhost/tile/18/135536/89345.png --fail -o example.png
-
name: Upload tiles
if : ${{ matrix.mode == 'build-and-test' }}
uses: actions/upload-artifact@v3
with:
name: tiles
path: '*.png'
-
name: Verify tiles
if : ${{ matrix.mode == 'build-and-test' }}
run : |
sha1sum *.png
sha1sum --check <<EOF
c226ca747874fb1307eef853feaf9d8db28cef2b *empty.png
EOF
tiles=(`ls *.png`)
for ((i=0; i<${#tiles[@]}; i++)) ; do
if [ `file --brief --mime-type "${tiles[$i]}"` != 'image/png' ] ; then
>&2 echo "ERROR: ${tiles[$i]} is not a image/png file"
exit 1
fi
for ((j=i+1; j<${#tiles[@]}; j++)) ; do
if ( diff "${tiles[$i]}" "${tiles[$j]}" ) ; then
>&2 echo "ERROR: ${tiles[$i]} is identical to ${tiles[$j]}"
exit 2
fi
done
done
-
name: Cleanup
if : ${{ matrix.mode == 'build-and-test' }}
run : |
docker rm --force --volumes ${CONTAINER}
docker volume rm --force ${VOLUME}
docker rmi --force ${IMAGE}:${TAG}
deploy:
runs-on: ubuntu-latest
needs:
- build
if: ${{ github.event_name != 'pull_request' }}
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Environment
run : |
echo IMAGE=$(echo ${{ env.IMAGE }} | tr '[:upper:]' '[:lower:]') >>$GITHUB_ENV
echo DOCKERHUB_IMAGE=$([ "${{ secrets.DOCKERHUB_USERNAME }}" != '' ] && [ "${{ secrets.DOCKERHUB_PASSWORD }}" != "" ] && echo "$IMAGE") >>$GITHUB_ENV
-
name: Docker meta
id: meta
uses: docker/metadata-action@v4
with:
images: |
${{ env.DOCKERHUB_IMAGE }}
ghcr.io/${{ env.IMAGE }}
tags: |
type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', github.event.repository.default_branch) }}
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
-
name: Set up QEMU
uses: docker/setup-qemu-action@v2
with:
platforms: amd64,arm64
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Login to DockerHub
uses: docker/login-action@v2
if: ${{ env.DOCKERHUB_IMAGE != '' }}
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
-
name: Login to GHCR
uses: docker/login-action@v2
with:
registry : ghcr.io
username : ${{ github.repository_owner }}
password : ${{ secrets.GITHUB_TOKEN }}
-
name: Build and push
uses: docker/build-push-action@v3
with:
pull : true
push : true
platforms : linux/amd64,linux/arm64/v8
context : .
file : ./Dockerfile
tags : ${{ steps.meta.outputs.tags }}
labels : ${{ steps.meta.outputs.labels }}
cache-from: |
type=gha,scope=${{ github.workflow }}:linux/amd64
type=gha,scope=${{ github.workflow }}:linux/arm64/v8

6
.gitignore vendored
View File

@ -1,6 +0,0 @@
pbf/*.pbf
pbf/*.poly
tiles/*
!tiles/.gitkeep
database/*
!database/.gitkeep

View File

@ -1,28 +0,0 @@
os: linux
language: minimal
services:
- docker
# DOCKER_USERNAME/DOCKER_PASSWORD have been configured in Travis CI
# env:
before_install:
- echo "Before install"
before_script:
- docker pull overv/openstreetmap-tile-server || true
script:
- docker build --pull --cache-from overv/openstreetmap-tile-server --tag overv/openstreetmap-tile-server .
- docker volume create osm-data
- docker run --rm -v osm-data:/data/database/ overv/openstreetmap-tile-server import
- docker run --rm -v osm-data:/data/database/ -p 8080:80 -d overv/openstreetmap-tile-server run
- sleep 30
- make DOCKER_IMAGE=overv/openstreetmap-tile-server stop
after_script:
- docker images
after_success:
- if [[ "$TRAVIS_BRANCH" == "master" ]];
then
docker images ;
echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin ;
docker push overv/openstreetmap-tile-server ;
fi
notifications:
email: true

View File

@ -1,174 +1,98 @@
FROM ubuntu:22.04 AS compiler-common
ENV DEBIAN_FRONTEND=noninteractive
ENV LANG C.UTF-8
ENV LC_ALL C.UTF-8
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
ca-certificates gnupg lsb-release locales \
wget curl \
git-core unzip unrar \
&& locale-gen $LANG && update-locale LANG=$LANG \
&& sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list' \
&& wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - \
&& apt-get update && apt-get -y upgrade
###########################################################################################################
FROM compiler-common AS compiler-stylesheet
RUN cd ~ \
&& git clone --single-branch --branch v5.4.0 https://github.com/gravitystorm/openstreetmap-carto.git --depth 1 \
&& cd openstreetmap-carto \
&& sed -i 's/, "unifont Medium", "Unifont Upper Medium"//g' style/fonts.mss \
&& sed -i 's/"Noto Sans Tibetan Regular",//g' style/fonts.mss \
&& sed -i 's/"Noto Sans Tibetan Bold",//g' style/fonts.mss \
&& sed -i 's/Noto Sans Syriac Eastern Regular/Noto Sans Syriac Regular/g' style/fonts.mss \
&& rm -rf .git
###########################################################################################################
FROM compiler-common AS compiler-helper-script
RUN mkdir -p /home/renderer/src \
&& cd /home/renderer/src \
&& git clone https://github.com/zverik/regional \
&& cd regional \
&& rm -rf .git \
&& chmod u+x /home/renderer/src/regional/trim_osc.py
###########################################################################################################
FROM compiler-common AS final
FROM ubuntu:18.04
# Based on
# https://switch2osm.org/serving-tiles/manually-building-a-tile-server-18-04-lts/
ENV DEBIAN_FRONTEND=noninteractive
ENV AUTOVACUUM=on
ENV UPDATES=disabled
ENV REPLICATION_URL=https://planet.openstreetmap.org/replication/hour/
ENV MAX_INTERVAL_SECONDS=3600
ENV PG_VERSION 15
# https://switch2osm.org/manually-building-a-tile-server-18-04-lts/
# Install dependencies
RUN apt-get update
RUN apt-get install -y libboost-all-dev git-core tar unzip wget bzip2 build-essential autoconf libtool libxml2-dev libgeos-dev libgeos++-dev libpq-dev libbz2-dev libproj-dev munin-node munin libprotobuf-c0-dev protobuf-c-compiler libfreetype6-dev libtiff5-dev libicu-dev libgdal-dev libcairo-dev libcairomm-1.0-dev apache2 apache2-dev libagg-dev liblua5.2-dev ttf-unifont lua5.1 liblua5.1-dev libgeotiff-epsg
# Set up environment and renderer user
ENV TZ=UTC
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# Get packages
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
apache2 \
cron \
dateutils \
fonts-hanazono \
fonts-noto-cjk \
fonts-noto-hinted \
fonts-noto-unhinted \
fonts-unifont \
gnupg2 \
gdal-bin \
liblua5.3-dev \
lua5.3 \
mapnik-utils \
npm \
osm2pgsql \
osmium-tool \
osmosis \
postgresql-$PG_VERSION \
postgresql-$PG_VERSION-postgis-3 \
postgresql-$PG_VERSION-postgis-3-scripts \
postgis \
python-is-python3 \
python3-mapnik \
python3-lxml \
python3-psycopg2 \
python3-shapely \
python3-pip \
renderd \
sudo \
vim \
&& apt-get clean autoclean \
&& apt-get autoremove --yes \
&& rm -rf /var/lib/{apt,dpkg,cache,log}/
RUN adduser --disabled-password --gecos "" renderer
USER renderer
# Get Noto Emoji Regular font, despite it being deprecated by Google
RUN wget https://github.com/googlefonts/noto-emoji/blob/9a5261d871451f9b5183c93483cbd68ed916b1e9/fonts/NotoEmoji-Regular.ttf?raw=true --content-disposition -P /usr/share/fonts/
# Install latest osm2pgsql
RUN mkdir /home/renderer/src
WORKDIR /home/renderer/src
RUN git clone https://github.com/openstreetmap/osm2pgsql.git
WORKDIR /home/renderer/src/osm2pgsql
USER root
RUN apt-get install -y make cmake g++ libboost-dev libboost-system-dev libboost-filesystem-dev libexpat1-dev zlib1g-dev libbz2-dev libpq-dev libgeos-dev libgeos++-dev libproj-dev lua5.2 liblua5.2-dev
USER renderer
RUN mkdir build
WORKDIR /home/renderer/src/osm2pgsql/build
RUN cmake ..
RUN make
USER root
RUN make install
USER renderer
# For some reason this one is missing in the default packages
RUN wget https://github.com/stamen/terrain-classic/blob/master/fonts/unifont-Medium.ttf?raw=true --content-disposition -P /usr/share/fonts/
# Install and test Mapnik
USER root
RUN apt-get -y install autoconf apache2-dev libtool libxml2-dev libbz2-dev libgeos-dev libgeos++-dev libproj-dev gdal-bin libmapnik-dev mapnik-utils python-mapnik
USER renderer
RUN python -c 'import mapnik'
# Install python libraries
RUN pip3 install \
requests \
osmium \
pyyaml
# Install mod_tile and renderd
WORKDIR /home/renderer/src
RUN git clone -b switch2osm https://github.com/SomeoneElseOSM/mod_tile.git
WORKDIR /home/renderer/src/mod_tile
RUN ./autogen.sh
RUN ./configure
RUN make
USER root
RUN make install
RUN make install-mod_tile
RUN ldconfig
USER renderer
# Install carto for stylesheet
RUN npm install -g carto@0.18.2
# Configure stylesheet
WORKDIR /home/renderer/src
RUN git clone https://github.com/gravitystorm/openstreetmap-carto.git
WORKDIR /home/renderer/src/openstreetmap-carto
USER root
RUN apt-get install -y npm nodejs
RUN npm install -g carto
USER renderer
RUN carto -v
RUN carto project.mml > mapnik.xml
# Load shapefiles
WORKDIR /home/renderer/src/openstreetmap-carto
RUN scripts/get-shapefiles.py
# Install fonts
USER root
RUN apt-get install -y fonts-noto-cjk fonts-noto-hinted fonts-noto-unhinted ttf-unifont
USER renderer
# Configure renderd
USER root
RUN sed -i 's/renderaccount/renderer/g' /usr/local/etc/renderd.conf
RUN sed -i 's/hot/tile/g' /usr/local/etc/renderd.conf
USER renderer
# Configure Apache
RUN echo "LoadModule tile_module /usr/lib/apache2/modules/mod_tile.so" >> /etc/apache2/conf-available/mod_tile.conf \
&& echo "LoadModule headers_module /usr/lib/apache2/modules/mod_headers.so" >> /etc/apache2/conf-available/mod_headers.conf \
&& a2enconf mod_tile && a2enconf mod_headers
USER root
RUN mkdir /var/lib/mod_tile
RUN chown renderer /var/lib/mod_tile
RUN mkdir /var/run/renderd
RUN chown renderer /var/run/renderd
RUN echo "LoadModule tile_module /usr/lib/apache2/modules/mod_tile.so" >> /etc/apache2/conf-available/mod_tile.conf
RUN a2enconf mod_tile
COPY apache.conf /etc/apache2/sites-available/000-default.conf
RUN ln -sf /dev/stdout /var/log/apache2/access.log \
&& ln -sf /dev/stderr /var/log/apache2/error.log
USER renderer
# leaflet
COPY leaflet-demo.html /var/www/html/index.html
RUN cd /var/www/html/ \
&& wget https://github.com/Leaflet/Leaflet/releases/download/v1.8.0/leaflet.zip \
&& unzip leaflet.zip \
&& rm leaflet.zip
# Icon
RUN wget -O /var/www/html/favicon.ico https://www.openstreetmap.org/favicon.ico
# Copy update scripts
COPY openstreetmap-tiles-update-expire.sh /usr/bin/
RUN chmod +x /usr/bin/openstreetmap-tiles-update-expire.sh \
&& mkdir /var/log/tiles \
&& chmod a+rw /var/log/tiles \
&& ln -s /home/renderer/src/mod_tile/osmosis-db_replag /usr/bin/osmosis-db_replag \
&& echo "* * * * * renderer openstreetmap-tiles-update-expire.sh\n" >> /etc/crontab
# Configure PosgtreSQL
COPY postgresql.custom.conf.tmpl /etc/postgresql/$PG_VERSION/main/
RUN chown -R postgres:postgres /var/lib/postgresql \
&& chown postgres:postgres /etc/postgresql/$PG_VERSION/main/postgresql.custom.conf.tmpl \
&& echo "host all all 0.0.0.0/0 scram-sha-256" >> /etc/postgresql/$PG_VERSION/main/pg_hba.conf \
&& echo "host all all ::/0 scram-sha-256" >> /etc/postgresql/$PG_VERSION/main/pg_hba.conf
# Create volume directories
RUN mkdir -p /run/renderd/ \
&& mkdir -p /data/database/ \
&& mkdir -p /data/style/ \
&& mkdir -p /home/renderer/src/ \
&& chown -R renderer: /data/ \
&& chown -R renderer: /home/renderer/src/ \
&& chown -R renderer: /run/renderd \
&& mv /var/lib/postgresql/$PG_VERSION/main/ /data/database/postgres/ \
&& mv /var/cache/renderd/tiles/ /data/tiles/ \
&& chown -R renderer: /data/tiles \
&& ln -s /data/database/postgres /var/lib/postgresql/$PG_VERSION/main \
&& ln -s /data/style /home/renderer/src/openstreetmap-carto \
&& ln -s /data/tiles /var/cache/renderd/tiles \
;
RUN echo '[default] \n\
URI=/tile/ \n\
TILEDIR=/var/cache/renderd/tiles \n\
XML=/home/renderer/src/openstreetmap-carto/mapnik.xml \n\
HOST=localhost \n\
TILESIZE=256 \n\
MAXZOOM=20' >> /etc/renderd.conf \
&& sed -i 's,/usr/share/fonts/truetype,/usr/share/fonts,g' /etc/renderd.conf
# Install helper script
COPY --from=compiler-helper-script /home/renderer/src/regional /home/renderer/src/regional
COPY --from=compiler-stylesheet /root/openstreetmap-carto /home/renderer/src/openstreetmap-carto-backup
# Install PostgreSQL
USER root
RUN apt-get install -y postgresql postgresql-contrib postgis postgresql-10-postgis-2.4
USER renderer
# Start running
USER root
RUN apt-get install -y sudo
COPY run.sh /
ENTRYPOINT ["/run.sh"]
CMD []
EXPOSE 80 5432
CMD []

201
LICENSE
View File

@ -1,201 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2019 Alexander Overvoorde
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -1,18 +1,12 @@
.PHONY: build push test
DOCKER_IMAGE=overv/openstreetmap-tile-server
build:
docker build -t ${DOCKER_IMAGE} .
docker build -t overv/openstreetmap-tile-server .
push: build
docker push ${DOCKER_IMAGE}:latest
docker push overv/openstreetmap-tile-server:latest
test: build
docker volume create osm-data
docker run --rm -v osm-data:/data/database/ ${DOCKER_IMAGE} import
docker run --rm -v osm-data:/data/database/ -p 8080:80 -d ${DOCKER_IMAGE} run
stop:
docker rm -f `docker ps | grep '${DOCKER_IMAGE}' | awk '{ print $$1 }'` || true
docker volume rm -f osm-data
docker volume create openstreetmap-data
docker run -v openstreetmap-data:/var/lib/postgresql/10/main overv/openstreetmap-tile-server import
docker run -v openstreetmap-data:/var/lib/postgresql/10/main -p 80:80 -d overv/openstreetmap-tile-server run

351
README.md
View File

@ -1,375 +1,54 @@
# openstreetmap-tile-server
## Champs-libres fork
This is an adaptation of https://github.com/Overv/openstreetmap-tile-server/ for testing different cartoCss styles and generating tiles.
### Use with docker-compose
#### Fresh install
```bash
#docker volume create osm-data
docker-compose build
```
For entering into the container, use the "terminal" argument of the run.sh script:
```bash
docker-compose run --rm map terminal
```
#### Do an import
Download a pbf and a poly file of your choice on https://download.geofabrik.de and put it in the `pbf` folder. Change the lines of the pbf and poly paths in the volumes in the `docker-compose.yml` file
Then, you can import the OSM data by doing this command:
```bash
docker-compose run --rm map import
```
This will take a while, about 15 min for Luxembourg for example.
You should end with :
```
...
INFO:root: Importing into database
INFO:root: Import complete
+ sudo -u renderer touch /data/database/planet-import-complete
+ service postgresql stop
* Stopping PostgreSQL 15 database server [ OK ]
+ exit 0
```
#### Run the server to produce and view tiles
```bash
docker-compose run --rm map run
```
The tiles are available on http://192.168.176.2/ or something like that. Have a look at the docker container to know which is the IP address: there is a message like "Could not reliably determine the server's fully qualified domain name, using 192.168.176.2.". (should be on http://localhost:8080/ though...)
#### Generate tiles from a list
There's a script in utils to generate a list of tiles to be used to generate the tiles.
```bash
python3 generate-tiles-list.py > tiles.list
```
Move this `tiles.list` file in the `/tiles/` directory and then run:
```bash
docker-compose run --rm map generate_tiles
```
## Original README
[![Build Status](https://travis-ci.org/Overv/openstreetmap-tile-server.svg?branch=master)](https://travis-ci.org/Overv/openstreetmap-tile-server) [![](https://images.microbadger.com/badges/image/overv/openstreetmap-tile-server.svg)](https://microbadger.com/images/overv/openstreetmap-tile-server "openstreetmap-tile-server")
[![Docker Image Version (latest semver)](https://img.shields.io/docker/v/overv/openstreetmap-tile-server?label=docker%20image)](https://hub.docker.com/r/overv/openstreetmap-tile-server/tags)
This container allows you to easily set up an OpenStreetMap PNG tile server given a `.osm.pbf` file. It is based on the [latest Ubuntu 18.04 LTS guide](https://switch2osm.org/serving-tiles/manually-building-a-tile-server-18-04-lts/) from [switch2osm.org](https://switch2osm.org/) and therefore uses the default OpenStreetMap style.
This container allows you to easily set up an OpenStreetMap PNG tile server given a `.osm.pbf` file. It is based on the [latest Ubuntu 18.04 LTS guide](https://switch2osm.org/manually-building-a-tile-server-18-04-lts/) from [switch2osm.org](https://switch2osm.org/) and therefore uses the default OpenStreetMap style.
## Setting up the server
First create a Docker volume to hold the PostgreSQL database that will contain the OpenStreetMap data:
docker volume create osm-data
docker volume create openstreetmap-data
Next, download an `.osm.pbf` extract from geofabrik.de for the region that you're interested in. You can then start importing it into PostgreSQL by running a container and mounting the file as `/data/region.osm.pbf`. For example:
Next, download an .osm.pbf extract from geofabrik.de for the region that you're interested in. You can then start importing it into PostgreSQL by running a container and mounting the file as `/data.osm.pbf`. For example:
```
docker run \
-v /absolute/path/to/luxembourg.osm.pbf:/data/region.osm.pbf \
-v osm-data:/data/database/ \
overv/openstreetmap-tile-server \
import
```
docker run -v luxembourg.osm.pbf:/data.osm.pbf -v openstreetmap-data:/var/lib/postgresql/10/main overv/openstreetmap-tile-server import
If the container exits without errors, then your data has been successfully imported and you are now ready to run the tile server.
Note that the import process requires an internet connection. The run process does not require an internet connection. If you want to run the openstreetmap-tile server on a computer that is isolated, you must first import on an internet connected computer, export the `osm-data` volume as a tarfile, and then restore the data volume on the target computer system.
Also when running on an isolated system, the default `index.html` from the container will not work, as it requires access to the web for the leaflet packages.
### Automatic updates (optional)
If your import is an extract of the planet and has polygonal bounds associated with it, like those from [geofabrik.de](https://download.geofabrik.de/), then it is possible to set your server up for automatic updates. Make sure to reference both the OSM file and the polygon file during the `import` process to facilitate this, and also include the `UPDATES=enabled` variable:
```
docker run \
-e UPDATES=enabled \
-v /absolute/path/to/luxembourg.osm.pbf:/data/region.osm.pbf \
-v /absolute/path/to/luxembourg.poly:/data/region.poly \
-v osm-data:/data/database/ \
overv/openstreetmap-tile-server \
import
```
Refer to the section *Automatic updating and tile expiry* to actually enable the updates while running the tile server.
Please note: If you're not importing the whole planet, then the `.poly` file is necessary to limit automatic updates to the relevant region.
Therefore, when you only have a `.osm.pbf` file but not a `.poly` file, you should not enable automatic updates.
### Letting the container download the file
It is also possible to let the container download files for you rather than mounting them in advance by using the `DOWNLOAD_PBF` and `DOWNLOAD_POLY` parameters:
```
docker run \
-e DOWNLOAD_PBF=https://download.geofabrik.de/europe/luxembourg-latest.osm.pbf \
-e DOWNLOAD_POLY=https://download.geofabrik.de/europe/luxembourg.poly \
-v osm-data:/data/database/ \
overv/openstreetmap-tile-server \
import
```
### Using an alternate style
By default the container will use openstreetmap-carto if it is not specified. However, you can modify the style at run-time. Be aware you need the style mounted at `run` AND `import` as the Lua script needs to be run:
```
docker run \
-e DOWNLOAD_PBF=https://download.geofabrik.de/europe/luxembourg-latest.osm.pbf \
-e DOWNLOAD_POLY=https://download.geofabrik.de/europe/luxembourg.poly \
-e NAME_LUA=sample.lua \
-e NAME_STYLE=test.style \
-e NAME_MML=project.mml \
-e NAME_SQL=test.sql \
-v /home/user/openstreetmap-carto-modified:/data/style/ \
-v osm-data:/data/database/ \
overv/openstreetmap-tile-server \
import
```
If you do not define the "NAME_*" variables, the script will default to those found in the openstreetmap-carto style.
Be sure to mount the volume during `run` with the same `-v /home/user/openstreetmap-carto-modified:/data/style/`
If you do not see the expected style upon `run` double check your paths as the style may not have been found at the directory specified. By default, `openstreetmap-carto` will be used if a style cannot be found
**Only openstreetmap-carto and styles like it, eg, ones with one lua script, one style, one mml, one SQL can be used**
## Running the server
Run the server like this:
```
docker run \
-p 8080:80 \
-v osm-data:/data/database/ \
-d overv/openstreetmap-tile-server \
run
```
docker run -p 80:80 -v openstreetmap-data:/var/lib/postgresql/10/main -d overv/openstreetmap-tile-server run
Your tiles will now be available at `http://localhost:8080/tile/{z}/{x}/{y}.png`. The demo map in `leaflet-demo.html` will then be available on `http://localhost:8080`. Note that it will initially take quite a bit of time to render the larger tiles for the first time.
Your tiles will now be available at http://localhost:80/tile/{z}/{x}/{y}.png. If you open `leaflet-demo.html` in your browser, you should be able to see the tiles served by your own machine. Note that it will initially quite a bit of time to render the larger tiles for the first time.
### Using Docker Compose
## Preserving rendered tiles
The `docker-compose.yml` file included with this repository shows how the aforementioned command can be used with Docker Compose to run your server.
Tiles that have already been rendered will be stored in `/var/lib/mod_tile`. To make sure that this data survives container restarts, you should create another volume for it:
### Preserving rendered tiles
docker volume create openstreetmap-rendered-tiles
docker run -p 80:80 -v openstreetmap-data:/var/lib/postgresql/10/main -v openstreetmap-rendered-tiles:/var/lib/mod_tile -d overv/openstreetmap-tile-server run
Tiles that have already been rendered will be stored in `/data/tiles/`. To make sure that this data survives container restarts, you should create another volume for it:
```
docker volume create osm-tiles
docker run \
-p 8080:80 \
-v osm-data:/data/database/ \
-v osm-tiles:/data/tiles/ \
-d overv/openstreetmap-tile-server \
run
```
**If you do this, then make sure to also run the import with the `osm-tiles` volume to make sure that caching works properly across updates!**
### Enabling automatic updating (optional)
Given that you've set up your import as described in the *Automatic updates* section during server setup, you can enable the updating process by setting the `UPDATES` variable while running your server as well:
```
docker run \
-p 8080:80 \
-e REPLICATION_URL=https://planet.openstreetmap.org/replication/minute/ \
-e MAX_INTERVAL_SECONDS=60 \
-e UPDATES=enabled \
-v osm-data:/data/database/ \
-v osm-tiles:/data/tiles/ \
-d overv/openstreetmap-tile-server \
run
```
This will enable a background process that automatically downloads changes from the OpenStreetMap server, filters them for the relevant region polygon you specified, updates the database and finally marks the affected tiles for rerendering.
### Tile expiration (optional)
Specify custom tile expiration settings to control which zoom level tiles are marked as expired when an update is performed. Tiles can be marked as expired in the cache (TOUCHFROM), but will still be served
until a new tile has been rendered, or deleted from the cache (DELETEFROM), so nothing will be served until a new tile has been rendered.
The example tile expiration values below are the default values.
```
docker run \
-p 8080:80 \
-e REPLICATION_URL=https://planet.openstreetmap.org/replication/minute/ \
-e MAX_INTERVAL_SECONDS=60 \
-e UPDATES=enabled \
-e EXPIRY_MINZOOM=13 \
-e EXPIRY_TOUCHFROM=13 \
-e EXPIRY_DELETEFROM=19 \
-e EXPIRY_MAXZOOM=20 \
-v osm-data:/data/database/ \
-v osm-tiles:/data/tiles/ \
-d overv/openstreetmap-tile-server \
run
```
### Cross-origin resource sharing
To enable the `Access-Control-Allow-Origin` header to be able to retrieve tiles from other domains, simply set the `ALLOW_CORS` variable to `enabled`:
```
docker run \
-p 8080:80 \
-v osm-data:/data/database/ \
-e ALLOW_CORS=enabled \
-d overv/openstreetmap-tile-server \
run
```
### Connecting to Postgres
To connect to the PostgreSQL database inside the container, make sure to expose port 5432:
```
docker run \
-p 8080:80 \
-p 5432:5432 \
-v osm-data:/data/database/ \
-d overv/openstreetmap-tile-server \
run
```
Use the user `renderer` and the database `gis` to connect.
```
psql -h localhost -U renderer gis
```
The default password is `renderer`, but it can be changed using the `PGPASSWORD` environment variable:
```
docker run \
-p 8080:80 \
-p 5432:5432 \
-e PGPASSWORD=secret \
-v osm-data:/data/database/ \
-d overv/openstreetmap-tile-server \
run
```
## Performance tuning and tweaking
Details for update procedure and invoked scripts can be found here [link](https://ircama.github.io/osm-carto-tutorials/updating-data/).
### THREADS
## Performance tuning
The import and tile serving processes use 4 threads by default, but this number can be changed by setting the `THREADS` environment variable. For example:
```
docker run \
-p 8080:80 \
-e THREADS=24 \
-v osm-data:/data/database/ \
-d overv/openstreetmap-tile-server \
run
```
### CACHE
The import and tile serving processes use 800 MB RAM cache by default, but this number can be changed by option -C. For example:
```
docker run \
-p 8080:80 \
-e "OSM2PGSQL_EXTRA_ARGS=-C 4096" \
-v osm-data:/data/database/ \
-d overv/openstreetmap-tile-server \
run
```
### AUTOVACUUM
The database use the autovacuum feature by default. This behavior can be changed with `AUTOVACUUM` environment variable. For example:
```
docker run \
-p 8080:80 \
-e AUTOVACUUM=off \
-v osm-data:/data/database/ \
-d overv/openstreetmap-tile-server \
run
```
### FLAT_NODES
If you are planning to import the entire planet or you are running into memory errors then you may want to enable the `--flat-nodes` option for osm2pgsql. You can then use it during the import process as follows:
```
docker run \
-v /absolute/path/to/luxembourg.osm.pbf:/data/region.osm.pbf \
-v osm-data:/data/database/ \
-e "FLAT_NODES=enabled" \
overv/openstreetmap-tile-server \
import
```
Warning: enabling `FLAT_NOTES` together with `UPDATES` only works for entire planet imports (without a `.poly` file). Otherwise this will break the automatic update script. This is because trimming the differential updates to the specific regions currently isn't supported when using flat nodes.
### Benchmarks
You can find an example of the import performance to expect with this image on the [OpenStreetMap wiki](https://wiki.openstreetmap.org/wiki/Osm2pgsql/benchmarks#debian_9_.2F_openstreetmap-tile-server).
## Troubleshooting
### ERROR: could not resize shared memory segment / No space left on device
If you encounter such entries in the log, it will mean that the default shared memory limit (64 MB) is too low for the container and it should be raised:
```
renderd[121]: ERROR: failed to render TILE default 2 0-3 0-3
renderd[121]: reason: Postgis Plugin: ERROR: could not resize shared memory segment "/PostgreSQL.790133961" to 12615680 bytes: ### No space left on device
```
To raise it use `--shm-size` parameter. For example:
```
docker run \
-p 8080:80 \
-v osm-data:/data/database/ \
--shm-size="192m" \
-d overv/openstreetmap-tile-server \
run
```
For too high values you may notice excessive CPU load and memory usage. It might be that you will have to experimentally find the best values for yourself.
### The import process unexpectedly exits
You may be running into problems with memory usage during the import. Have a look at the "Flat nodes" section in this README.
docker run -p 80:80 -e THREADS=24 -v openstreetmap-data:/var/lib/postgresql/10/main -d overv/openstreetmap-tile-server run
## License
```
Copyright 2019 Alexander Overvoorde
Copyright 2018 Alexander Overvoorde
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
```
```

View File

@ -1,9 +1,8 @@
<VirtualHost *:80>
ServerAdmin webmaster@localhost
AddTileConfig /tile/ default
LoadTileConfigFile /etc/renderd.conf
ModTileRenderdSocketName /run/renderd/renderd.sock
LoadTileConfigFile /usr/local/etc/renderd.conf
ModTileRenderdSocketName /var/run/renderd/renderd.sock
ModTileRequestTimeout 0
ModTileMissingRequestTimeout 30
@ -11,8 +10,4 @@
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
<IfDefine ALLOW_CORS>
Header set Access-Control-Allow-Origin "*"
</IfDefine>
</VirtualHost>

View File

View File

@ -1,19 +0,0 @@
version: '3'
services:
map:
image: overv/openstreetmap-tile-server
volumes:
#- osm-data:/data/database/
- ./database:/data/database/
- ./tiles:/data/tiles/
- ./run.sh:/run.sh # for dev
- ./pbf/luxembourg-latest.osm.pbf:/data/region.osm.pbf # change here your pbf
- ./pbf/luxembourg.poly:/data/region.poly # and your poly
ports:
- "8080:80"
command: "run"
# volumes:
# osm-data:
# external: true

View File

@ -6,8 +6,8 @@
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="leaflet.css"/>
<script src="leaflet.js"></script>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.1/dist/leaflet.css" integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" crossorigin=""/>
<script src="https://unpkg.com/leaflet@1.3.1/dist/leaflet.js" integrity="sha512-/Nsx9X4HebavoBvEBuyp3I7od5tA0UzAxs+j83KgC8PU0kgB4XiK4Lfe4y4cgBtaRJQEIFCW+oC506aPT2L1zw==" crossorigin=""></script>
<style>
html, body, #map {
@ -25,7 +25,7 @@
<script>
var map = L.map('map').setView([0, 0], 3);
L.tileLayer('/tile/{z}/{x}/{y}.png', {
L.tileLayer('http://localhost/tile/{z}/{x}/{y}.png', {
maxZoom: 18,
attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>',
id: 'base'

View File

@ -1,206 +0,0 @@
#!/bin/sh
set -e
#------------------------------------------------------------------------------
# Change directory to mod_tile directory so that we can run replag
# and other things directly from this script when run from cron.
# Change the actual location to wherever installed locally.
#------------------------------------------------------------------------------
# Extra OSM2PGSQL_OPTIONS may need setting if a tag transform script is
# in use. See https://github.com/SomeoneElseOSM/SomeoneElse-style and
# http://wiki.openstreetmap.org/wiki/User:SomeoneElse/Ubuntu_1404_tileserver_load
# The database name always needs setting.
#------------------------------------------------------------------------------
OSMOSIS_BIN=osmosis
OSM2PGSQL_BIN=osm2pgsql
TRIM_BIN=/home/renderer/src/regional/trim_osc.py
DBNAME=gis
OSM2PGSQL_OPTIONS="-d $DBNAME -G --hstore --tag-transform-script /data/style/${NAME_LUA:-openstreetmap-carto.lua} --number-processes ${THREADS:-4} -S /data/style/${NAME_STYLE:-openstreetmap-carto.style} ${OSM2PGSQL_EXTRA_ARGS}"
# flat-nodes
if [ -f /data/database/flat_nodes.bin ]; then
OSM2PGSQL_OPTIONS="${OSM2PGSQL_OPTIONS} --flat-nodes /data/database/flat_nodes.bin"
fi
#------------------------------------------------------------------------------
# When using trim_osc.py we can define either a bounding box (such as this
# example for England and Wales) or a polygon.
# See https://github.com/zverik/regional .
# This area will usually correspond to the data originally loaded.
#------------------------------------------------------------------------------
TRIM_POLY_FILE="/data/database/region.poly"
TRIM_OPTIONS="-d $DBNAME"
TRIM_REGION_OPTIONS="-p $TRIM_POLY_FILE"
BASE_DIR=/data/database
LOG_DIR=/var/log/tiles
WORKOSM_DIR=$BASE_DIR/.osmosis
LOCK_FILE=/tmp/openstreetmap-update-expire-lock.txt
CHANGE_FILE=$BASE_DIR/changes.osc.gz
EXPIRY_FILE=$BASE_DIR/dirty_tiles
STOP_FILE=$BASE_DIR/stop.txt
OSMOSISLOG=$LOG_DIR/osmosis.log
PGSQLLOG=$LOG_DIR/osm2pgsql.log
EXPIRYLOG=$LOG_DIR/expiry.log
RUNLOG=$LOG_DIR/run.log
#------------------------------------------------------------------------------
# The tile expiry section below can re-render, delete or dirty expired tiles.
# By default, tiles between EXPIRY_MINZOOM and EXPIRY_MAXZOOM are rerendered.
# "render_expired" can optionally delete (and/or dirty) tiles above a certail
# threshold rather than rendering them.
# Here we expire (but don't immediately rerender) tiles between zoom levels
# 13 and 18 and delete between 19 and 20.
#------------------------------------------------------------------------------
EXPIRY_MINZOOM=${EXPIRY_MINZOOM:="13"}
EXPIRY_TOUCHFROM=${EXPIRY_TOUCHFROM:="13"}
EXPIRY_DELETEFROM=${EXPIRY_DELETEFROM:="19"}
EXPIRY_MAXZOOM=${EXPIRY_MAXZOOM:="20"}
#*************************************************************************
#*************************************************************************
m_info()
{
echo "[`date +"%Y-%m-%d %H:%M:%S"`] $$ $1" >> "$RUNLOG"
}
m_error()
{
echo "[`date +"%Y-%m-%d %H:%M:%S"`] $$ [error] $1" >> "$RUNLOG"
m_info "resetting state"
/bin/cp $WORKOSM_DIR/last.state.txt $WORKOSM_DIR/state.txt || true
rm "$CHANGE_FILE" || true
rm "$EXPIRY_FILE.$$" || true
rm "$LOCK_FILE"
exit
}
m_ok()
{
echo "[`date +"%Y-%m-%d %H:%M:%S"`] $$ $1" >> "$RUNLOG"
}
getlock()
{
if [ -s $1 ]; then
if [ "$(ps -p `cat $1` | wc -l)" -gt 1 ]; then
return 1 #false
fi
fi
echo $$ >"$1"
return 0 #true
}
freelock()
{
rm "$1"
rm "$CHANGE_FILE"
}
if [ $# -eq 1 ] ; then
m_info "Initialising Osmosis replication system to $1"
mkdir -p $WORKOSM_DIR
$OSMOSIS_BIN -v 5 --read-replication-interval-init workingDirectory=$WORKOSM_DIR 1>&2 2> "$OSMOSISLOG"
init_seq=$(/usr/lib/python3-pyosmium/pyosmium-get-changes --server $REPLICATION_URL -D $1)
url_dynamicPart=$(printf %09d $init_seq | sed 's_\([0-9][0-9][0-9]\)\([0-9][0-9][0-9]\)\([0-9][0-9][0-9]\)_\1/\2/\3_')
wget $REPLICATION_URL/$url_dynamicPart.state.txt -O $WORKOSM_DIR/state.txt
cat > $WORKOSM_DIR/configuration.txt <<- EOM
baseUrl=$REPLICATION_URL
maxInterval=$MAX_INTERVAL_SECONDS
EOM
fi
# make sure the lockfile is removed when we exit and then claim it
if ! getlock "$LOCK_FILE"; then
m_info "pid `cat $LOCK_FILE` still running"
exit 3
fi
if [ -e $STOP_FILE ]; then
m_info "stopped"
exit 2
fi
# -----------------------------------------------------------------------------
# Add disk space check from https://github.com/zverik/regional
# -----------------------------------------------------------------------------
MIN_DISK_SPACE_MB=500
if `python -c "import os, sys; st=os.statvfs('$BASE_DIR'); sys.exit(1 if st.f_bavail*st.f_frsize/1024/1024 > $MIN_DISK_SPACE_MB else 0)"`; then
m_info "there is less than $MIN_DISK_SPACE_MB MB left"
exit 4
fi
seq=`cat $WORKOSM_DIR/state.txt | grep sequenceNumber | cut -d= -f2`
replag=`dateutils.ddiff $(cat $WORKOSM_DIR/state.txt | grep timestamp | cut -d "=" -f 2 | sed 's,\\\,,g') now`
m_ok "start import from seq-nr $seq, replag is $replag"
/bin/cp $WORKOSM_DIR/state.txt $WORKOSM_DIR/last.state.txt
m_ok "downloading diff"
if ! $OSMOSIS_BIN --read-replication-interval workingDirectory=$WORKOSM_DIR --simplify-change --write-xml-change $CHANGE_FILE 1>&2 2> "$OSMOSISLOG"; then
m_error "Osmosis error"
fi
if [ -f $TRIM_POLY_FILE ] ; then
m_ok "filtering diff"
if ! $TRIM_BIN $TRIM_OPTIONS $TRIM_REGION_OPTIONS -z $CHANGE_FILE $CHANGE_FILE 1>&2 2>> "$RUNLOG"; then
m_error "Trim_osc error"
fi
else
m_ok "filtering diff skipped"
fi
m_ok "importing diff"
#------------------------------------------------------------------------------
# Previously openstreetmap-tiles-update-expire tried to dirty layer
# "$EXPIRY_MAXZOOM - 3" (which was 15) only. Instead we write all expired
# tiles in range to the list (note the "-" rather than ":" in the "-e"
# parameter).
#------------------------------------------------------------------------------
if ! $OSM2PGSQL_BIN -a --slim -e$EXPIRY_MINZOOM-$EXPIRY_MAXZOOM $OSM2PGSQL_OPTIONS -o "$EXPIRY_FILE.$$" $CHANGE_FILE 1>&2 2> "$PGSQLLOG"; then
m_error "osm2pgsql error"
fi
#------------------------------------------------------------------------------
# The lockfile is normally removed before we expire tiles because that is
# something that can be done in parallel with further processing. In order to
# avoid rework, if actually rerendering is done rather than just deleting or
# dirtying, it makes sense to move it lower down.
#------------------------------------------------------------------------------
# m_ok "Import complete; removing lock file"
# freelock "$LOCK_FILE"
m_ok "expiring tiles"
#------------------------------------------------------------------------------
# Previously all tiles on the "dirty" list between $EXPIRY_MINZOOM and
# $EXPIRY_MAXZOOM were dirtied. We currently re-render
# tiles >= $EXPIRY_MINZOOM and < $EXPIRY_DELETEFROM, expiry from 14 and
# delete >= $EXPIRY_DELETEFROM and <= $EXPIRY_MAXZOOM.
# The default path to renderd.sock is fixed.
#------------------------------------------------------------------------------
if ! render_expired --map=default --min-zoom=$EXPIRY_MINZOOM --touch-from=$EXPIRY_TOUCHFROM --delete-from=$EXPIRY_DELETEFROM --max-zoom=$EXPIRY_MAXZOOM -s /run/renderd/renderd.sock < "$EXPIRY_FILE.$$" 2>&1 | tail -8 >> "$EXPIRYLOG"; then
m_info "Expiry failed"
fi
rm "$EXPIRY_FILE.$$"
#------------------------------------------------------------------------------
# Only remove the lock file after expiry (if system is slow we want to delay
# the next import, not have multiple render_expired processes running)
#------------------------------------------------------------------------------
freelock "$LOCK_FILE"
m_ok "Done with import"

View File

View File

@ -1,25 +0,0 @@
# Suggested minimal settings from
# https://ircama.github.io/osm-carto-tutorials/tile-server-ubuntu/
shared_buffers = 128MB
min_wal_size = 1GB
# max_wal_size = 2GB # Overridden below
maintenance_work_mem = 256MB
# Suggested settings from
# https://github.com/openstreetmap/chef/blob/master/roles/tile.rb#L38-L45
max_connections = 250
temp_buffers = 32MB
work_mem = 128MB
wal_buffers = 1024kB
wal_writer_delay = 500ms
commit_delay = 10000
# checkpoint_segments = 60 # unrecognized in psql 10.7.1
max_wal_size = 2880MB
random_page_cost = 1.1
track_activity_query_size = 16384
autovacuum_vacuum_scale_factor = 0.05
autovacuum_analyze_scale_factor = 0.02
listen_addresses = '*'

185
run.sh
View File

@ -1,60 +1,17 @@
#!/bin/bash
set -euo pipefail
function createPostgresConfig() {
cp /etc/postgresql/$PG_VERSION/main/postgresql.custom.conf.tmpl /etc/postgresql/$PG_VERSION/main/conf.d/postgresql.custom.conf
sudo -u postgres echo "autovacuum = $AUTOVACUUM" >> /etc/postgresql/$PG_VERSION/main/conf.d/postgresql.custom.conf
cat /etc/postgresql/$PG_VERSION/main/conf.d/postgresql.custom.conf
}
function setPostgresPassword() {
sudo -u postgres psql -c "ALTER USER renderer PASSWORD '${PGPASSWORD:-renderer}'"
}
if [ "$#" -ne 1 ]; then
echo "usage: <import|run>"
echo "commands:"
echo " import: Set up the database and import /data/region.osm.pbf"
echo " import: Set up the database and import /data.osm.pbf"
echo " run: Runs Apache and renderd to serve tiles at /tile/{z}/{x}/{y}.png"
echo "environment variables:"
echo " THREADS: defines number of threads used for importing / tile rendering"
echo " UPDATES: consecutive updates (enabled/disabled)"
echo " NAME_LUA: name of .lua script to run as part of the style"
echo " NAME_STYLE: name of the .style to use"
echo " NAME_MML: name of the .mml file to render to mapnik.xml"
echo " NAME_SQL: name of the .sql file to use"
exit 1
fi
set -x
# if there is no custom style mounted, then use osm-carto
if [ ! "$(ls -A /data/style/)" ]; then
mv /home/renderer/src/openstreetmap-carto-backup/* /data/style/
fi
# carto build
if [ ! -f /data/style/mapnik.xml ]; then
cd /data/style/
carto ${NAME_MML:-project.mml} > mapnik.xml
fi
if [ "$1" == "terminal" ]; then
bash
fi
if [ "$1" == "import" ]; then
# Ensure that database directory is in right state
mkdir -p /data/database/postgres/
chown renderer: /data/database/
chown -R postgres: /var/lib/postgresql /data/database/postgres/
if [ ! -f /data/database/postgres/PG_VERSION ]; then
sudo -u postgres /usr/lib/postgresql/$PG_VERSION/bin/pg_ctl -D /data/database/postgres/ initdb -o "--locale C.UTF-8"
fi
if [ "$1" = "import" ]; then
# Initialize PostgreSQL
createPostgresConfig
service postgresql start
sudo -u postgres createuser renderer
sudo -u postgres createdb -E UTF8 -O renderer gis
@ -62,152 +19,32 @@ if [ "$1" == "import" ]; then
sudo -u postgres psql -d gis -c "CREATE EXTENSION hstore;"
sudo -u postgres psql -d gis -c "ALTER TABLE geometry_columns OWNER TO renderer;"
sudo -u postgres psql -d gis -c "ALTER TABLE spatial_ref_sys OWNER TO renderer;"
setPostgresPassword
# Download Luxembourg as sample if no data is provided
if [ ! -f /data/region.osm.pbf ] && [ -z "${DOWNLOAD_PBF:-}" ]; then
echo "WARNING: No import file at /data/region.osm.pbf, so importing Luxembourg as example..."
DOWNLOAD_PBF="https://download.geofabrik.de/europe/luxembourg-latest.osm.pbf"
DOWNLOAD_POLY="https://download.geofabrik.de/europe/luxembourg.poly"
fi
if [ -n "${DOWNLOAD_PBF:-}" ]; then
echo "INFO: Download PBF file: $DOWNLOAD_PBF"
wget ${WGET_ARGS:-} "$DOWNLOAD_PBF" -O /data/region.osm.pbf
if [ -n "${DOWNLOAD_POLY:-}" ]; then
echo "INFO: Download PBF-POLY file: $DOWNLOAD_POLY"
wget ${WGET_ARGS:-} "$DOWNLOAD_POLY" -O /data/region.poly
fi
fi
if [ "${UPDATES:-}" == "enabled" ] || [ "${UPDATES:-}" == "1" ]; then
# determine and set osmosis_replication_timestamp (for consecutive updates)
REPLICATION_TIMESTAMP=`osmium fileinfo -g header.option.osmosis_replication_timestamp /data/region.osm.pbf`
# initial setup of osmosis workspace (for consecutive updates)
sudo -E -u renderer openstreetmap-tiles-update-expire.sh $REPLICATION_TIMESTAMP
fi
# copy polygon file if available
if [ -f /data/region.poly ]; then
cp /data/region.poly /data/database/region.poly
chown renderer: /data/database/region.poly
fi
# flat-nodes
if [ "${FLAT_NODES:-}" == "enabled" ] || [ "${FLAT_NODES:-}" == "1" ]; then
OSM2PGSQL_EXTRA_ARGS="${OSM2PGSQL_EXTRA_ARGS:-} --flat-nodes /data/database/flat_nodes.bin"
if [ ! -f /data.osm.pbf ]; then
echo "WARNING: No import file at /data.osm.pbf, so importing Luxembourg as example..."
wget -nv http://download.geofabrik.de/europe/luxembourg-latest.osm.pbf -O /data.osm.pbf
fi
# Import data
sudo -u renderer osm2pgsql -d gis --create --slim -G --hstore \
--tag-transform-script /data/style/${NAME_LUA:-openstreetmap-carto.lua} \
--number-processes ${THREADS:-4} \
-S /data/style/${NAME_STYLE:-openstreetmap-carto.style} \
/data/region.osm.pbf \
${OSM2PGSQL_EXTRA_ARGS:-} \
;
# old flat-nodes dir
if [ -f /nodes/flat_nodes.bin ] && ! [ -f /data/database/flat_nodes.bin ]; then
mv /nodes/flat_nodes.bin /data/database/flat_nodes.bin
chown renderer: /data/database/flat_nodes.bin
fi
# Create indexes
if [ -f /data/style/${NAME_SQL:-indexes.sql} ]; then
sudo -u postgres psql -d gis -f /data/style/${NAME_SQL:-indexes.sql}
fi
#Import external data
chown -R renderer: /home/renderer/src/ /data/style/
if [ -f /data/style/scripts/get-external-data.py ] && [ -f /data/style/external-data.yml ]; then
sudo -E -u renderer python3 /data/style/scripts/get-external-data.py -c /data/style/external-data.yml -D /data/style/data
fi
# Register that data has changed for mod_tile caching purposes
sudo -u renderer touch /data/database/planet-import-complete
service postgresql stop
sudo -u renderer osm2pgsql -d gis --create --slim -G --hstore --tag-transform-script /home/renderer/src/openstreetmap-carto/openstreetmap-carto.lua -C 2048 --number-processes ${THREADS:-4} -S /home/renderer/src/openstreetmap-carto/openstreetmap-carto.style /data.osm.pbf
exit 0
fi
if [ "$1" == "run" ]; then
# Clean /tmp
rm -rf /tmp/*
# migrate old files
if [ -f /data/database/PG_VERSION ] && ! [ -d /data/database/postgres/ ]; then
mkdir /data/database/postgres/
mv /data/database/* /data/database/postgres/
fi
if [ -f /nodes/flat_nodes.bin ] && ! [ -f /data/database/flat_nodes.bin ]; then
mv /nodes/flat_nodes.bin /data/database/flat_nodes.bin
fi
if [ -f /data/tiles/data.poly ] && ! [ -f /data/database/region.poly ]; then
mv /data/tiles/data.poly /data/database/region.poly
fi
# sync planet-import-complete file
if [ -f /data/tiles/planet-import-complete ] && ! [ -f /data/database/planet-import-complete ]; then
cp /data/tiles/planet-import-complete /data/database/planet-import-complete
fi
if ! [ -f /data/tiles/planet-import-complete ] && [ -f /data/database/planet-import-complete ]; then
cp /data/database/planet-import-complete /data/tiles/planet-import-complete
fi
# Fix postgres data privileges
chown -R postgres: /var/lib/postgresql/ /data/database/postgres/
# Configure Apache CORS
if [ "${ALLOW_CORS:-}" == "enabled" ] || [ "${ALLOW_CORS:-}" == "1" ]; then
echo "export APACHE_ARGUMENTS='-D ALLOW_CORS'" >> /etc/apache2/envvars
fi
if [ "$1" = "run" ]; then
# Initialize PostgreSQL and Apache
createPostgresConfig
service postgresql start
service apache2 restart
setPostgresPassword
# Configure renderd threads
sed -i -E "s/num_threads=[0-9]+/num_threads=${THREADS:-4}/g" /etc/renderd.conf
sed -i -E "s/num_threads=[0-9]+/num_threads=${THREADS:-4}/g" /usr/local/etc/renderd.conf
# start cron job to trigger consecutive updates
if [ "${UPDATES:-}" == "enabled" ] || [ "${UPDATES:-}" == "1" ]; then
/etc/init.d/cron start
sudo -u renderer touch /var/log/tiles/run.log; tail -f /var/log/tiles/run.log >> /proc/1/fd/1 &
sudo -u renderer touch /var/log/tiles/osmosis.log; tail -f /var/log/tiles/osmosis.log >> /proc/1/fd/1 &
sudo -u renderer touch /var/log/tiles/expiry.log; tail -f /var/log/tiles/expiry.log >> /proc/1/fd/1 &
sudo -u renderer touch /var/log/tiles/osm2pgsql.log; tail -f /var/log/tiles/osm2pgsql.log >> /proc/1/fd/1 &
fi
# Run while handling docker stop's SIGTERM
stop_handler() {
kill -TERM "$child"
}
trap stop_handler SIGTERM
sudo -u renderer renderd -f -c /etc/renderd.conf &
child=$!
wait "$child"
service postgresql stop
# Run
sudo -u renderer renderd -f -c /usr/local/etc/renderd.conf
exit 0
fi
if [ "$1" == "generate_tiles" ]; then
service postgresql start
service apache2 restart
sudo -u renderer renderd -c /etc/renderd.conf
cat /data/tiles/default/tiles.list | render_list --map default
fi
echo "invalid command"
exit 1
exit 1

View File

View File

@ -1,35 +0,0 @@
# usage: python3 generate-tiles-list.py > tiles.list
import math
def deg2num(lat_deg, lon_deg, zoom):
lat_rad = math.radians(lat_deg)
n = 2.0 ** zoom
xtile = int((lon_deg + 180.0) / 360.0 * n)
ytile = int((1.0 - math.asinh(math.tan(lat_rad)) / math.pi) / 2.0 * n)
return (xtile, ytile)
# GD lux coordinates
max_x = 6.531
max_y = 50.184
min_x = 5.735
min_y = 49.452
min_z = 9
max_z = 17
for z in range(min_z, max_z+1):
x1_tile, y1_tile = deg2num(max_y, max_x, z)
x2_tile, y2_tile = deg2num(min_y, min_x, z)
min_x_tile = x1_tile if x1_tile < x2_tile else x2_tile
max_x_tile = x1_tile if x1_tile > x2_tile else x2_tile
min_y_tile = y1_tile if y1_tile < y2_tile else y2_tile
max_y_tile = y1_tile if y1_tile > y2_tile else y2_tile
for tx in range(min_x_tile, max_x_tile):
if tx % 8 != 0:
continue
for ty in range(min_y_tile, max_y_tile):
if ty % 8 != 0:
continue
print("{} {} {}".format(tx, ty, z))