Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP Refactored/reworked mainly upgrading and slimming Image and added examples #18

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: CI

# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the master branch
on:
push:
branches: [ master ]
paths-ignore:
- '**.md'
- 'examples/**'
pull_request:
branches: [ master ]
paths-ignore:
- '**.md'
- 'examples/**'

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
build:
# The type of runner that the job will run on
runs-on: ubuntu-latest

# Steps represent a sequence of tasks that will be executed as part of the job
steps:
- uses: actions/checkout@v2

- name: Build-Push-DockerHub
uses: docker/build-push-action@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
repository: justb4/mapproxy
tags: latest,2.0.2-2
tag_with_ref: false
tag_with_sha: false
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
# Created by .ignore support plugin (hsz.mobi)

mapproxy/
cache/
.idea/
log/

86 changes: 62 additions & 24 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,39 +1,77 @@
FROM python:3.5
MAINTAINER Arne Schubert<[email protected]>
FROM python:3.11-slim-bookworm

ENV MAPPROXY_VERSION 1.11.0
ENV MAPPROXY_PROCESSES 4
ENV MAPPROXY_THREADS 2
# Notes by Just van den Broecke
# July 2020
# The original image (from 2019), based on Debian Buster Python3 was around 1GB.
# Slimmed down to 294MB by:
# - using Debian Slim image.
# - Using https://github.com/geopython/pygeoapi/blob/master/Dockerfile as example.
# - avoided building wheels by installing python- packages
# - removing build dependency packages.
#
# Upgrade notes: Debian bullseye-slim (follow up from Buster) has Python 3.8
# Currently compat problem with MP 1.12.0 because of "cgi" packages
# See issue: https://github.com/mapproxy/mapproxy/issues/462
# like wsgi-plugin-python3 (needs to wait)
#
# Upgrade notes: in bullseye: use libproj19 uwsgi-plugin-python3 (i.s.o. pip3 uwsgi)
# --plugin /usr/lib/uwsgi/plugins/python3_plugin.so in uwsgi command and remove --wsgi-disable-file-wrapper

# May 2024
# * Python 3.11 and MapProxy 2.0.2
# * upgrade Base image to python:3.11-slim-bookworm
# * drop support for EPSG:900913
# * patch TMS demo HTML

LABEL original_developer="Arne Schubert <[email protected]>"
LABEL contributor="Just van den Broecke <[email protected]>"

# Build ARGS
ARG TZ="Europe/Amsterdam"
ARG LOCALE="en_US.UTF-8"
# Only adds 1MB and handy tools
ARG ADD_DEB_PACKAGES="curl xsltproc libxml2-utils patch"
ARG ADD_PIP_PACKAGES=""
ARG MAPPROXY_VERSION="2.0.2"

# ENV settings
ENV MAPPROXY_PROCESSES="4" \
MAPPROXY_THREADS="2" \
UWSGI_EXTRA_OPTIONS="" \
DEBIAN_FRONTEND="noninteractive" \
PROJ_DATA="/usr/share/proj" \
PYTHONPATH="/usr/lib/python3/dist-packages" \
DEB_BUILD_DEPS="build-essential libpcre2-dev" \
DEB_PACKAGES="python3-pil python3-yaml python3-pyproj libgeos-dev python3-lxml libgdal-dev python3-shapely libxml2-dev libxslt-dev uwsgi-plugin-python3 ${ADD_DEB_PACKAGES}" \
PIP_PACKAGES="uwsgi requests geojson watchdog MapProxy==${MAPPROXY_VERSION} ${ADD_PIP_PACKAGES}"

