├── .gitignore ├── Dockerfile ├── README.md ├── etc ├── cesi.conf ├── init_supervisord ├── nginx.conf ├── nginx_site.conf ├── nginx_tilestache.conf ├── run_tilestache.py ├── supervisor_inet.conf ├── supervisor_uwsgi.ini └── uwsgi_tilestache.ini ├── ressources ├── README.md └── tilestache.cfg └── start.sh /.gitignore: -------------------------------------------------------------------------------- 1 | *~ -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Mapnik for Docker 2 | 3 | FROM ubuntu:16.04 4 | MAINTAINER Fabien Reboia 5 | 6 | ENV LANG C.UTF-8 7 | ENV MAPNIK_VERSION 3.0.10 8 | RUN update-locale LANG=C.UTF-8 9 | 10 | # Update and upgrade system 11 | RUN apt-get -qq update && apt-get -qq --yes upgrade 12 | 13 | # Essential stuffs 14 | RUN apt-get -qq install --yes build-essential openssh-server sudo software-properties-common curl 15 | 16 | # Boost 17 | RUN apt-get -qq install -y libboost-dev libboost-filesystem-dev libboost-program-options-dev libboost-python-dev libboost-regex-dev libboost-system-dev libboost-thread-dev 18 | 19 | # Mapnik dependencies 20 | RUN apt-get -qq install --yes libicu-dev libtiff5-dev libfreetype6-dev libpng12-dev libxml2-dev libproj-dev libsqlite3-dev libgdal-dev libcairo-dev python-cairo-dev postgresql-contrib libharfbuzz-dev 21 | 22 | # Mapnik 3.0.9 23 | RUN curl -s https://mapnik.s3.amazonaws.com/dist/v${MAPNIK_VERSION}/mapnik-v${MAPNIK_VERSION}.tar.bz2 | tar -xj -C /tmp/ && cd /tmp/mapnik-v${MAPNIK_VERSION} && python scons/scons.py configure JOBS=4 && make && make install JOBS=4 24 | 25 | # TileStache and dependencies 26 | RUN ln -s /usr/lib/x86_64-linux-gnu/libz.so /usr/lib 27 | RUN cd /tmp/ && curl -Os https://bootstrap.pypa.io/get-pip.py && python get-pip.py 28 | RUN apt-get install python-pil 29 | RUN pip install -U modestmaps simplejson werkzeug tilestache --allow-external PIL --allow-unverified PIL 30 | RUN mkdir -p /etc/tilestache 31 | COPY etc/run_tilestache.py /etc/tilestache/ 32 | 33 | 34 | # Uwsgi 35 | RUN pip install uwsgi 36 | RUN mkdir -p /etc/uwsgi/apps-enabled 37 | RUN mkdir -p /etc/uwsgi/apps-available 38 | COPY etc/uwsgi_tilestache.ini /etc/uwsgi/apps-available/tilestache.ini 39 | RUN ln -s /etc/uwsgi/apps-available/tilestache.ini /etc/uwsgi/apps-enabled/tilestache.ini 40 | 41 | # Supervisor 42 | RUN pip install supervisor 43 | RUN echo_supervisord_conf > /etc/supervisord.conf && printf "[include]\\nfiles = /etc/supervisord/*" >> /etc/supervisord.conf 44 | RUN mkdir -p /etc/supervisord 45 | COPY etc/supervisor_uwsgi.ini /etc/supervisord/uwsgi.ini 46 | COPY etc/supervisor_inet.conf /etc/supervisord/inet.conf 47 | COPY etc/init_supervisord /etc/init.d/supervisord 48 | RUN chmod +x /etc/init.d/supervisord 49 | 50 | # Nginx 51 | RUN add-apt-repository -y ppa:nginx/stable && apt-get -qq update && apt-get -qq install -y nginx 52 | COPY etc/nginx_site.conf /etc/nginx/sites-available/site.conf 53 | RUN ln -s /etc/nginx/sites-available/site.conf /etc/nginx/sites-enabled/ 54 | RUN rm /etc/nginx/sites-available/default /etc/nginx/sites-enabled/default 55 | 56 | # SSH config 57 | RUN mkdir /var/run/sshd 58 | RUN echo 'root:toor' | chpasswd 59 | RUN sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/' /etc/ssh/sshd_config 60 | # SSH login fix. Otherwise user is kicked off after login 61 | RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd 62 | 63 | # Start services 64 | RUN /etc/init.d/supervisord start 65 | RUN service nginx start 66 | 67 | EXPOSE 22 80 9001 68 | 69 | ENV HOST_IP `ifconfig | grep inet | grep Mask:255.255.255.0 | cut -d ' ' -f 12 | cut -d ':' -f 2` 70 | 71 | ADD start.sh / 72 | RUN chmod +x /start.sh 73 | 74 | CMD ["/start.sh"] 75 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | docker-mapnik 2 | =================== 3 | 4 | The purpose of this project is to provide a tile server using mapnik and tilestache. 5 | 6 | ## Mapnik 7 | 8 | Mapnik is a Free Toolkit for developing mapping applications. It's written in C++ and there are Python bindings to facilitate fast-paced agile development. It can comfortably be used for both desktop and web development 9 | 10 | ## TileStache 11 | 12 | TileStache is a Python-based server application that can serve up map tiles based on rendered geographic data. 13 | 14 | ## Building docker-mapnik 15 | 16 | Running this will build a docker image with mapnik 3.0.10 and TileStache. 17 | 18 | git clone https://github.com/srounet/docker-mapnik 19 | cd docker-mapnik 20 | docker build -t mapnik . 21 | 22 | 23 | ## Running docker-mapnik 24 | 25 | This image expose three ports 22 for ssh and 80 for Nginx/TileStache and 9001 for supervisord 26 | 27 | sudo docker run -d -P -v $(readlink --canonicalize ressources):/etc/tilestache/ressources/ -v $(readlink --canonicalize ressources/tilestache.cfg):/etc/tilestache/tilestache.cfg --name mapnik mapnik 28 | 29 | ## Image active users 30 | 31 | The root password is `toor`. 32 | 33 | ## Supervisord remote access 34 | 35 | Default user and password are: ma/ma1337 36 | 37 | ### Side note on tilestache 38 | 39 | Use ressources folder to synchronize your mapnik styles. 40 | Modify tilestache.cfg according to your needs, it should be synchronized with your Docker. 41 | Don't forget to restart tilestache from uwsgi / supervisord. 42 | -------------------------------------------------------------------------------- /etc/cesi.conf: -------------------------------------------------------------------------------- 1 | [node:] 2 | ;username = 3 | ;password = 4 | ;host = 5 | ;port = 6 | 7 | [node:] 8 | ;username = 9 | ;password = 10 | ;host = 11 | ;port = 12 | 13 | ;[environment:] 14 | ;members = , 15 | 16 | [cesi] 17 | database = /etc/cesi/userinfo.db 18 | activity_log = /var/log/cesi.log -------------------------------------------------------------------------------- /etc/init_supervisord: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | ### BEGIN INIT INFO 3 | # Provides: supervisord 4 | # Required-Start: $remote_fs 5 | # Required-Stop: $remote_fs 6 | # Default-Start: 2 3 4 5 7 | # Default-Stop: 0 1 6 8 | # Short-Description: Example initscript 9 | # Description: This file should be used to construct scripts to be 10 | # placed in /etc/init.d. 11 | ### END INIT INFO 12 | 13 | # Author: Dan MacKinlay 14 | # Based on instructions by Bertrand Mathieu 15 | # http://zebert.blogspot.com/2009/05/installing-django-solr-varnish-and.html 16 | 17 | # Do NOT "set -e" 18 | 19 | # PATH should only include /usr/* if it runs after the mountnfs.sh script 20 | PATH=/sbin:/usr/sbin:/bin:/usr/bin 21 | DESC="Description of the service" 22 | NAME=supervisord 23 | DAEMON=/usr/local/bin/supervisord 24 | DAEMON_ARGS="-c /etc/supervisord.conf" 25 | PIDFILE=/var/run/$NAME.pid 26 | SCRIPTNAME=/etc/init.d/$NAME 27 | 28 | # Exit if the package is not installed 29 | [ -x "$DAEMON" ] || exit 0 30 | 31 | # Read configuration variable file if it is present 32 | [ -r /etc/default/$NAME ] && . /etc/default/$NAME 33 | 34 | # Load the VERBOSE setting and other rcS variables 35 | . /lib/init/vars.sh 36 | 37 | # Define LSB log_* functions. 38 | # Depend on lsb-base (>= 3.0-6) to ensure that this file is present. 39 | . /lib/lsb/init-functions 40 | 41 | # 42 | # Function that starts the daemon/service 43 | # 44 | do_start() 45 | { 46 | # Return 47 | # 0 if daemon has been started 48 | # 1 if daemon was already running 49 | # 2 if daemon could not be started 50 | start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \ 51 | || return 1 52 | start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \ 53 | $DAEMON_ARGS \ 54 | || return 2 55 | # Add code here, if necessary, that waits for the process to be ready 56 | # to handle requests from services started subsequently which depend 57 | # on this one. As a last resort, sleep for some time. 58 | } 59 | 60 | # 61 | # Function that stops the daemon/service 62 | # 63 | do_stop() 64 | { 65 | # Return 66 | # 0 if daemon has been stopped 67 | # 1 if daemon was already stopped 68 | # 2 if daemon could not be stopped 69 | # other if a failure occurred 70 | start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME 71 | RETVAL="$?" 72 | [ "$RETVAL" = 2 ] && return 2 73 | # Wait for children to finish too if this is a daemon that forks 74 | # and if the daemon is only ever run from this initscript. 75 | # If the above conditions are not satisfied then add some other code 76 | # that waits for the process to drop all resources that could be 77 | # needed by services started subsequently. A last resort is to 78 | # sleep for some time. 79 | start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON 80 | [ "$?" = 2 ] && return 2 81 | # Many daemons don't delete their pidfiles when they exit. 82 | rm -f $PIDFILE 83 | return "$RETVAL" 84 | } 85 | 86 | # 87 | # Function that sends a SIGHUP to the daemon/service 88 | # 89 | do_reload() { 90 | # 91 | # If the daemon can reload its configuration without 92 | # restarting (for example, when it is sent a SIGHUP), 93 | # then implement that here. 94 | # 95 | start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME 96 | return 0 97 | } 98 | 99 | case "$1" in 100 | start) 101 | [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" 102 | do_start 103 | case "$?" in 104 | 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 105 | 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; 106 | esac 107 | ;; 108 | stop) 109 | [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" 110 | do_stop 111 | case "$?" in 112 | 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 113 | 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; 114 | esac 115 | ;; 116 | #reload|force-reload) 117 | # 118 | # If do_reload() is not implemented then leave this commented out 119 | # and leave 'force-reload' as an alias for 'restart'. 120 | # 121 | #log_daemon_msg "Reloading $DESC" "$NAME" 122 | #do_reload 123 | #log_end_msg $? 124 | #;; 125 | restart|force-reload) 126 | # 127 | # If the "reload" option is implemented then remove the 128 | # 'force-reload' alias 129 | # 130 | log_daemon_msg "Restarting $DESC" "$NAME" 131 | do_stop 132 | case "$?" in 133 | 0|1) 134 | do_start 135 | case "$?" in 136 | 0) log_end_msg 0 ;; 137 | 1) log_end_msg 1 ;; # Old process is still running 138 | *) log_end_msg 1 ;; # Failed to start 139 | esac 140 | ;; 141 | *) 142 | # Failed to stop 143 | log_end_msg 1 144 | ;; 145 | esac 146 | ;; 147 | *) 148 | #echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2 149 | echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2 150 | exit 3 151 | ;; 152 | esac 153 | 154 | exit 0 155 | -------------------------------------------------------------------------------- /etc/nginx.conf: -------------------------------------------------------------------------------- 1 | # nginx 2 | 3 | description "nginx http daemon" 4 | author "George Shammas " 5 | 6 | start on (filesystem and net-device-up IFACE=lo) 7 | stop on runlevel [!2345] 8 | 9 | env DAEMON=/opt/nginx/sbin/nginx 10 | env PID=/opt/nginx/logs/nginx.pid 11 | 12 | expect fork 13 | respawn 14 | respawn limit 10 5 15 | #oom never 16 | 17 | pre-start script 18 | $DAEMON -t 19 | if [ $? -ne 0 ] 20 | then exit $? 21 | fi 22 | end script 23 | 24 | exec $DAEMON 25 | -------------------------------------------------------------------------------- /etc/nginx_site.conf: -------------------------------------------------------------------------------- 1 | # site_nginx.conf 2 | upstream tilestache { 3 | server unix:///tmp/tilestache.sock; 4 | } 5 | 6 | server { 7 | listen 80; 8 | charset utf-8; 9 | server_name localhost; 10 | 11 | location / { 12 | uwsgi_pass tilestache; 13 | include /etc/nginx/uwsgi_params; 14 | } 15 | } -------------------------------------------------------------------------------- /etc/nginx_tilestache.conf: -------------------------------------------------------------------------------- 1 | # tilestache_nginx.conf 2 | upstream tilestache { 3 | server unix:///tmp/tilestache.sock; 4 | } 5 | 6 | server { 7 | # the port your site will be served on 8 | listen 80; 9 | charset utf-8; 10 | 11 | location /tilestache { 12 | uwsgi_pass tilestache; 13 | include /etc/nginx/uwsgi_params; 14 | } 15 | } -------------------------------------------------------------------------------- /etc/run_tilestache.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import TileStache 5 | 6 | 7 | application = TileStache.WSGITileServer('/etc/tilestache/ressources/tilestache.cfg') 8 | -------------------------------------------------------------------------------- /etc/supervisor_inet.conf: -------------------------------------------------------------------------------- 1 | [inet_http_server] 2 | port=*:9001 3 | username=ma 4 | password=ma1337 -------------------------------------------------------------------------------- /etc/supervisor_uwsgi.ini: -------------------------------------------------------------------------------- 1 | [program:uwsgi] 2 | directory = /root 3 | command = /usr/local/bin/uwsgi --emperor "/etc/uwsgi/apps-enabled/*" --die-on-term --master --catch-exceptions 4 | autostart = true 5 | autorestart = true -------------------------------------------------------------------------------- /etc/uwsgi_tilestache.ini: -------------------------------------------------------------------------------- 1 | [uwsgi] 2 | # Variables 3 | user = www-data 4 | group = www-data 5 | appname = %n 6 | 7 | # Config 8 | uid = %(user) 9 | gid = %(group) 10 | chmod-socket = 665 11 | processes = 4 12 | vacuum = true 13 | master = true 14 | socket = /tmp/%(appname).sock 15 | mount = /=/etc/tilestache/run_tilestache.py 16 | need-app = true 17 | -------------------------------------------------------------------------------- /ressources/README.md: -------------------------------------------------------------------------------- 1 | Placeholder for mapnik related ressources. 2 | Bind this folder to your host so you can easilly add config files for tilestache. -------------------------------------------------------------------------------- /ressources/tilestache.cfg: -------------------------------------------------------------------------------- 1 | { 2 | "cache": {"name": "Test"}, 3 | "logging": "debug", 4 | "layers": { 5 | "osm": { 6 | "provider": {"name": "proxy", "provider": "OPENSTREETMAP"} 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Start supervisord 4 | /etc/init.d/supervisord start 5 | # Start nginx 6 | service nginx start 7 | 8 | # Start sshd service 9 | /usr/sbin/sshd -D --------------------------------------------------------------------------------