Deployment guide

MapFish Print

Overview

MapFish Print is an open source Java service that renders printable map and report documents entirely server-side. A client, such as a GIS portal, an OpenLayers or GeoMapFish application, or a script, sends a JSON print specification that describes the layout, the map center and layers, and any titles or legends. MapFish Print returns a finished PDF, PNG, JPEG, BMP or TIFF built with the JasperReports rendering engine. It has powered production cartographic printing for GIS platforms for over a decade. It has no interactive UI of its own: it is a headless backend REST API that other applications call.

The SecureAnyCloud image runs the official print-servlet 4.0.6 WAR on Apache Tomcat 11 with OpenJDK 21, the exact combination that upstream ships in its own official Docker image. MapFish Print has no accounts of its own, so nginx adds a per-VM HTTP Basic Auth gate in front of it.

What you get:

  • MapFish Print 4.0.6 (official print-servlet.war) deployed on Apache Tomcat 11.0.23, running as the mapfish-print systemd service
  • OpenJDK 21 (never Oracle JDK)
  • The print REST API on :80, fronted by nginx, with Tomcat bound to loopback only
  • Per-VM HTTP Basic Auth (user admin) that protects the entire API, with a unique password generated on first boot
  • One working example print app (examples) bundled out of the box: a JasperReports layout with a local, self-contained GeoJSON world countries map layer. You can generate a real PDF with a single API call the moment the VM boots, with no external map server required.
  • mapfish-print.service and nginx.service as systemd units, enabled and active
  • An unauthenticated /healthz endpoint for Azure Load Balancer health probes
  • 24/7 SecureAnyCloud support

Prerequisites

  • An active Azure subscription, an SSH key pair, and a VNet and subnet in the target region.
  • A Standard_B2s VM (2 vCPU / 4 GiB RAM), a comfortable starting point for the bundled example app and typical single-map report jobs. Move to a larger size if you print large, high-DPI or multi-map reports.
  • NSG inbound rules that allow 22/tcp from your management network and 80/tcp for the print API.

MapFish Print serves plain HTTP on port 80. In production, terminate TLS in front of it with your own domain and restrict access to trusted IP ranges (see Maintenance).

Step 1 - Deploy from the Azure Marketplace

  • Sign in to the Azure Portal, choose Create a resource, search the Marketplace for MapFish Print by SecureAnyCloud, and select Create.
  • On Basics, pick your subscription, resource group, region and size.
  • Under Administrator account, choose SSH public key and paste your key.
  • Under Inbound port rules, allow SSH (22) and HTTP (80).
  • Review your settings, then select Review + create and Create.

Step 2 - Deploy from the Azure CLI

# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:mapfish-print-ubuntu-24-04:default:latest
az vm create \
  --resource-group <your-rg> \
  --name mapfish-print \
  --image sac1647283583153:mapfish-print-ubuntu-24-04:default:latest \
  --size Standard_B2s \
  --admin-username azureuser \
  --ssh-key-values ~/.ssh/id_ed25519.pub \
  --vnet-name <your-vnet> --subnet <your-subnet> \
  --public-ip-sku Standard
az vm open-port --resource-group <your-rg> --name mapfish-print --port 80 --priority 1010

Step 3 - Connect to your VM

ssh azureuser@<vm-public-ip>

Step 4 - Confirm the services are running

systemctl is-active mapfish-print.service nginx.service
sudo ss -tln | grep -E '127.0.0.1.*:8080 |:80 '

Both services report active. MapFish Print (Tomcat) is bound to the loopback address 127.0.0.1:8080 only. nginx fronts it on port 80 and is the only path in from the network.

Step 5 - Retrieve your API password

nginx protects the entire print API with HTTP Basic Auth. The username is admin. A unique password is generated on the first boot of your VM and written to a root-only file:

sudo cat /root/mapfish-print-credentials.txt

This file contains MAPFISH_PRINT_USERNAME, MAPFISH_PRINT_PASSWORD and the MAPFISH_PRINT_URL. The password is stored on disk only as a bcrypt hash in /etc/nginx/.mapfish-print.htpasswd, so no plaintext password ships in the image. Store the password somewhere safe.

You can also confirm the deployed version, the JVM, the loopback-only Tomcat connector and the bundled example print app's layout definition:

grep Mapfish-Print-Version /opt/tomcat/webapps/ROOT/META-INF/MANIFEST.MF java -version cat /opt/tomcat/webapps/ROOT/print-apps/examples/config.yaml

Step 6 - Confirm the health endpoint

nginx serves an unauthenticated health endpoint for load balancers and probes:

curl -s http://localhost/healthz

It returns ok. This endpoint never requires authentication, so you can use it for an Azure Load Balancer health probe.

Step 7 - Confirm authentication and list the print apps

Because a password is set on first boot, an unauthenticated request to the print API returns HTTP 401, so nobody can generate a print job without the password. The following command reads the per-VM password from the credentials file and proves the round trip. An unauthenticated request is rejected, a wrong password is rejected, and the correct password authenticates and lists the registered print apps.