RUN set -x \
&& apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \
python-imaging \
python-yaml \
libproj12 \
libgeos-dev \
python-lxml \
libgdal-dev \
build-essential \
python-dev \
libjpeg-dev \
zlib1g-dev \
libfreetype6-dev \
python-virtualenv \
&& rm -rf /var/lib/apt/lists/* \
&& apt update \
&& apt install --no-install-recommends -y ${DEB_BUILD_DEPS} ${DEB_PACKAGES} ${ADD_DEB_PACKAGES} \
&& useradd -ms /bin/bash mapproxy \
&& mkdir -p /mapproxy \
&& chown mapproxy /mapproxy \
&& pip install --upgrade pip \
&& pip install Shapely Pillow requests geojson uwsgi MapProxy==$MAPPROXY_VERSION \
&& mkdir -p /docker-entrypoint-initmapproxy.d
&& pip3 install ${PIP_PACKAGES} ${ADD_PIP_PACKAGES} \
&& mkdir -p /docker-entrypoint-initmapproxy.d \
&& pip3 uninstall --yes wheel \
&& pip3 cache purge \
&& ln -sf /usr/share/zoneinfo/${TZ} /etc/localtime \
&& apt-get remove --yes --purge ${DEB_BUILD_DEPS} \
&& apt-get --yes --purge autoremove \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

COPY patches/ /patches
RUN cd /patches && ./apply.sh && cd -

COPY docker-entrypoint.sh /
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["mapproxy"]

USER mapproxy
VOLUME ["/mapproxy"]

# Why needed? See examples.
# VOLUME ["/mapproxy"]
EXPOSE 8080
# Stats
EXPOSE 9191
112 changes: 77 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,16 @@
# Mapproxy for Docker
# MapProxy for Docker

MapProxy docker image from the [YAGA Development-Team](https://yagajs.org)
![GitHub license](https://img.shields.io/github/license/justb4/docker-mapproxy)
![GitHub release](https://img.shields.io/github/release/justb4/docker-mapproxy.svg)
![Docker Pulls](https://img.shields.io/docker/pulls/justb4/mapproxy.svg)

MapProxy Docker Image from the [YAGA Development-Team](https://github.com/yagajs).
Adapted by [justb4](https://github.com/justb4) to latest MP version, small Docker image and extended examples.
Find image on [Docker Hub](https://hub.docker.com/repository/docker/justb4/mapproxy).

## Supported tags

* `1.11.0`, `1.11`, `1`, `latest`
* `1.11.0-alpine`, `1.11-alpine`, `1-alpine`, `alpine`
* `1.10.4`, `1.10`
* `1.10.4-alpine`, `1.10-alpine`
* `1.10.3`
* `1.10.3-alpine`
* `1.10.2`
* `1.10.2-alpine`
* `1.10.1`
* `1.10.1-alpine`
* `1.10.0`
* `1.10.0-alpine`
* `1.9.1`, `1.9`
* `1.9.1-alpine`, `1.9-alpine`
* `1.9.0`
* `1.9.0-alpine`
* `1.8.2`, `1.8`
* `1.8.2-alpine`, `1.8-alpine`
* `1.8.1`
* `1.8.1-alpine`
* `1.8.0`
* `1.8.0-alpine`
* `1.7.1`, `1.7`
* `1.7.1-alpine`, `1.7-alpine`
* `1.7.0`
* `1.7.0-alpine`
See [Docker Hub](https://hub.docker.com/repository/docker/justb4/mapproxy)

## What is MapProxy

Expand All @@ -38,43 +19,104 @@ data from existing map services and serves any desktop or web GIS client.

## Run container

You can run the container with a command like this:
See the examples, these use `docker-compose`, more convenient than `docker run` commands:

* [default](examples/default) - default out-of-the-box example
* [standard](examples/standard) - mapproxy [config](examples/standard/config/mapproxy.yaml) with some facilities like GeoPackage tile cache, custom grid etc

The second example should give you a nice starter.

But you can run the container with standard `docker`:

```bash
docker run -v /path/to/mapproxy:/mapproxy -p 8080:8080 yagajs/mapproxy
docker run -v /path/to/mapproxy:/mapproxy -p 8080:8080 justb4/mapproxy
```

*It is optional, but recommended to add a volume. Within the volume mapproxy get the configuration, or create one
automatically. Cached tiles will be stored also into this volume.*

The container normally runs in [http-socket-mode](http://uwsgi-docs.readthedocs.io/en/latest/HTTP.html). If you will not
run the image behind a HTTP-Proxy, like [Nginx](http://nginx.org/), you can run it in direct http-mode by running:
The container normally runs in [http-socket-mode](http://uwsgi-docs.readthedocs.io/en/latest/HTTP.html). If you are not
running the image behind an HTTP-Proxy, like [Nginx](http://nginx.org/), you should run it in direct `http-mode` by running:

```bash
docker run -v /path/to/mapproxy:/mapproxy -p 8080:8080 yagajs/mapproxy mapproxy http
docker run -v /path/to/mapproxy:/mapproxy -p 8080:8080 justb4/mapproxy mapproxy http
```

### Environment variables

* `MAPPROXY_PROCESSES` default: 4
* `MAPPROXY_THREADS` default: 2
* `UWSGI_EXTRA_OPTIONS` extra `uwsgi` commandline options e.g. `"--disable-logging --stats 0.0.0.0:9191"`, default empty

### Run as local user

In some cases, especially when using mounted volumes, you may get permission issues on directories and (log-) files.
You can also have the Docker Container run as your local user (id) i.s.o. `mapproxy`. But never run as user root!

In a `docker-compose.yml` you may set: `user: ${HOST_UID_GID}`. This env var can be generated: `export HOST_UID_GID="$(id -u):$(id -g)"`, in your
local environment or a start script.

See the [docker-compose.yml in examples/standard](examples/standard/docker-compose.yml) and
[start.sh there](examples/standard/start.sh).

## Seeding

The image also allows arbitrary commands like for seeding:

```bash

docker exec -it mapproxy mapproxy-seed -f /mapproxy/mapproxy.yaml -s /mapproxy/seed.yaml --seed myseed1

```

## Proj Version Info

Proj in `/usr/lib` from `python3-proj` package.

```
$ /usr/bin/pyproj -v

pyproj info:
pyproj: 3.4.1
PROJ: 9.1.1
data dir: /usr/share/proj
user_data_dir: /tmp/proj
PROJ DATA (recommended version): 1.12
PROJ Database: 1.2
EPSG Database: v10.076 [2022-08-31]
ESRI Database: ArcGIS Pro 3.0 [2022-07-09]
IGNF Database: 3.1.0 [2019-05-24]

System:
python: 3.11.2 (main, Mar 13 2023, 12:18:29) [GCC 12.2.0]
executable: /usr/bin/python3
machine: Linux-6.6.22-linuxkit-aarch64-with-glibc2.36

Python deps:
certifi: 2022.9.24
Cython: None
setuptools: None
pip: None

```
## Enhance the image

You can put a `mapproxy.yaml` into the `/docker-entrypoint-initmapproxy.d` folder on the image. On startup this will be
used as MapProxy configuration. Attention, this will override an existing configuration in the volume!

Additional you can put shell-scripts, with `.sh`-suffix in that folder. They get executed on container startup.
In addition, you can put shell-scripts, with `.sh`-suffix in that folder. They get executed on container startup.

You should use the `mapproxy` user within the container, especially not `root`!

You can also add extra packages in build args: `ADD_DEB_PACKAGES` and `ADD_PIP_PACKAGES`.

## Contributing

You are invited to contribute new features, fixes, or updates, large or small; we are always thrilled to receive pull
requests, and do our best to process them as fast as we can.

Before you start to code, we recommend discussing your plans through a
[GitHub issue](https://github.com/yagajs/docker-mapproxy/issues), especially for more ambitious contributions.
[GitHub issue](https://github.com/justb4/docker-mapproxy/issues), especially for more ambitious contributions.
This gives other contributors a chance to point you in the right direction, give you feedback on your design, and help
you find out if someone else is working on the same thing.

Expand Down
20 changes: 15 additions & 5 deletions docker-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,25 @@ if [ "$1" = 'mapproxy' ]; then
if [ ! -f /mapproxy/app.py ] ;then
mapproxy-util create -t wsgi-app -f /mapproxy/mapproxy.yaml /mapproxy/app.py
fi
echo "Start mapproxy"

# --wsgi-disable-file-wrapper is required because of https://github.com/unbit/uwsgi/issues/1126
# Note: JvdB June 30, 2020: seems fixed but need Debian Bullseye:
# https://github.com/unbit/uwsgi/pull/2069, --wsgi-disable-file-wrapper even gives startup-error in Debian Bullseye...
# Also to wait for Bullseye: --plugin /usr/lib/uwsgi/plugins/python3_plugin.so
UWSGI_PROTO="http-socket"
if [ "$2" = 'http' ]; then
exec uwsgi --wsgi-disable-file-wrapper --http 0.0.0.0:8080 --wsgi-file /mapproxy/app.py --master --enable-threads --processes $MAPPROXY_PROCESSES --threads $MAPPROXY_THREADS --stats 0.0.0.0:9191
exit
UWSGI_PROTO="http"
fi

exec uwsgi --wsgi-disable-file-wrapper --http-socket 0.0.0.0:8080 --wsgi-file /mapproxy/app.py --master --enable-threads --processes $MAPPROXY_PROCESSES --threads $MAPPROXY_THREADS --stats 0.0.0.0:9191
echo "Start MapProxy with $MAPPROXY_PROCESSES processes and $MAPPROXY_THREADS threads, proto=$UWSGI_PROTO UWSGI_EXTRA_OPTIONS=$UWSGI_EXTRA_OPTIONS"
exec uwsgi \
--plugin /usr/lib/uwsgi/plugins/python3_plugin.so \
--$UWSGI_PROTO 0.0.0.0:8080 \
--wsgi-file /mapproxy/app.py \
--master \
--enable-threads \
--processes $MAPPROXY_PROCESSES \
--threads $MAPPROXY_THREADS \
$UWSGI_EXTRA_OPTIONS
exit
fi

Expand Down
17 changes: 17 additions & 0 deletions examples/default/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Example - Default

No configuration. Uses all defaults to have something working out-of-the-box.
Uses `docker-compose`.

How to use:

```
./build.sh
./start.sh
browse to http://localhost:8085/demo
./stop.sh
```

The local directory `./mapproxy` will be populated with a default config and MP WGSI app.
You can delete the directory `./mapproxy` after use or use that as a starter for your app.
See the other examples for more adavanced setup.
3 changes: 3 additions & 0 deletions examples/default/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash

docker-compose build
19 changes: 19 additions & 0 deletions examples/default/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Example docker-compose file, adapt for your setup
services:

mapproxy:

image: justb4/mapproxy:latest
build: ../../.

container_name: mapproxy

environment:
- MAPPROXY_PROCESSES=4
- MAPPROXY_THREADS=2

ports:
- "8085:8080"

# volumes:
# - ./mapproxy:/mapproxy:rw
5 changes: 5 additions & 0 deletions examples/default/start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash

mkdir -p mapproxy
docker-compose rm --force --stop
docker-compose up -d
3 changes: 3 additions & 0 deletions examples/default/stop.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash

docker-compose rm --force --stop
Loading