PW=$(sudo grep '^MAPFISH_PRINT_PASSWORD=' /root/mapfish-print-credentials.txt | cut -d= -f2-)
echo "unauth : $(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1/print/apps.json)"
echo "wrongpw : $(curl -s -o /dev/null -w '%{http_code}' -u admin:wrong-pw http://127.0.0.1/print/apps.json)"
echo "authed : $(curl -s -o /dev/null -w '%{http_code}' -u admin:$PW http://127.0.0.1/print/apps.json)" curl -s -u admin:$PW http://127.0.0.1/print/apps.json

It prints unauth : 401, wrongpw : 401, authed : 200, then a JSON array listing the registered print apps, including examples, the bundled sample app.

Step 8 - Generate your first PDF

The bundled examples print app renders an A4 portrait report with a title and a world map built entirely from a local GeoJSON layer shipped in the image, so it needs no external map server. buildreport is the synchronous endpoint, and it returns the finished document directly in the response body. Post the bundled sample specification and save the result:

PW=$(sudo grep '^MAPFISH_PRINT_PASSWORD=' /root/mapfish-print-credentials.txt | cut -d= -f2-)
curl -u admin:$PW -H 'Content-Type: application/json' \
  -d @/etc/mapfish-print/sample-request.json \
  http://127.0.0.1/print/examples/buildreport.pdf -o report.pdf file report.pdf

The request returns HTTP 200, and report.pdf is a genuine multi-page PDF document, not just a successful status code. Copy the file off the VM with scp to view it, or point your own client at http://<vm-public-ip>/print/examples/buildreport.pdf with the same credentials.

Step 9 - Explore the print API further

MapFish Print also exposes capabilities, asynchronous job submission and status polling for larger reports:

PW=$(sudo grep '^MAPFISH_PRINT_PASSWORD=' /root/mapfish-print-credentials.txt | cut -d= -f2-)
# Describe the layouts, attributes and output formats a print app supports curl -s -u admin:$PW http://127.0.0.1/print/examples/capabilities.json
# Submit an asynchronous job (returns a reference ID + status/download URLs instead of blocking)
curl -s -u admin:$PW -H 'Content-Type: application/json' \
  -d @/etc/mapfish-print/sample-request.json \
  http://127.0.0.1/print/examples/report.pdf

Use the synchronous buildreport.<format> endpoint from Step 8 for small, fast reports and interactive use. For larger jobs, where you do not want the client to block on the HTTP request, use the asynchronous flow: report.<format>, then status/<ref>.json, then report/<ref>.

Step 10 - Add your own print app

Add a new directory under /opt/tomcat/webapps/ROOT/print-apps/<your-app>/ containing your own config.yaml and JasperReports .jrxml template. The layout used by the bundled examples app is a good starting point. Then restart the service so that MapFish Print picks up the new app:

PW=$(sudo grep '^MAPFISH_PRINT_PASSWORD=' /root/mapfish-print-credentials.txt | cut -d= -f2-) sudo systemctl restart mapfish-print
# Tomcat takes a few seconds to redeploy the webapp after a restart; poll until it answers. for i in $(seq 1 20); do curl -s -o /dev/null -w '%{http_code}' -u admin:$PW http://127.0.0.1/print/apps.json | grep -q 200 && break sleep 2 done curl -s -u admin:$PW http://127.0.0.1/print/apps.json

Your new app id (the directory name) now appears alongside examples, and you can run buildreport against it exactly as in Step 8. See the MapFish Print configuration documentation for the full attribute, layer, processor and JasperReports reference.

Maintenance

  • Password. The API password is set on first boot and stored as a bcrypt entry in /etc/nginx/.mapfish-print.htpasswd. To change it, run sudo htpasswd -B /etc/nginx/.mapfish-print.htpasswd admin, then run sudo systemctl reload nginx.
  • Print apps. Add or edit apps under /opt/tomcat/webapps/ROOT/print-apps/<app>/, then run sudo systemctl restart mapfish-print to pick up the changes.
  • Restricted access. MapFish Print serves plain HTTP on port 80. In production, restrict access to trusted IP ranges in your Network Security Group, and front the service with TLS (for example certbot with your own domain) terminating on :443.
  • Loopback binding. Tomcat is bound to 127.0.0.1:8080 in /opt/tomcat/conf/server.xml (the Connector element's address="127.0.0.1" attribute), so nginx is the only path in. Keep it that way, and do not change the connector to a public address.
  • Heap size. The JVM heap is set in /opt/tomcat/bin/setenv.sh (-Xms256m -Xmx1536m by default, sized for Standard_B2s). Increase it if you print large, high-DPI or multi-map reports and see out-of-memory errors in /opt/tomcat/logs/catalina.out.
  • Logs. Tomcat and MapFish Print logs live under /opt/tomcat/logs/catalina.out.
  • Security patches. Unattended-upgrades remains enabled, so the OS continues to receive security updates automatically.

Support

SecureAnyCloud provides 24/7 expert support for this image. Contact sales@secureanycloud.com.

Deploy on Azure

Launch MapFish Print on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.

View this image

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure