Deployment guide

Lizmap 3.9

Overview

Lizmap turns a QGIS desktop project into an interactive web map. A cartographer styles layers, popups, print layouts and attribute tables in QGIS Desktop and saves the project. Lizmap then publishes it in the browser, with the layer tree, legend, search, feature identification, attribute tables, printing and per-group access control already wired up.

There is no re-authoring step and no second styling language to learn. The map your GIS team designed is the map your users get.

Lizmap is the web-client half of a two-part architecture. The rendering half is QGIS Server, the OGC map server of the QGIS project. This SecureAnyCloud image ships the whole stack assembled and proven, so there is nothing to wire together.

Security is designed in rather than bolted on. QGIS Server has no authentication of its own, so this image never exposes it. The OGC endpoint listens on 127.0.0.1 only, and Lizmap is its sole client. Access control is Lizmap's own user, group and repository model, which is what you configure.

Lizmap's documented default account (admin/admin) is deleted during the build, so the image ships with zero accounts. The administrator and the PostgreSQL password are both generated uniquely on the first boot of your VM.

What you get:

  • Lizmap Web Client 3.9.9 (3Liz, MPL-2.0) on PHP 8.3-FPM behind nginx, installed from the official 3Liz release archive, with the version and SHA-256 recorded at /var/lib/sac/config/sac-lizmap-version
  • QGIS Server 3.44 LTR (GPL-2.0-or-later) from the official QGIS apt repository (qgis.org/ubuntu-ltr), verified at build time to have come from that repository
  • Two persistent QGIS Server FastCGI workers, one per vCPU, reachable only over local unix sockets
  • The mandatory Lizmap QGIS Server plugin 2.14.1, with the QGIS_SERVER_LIZMAP_REVEAL_SETTINGS gate already enabled
  • PostgreSQL 16 with PostGIS 3.4, holding both Lizmap's own account database and the map data, tuned for 4 GiB alongside the map renderers and listening on localhost only
  • A per-VM Lizmap administrator (lizmapadmin) and a per-VM PostgreSQL password, both generated at first boot
  • A demo QGIS project with PostGIS-backed layers, published in the demo repository and rendering on first boot
  • /usr/local/sbin/lizmap-selftest.sh, an end-to-end check you can re-run at any time
  • A dedicated Azure data disk at /srv/lizmap carrying both the published projects and the PostgreSQL cluster
  • An unauthenticated /healthz endpoint for Azure Load Balancer health probes
  • 24/7 SecureAnyCloud support

Prerequisites

You need an active Azure subscription, an SSH key pair, and a VNet and subnet in the target region.

Standard_B2s (2 vCPU / 4 GiB RAM) is the recommended size. The three memory-hungry tiers are tuned for it. Scale up if you publish large raster projects or expect heavy concurrent tile traffic.

Configure the network security group (NSG) to allow inbound 22/tcp from your management network, 80/tcp for Lizmap, and 443/tcp if you add TLS. The appliance serves plain HTTP on port 80. For production, terminate TLS 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 Lizmap by SecureAnyCloud, and select Create.

On the Basics tab, 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 the dedicated data disk on the Disks tab. Then select Review + create, followed by 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:lizmap-ubuntu-24-04:default:latest
az vm create \
  --resource-group <your-rg> \
  --name lizmap \
  --image sac1647283583153:lizmap-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 lizmap --port 80 --priority 1010

Step 3 - Connect to your VM

ssh azureuser@<vm-public-ip>

Step 4 - Confirm every tier is running

Lizmap is a four-tier appliance. Confirm that all four services report active:

systemctl is-active postgresql php8.3-fpm qgis-server@1 qgis-server@2 nginx
cat /var/lib/sac/config/sac-lizmap-version /var/lib/sac/config/sac-qgis-server-version \
  /var/lib/sac/config/sac-lizmap-server-plugin-version /var/lib/sac/config/sac-lizmap-postgis-version

Step 5 - Confirm first boot completed

First boot generates the per-VM secrets, publishes the demo project and proves an end-to-end map render. Only then does it write its sentinel. If the sentinel is present, all of that succeeded.

test -f /var/lib/sac/data/lizmap-firstboot.done && echo "first boot complete"
sudo systemctl is-active lizmap-firstboot.service

Step 6 - Retrieve your per-VM credentials

The image contains no accounts at all. Your administrator account and your database password were generated on this VM, on its first boot, and exist nowhere else. Read them from the credentials file:

sudo cat /root/lizmap-credentials.txt

Store the values somewhere safe. LIZMAP_ADMIN_USERNAME is lizmapadmin and LIZMAP_ADMIN_PASSWORD is a 24-character random string.

Step 7 - Confirm the health endpoint

/healthz is static, unauthenticated and served by nginx, so it is a safe Azure Load Balancer probe target:

curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1/healthz

Step 8 - Confirm QGIS Server is not exposed

QGIS Server has no authentication of its own. On this appliance it is bound to the loopback interface, so it is unreachable from the network and Lizmap is its only client. PostgreSQL is bound the same way. Check the listeners:

ss -lnt | grep -E ':(80|8081|5432)\s'

Port 80 listens on all interfaces. 8081 (QGIS Server) and 5432 (PostgreSQL) must show 127.0.0.1 only.

Step 9 - Run the end-to-end self-test

This is the same check that first boot runs. It signs in with the per-VM password and asks Lizmap for a rendered map image. It asserts that the returned raster shows a real picture rather than a blank tile. It also asserts that a wrong password is refused and that the service is still alive afterwards.

On success, it prints OK and nothing else.

sudo /usr/local/sbin/lizmap-selftest.sh
sudo -u postgres psql -d lizmap -c 'SELECT f_table_name, type, srid FROM geometry_columns ORDER BY 1'

Step 10 - Sign in to Lizmap

Open http://<vm-public-ip>/ in a browser. Choose Connect and sign in with the username and password from Step 6.

Step 11 - Open the demo map

The landing page lists every project you are allowed to see, grouped by repository. The bundled SecureAnyCloud demo repository contains one project.

Choose Load the map. Lizmap asks QGIS Server for tiles, and QGIS Server reads the layers from PostGIS. The map draws with the symbology defined in the QGIS project: categorised region fills, dashed routes and site markers.

Use the layer tree on the left to toggle layers. Use the zoom controls or your scroll wheel to move around. Every movement re-renders on the server, so the labelling and styling stay correct at every scale.

Step 12 - Read the attribute table

The attribute table is a Lizmap feature that QGIS Server alone does not provide. Choose the table icon in the left toolbar, then choose Detail next to sac_regions.

The rows come straight from PostGIS. Selecting a row highlights the matching feature on the map.

Step 13 - Review the administration interface

Choose Administration in the header. Server information reports the Lizmap version, the QGIS Server version and the plugins that QGIS Server has loaded. After any upgrade, it is the fastest way to confirm that the two halves of the stack agree.

Use Users and Rights to add colleagues. Lizmap ships three groups: admins (full administration), publishers (may see the project list in the admin panel) and users (ordinary viewers).

All three groups can already view the demo repository. Anonymous visitors cannot, which is why the landing page is empty until you sign in.

Step 14 - Add a user

Add accounts from the administration interface or from the command line. Replace the example login, email and password.

cd /var/www/lizmap && sudo -u www-data php lizmap/console.php \
  jcommunity:user:create --no-error-if-exist mapviewer viewer@example.com 'ChangeThisPassword123' >/dev/null 2>&1
sudo -u postgres psql -tAd lizmap -c "SELECT usr_login, usr_email FROM jlx_user WHERE usr_login='mapviewer'"
cd /var/www/lizmap && sudo -u www-data php lizmap/console.php acl2user:addgroup mapviewer users >/dev/null 2>&1
sudo -u postgres psql -tAd lizmap -c "SELECT id_aclgrp FROM jacl2_user_group WHERE login='mapviewer'"

Note that the option is --no-error-if-exist (singular) on console.php. Redirect stdout to /dev/null. The command echoes the account's password back to the terminal, and you do not want that in your shell history or in a log.

The new account can sign in immediately. It sees every repository that the users group has been granted.

Step 15 - Publish your own QGIS project

A Lizmap project is two files that live together in a repository directory. They are the QGIS project (.qgs) and its Lizmap configuration (.qgs.cfg), which the Lizmap plugin for QGIS Desktop writes when you choose Publish in Lizmap.

Copy both files into a repository directory under /srv/lizmap/projects/. The project appears immediately, with no restart.

# from your workstation scp my-project.qgs my-project.qgs.cfg azureuser@<vm-public-ip>:/tmp/
sudo install -o www-data -g qgis -m 0640 /dev/null /srv/lizmap/projects/demo/.keep && echo "repository writable"

Your layers must be readable by the appliance. Layers stored in a GeoPackage or Shapefile need to sit under /srv/lizmap with group qgis.

Layers stored in the bundled PostGIS database are read as the read-only qgis role over the local socket. That role authenticates by operating system identity rather than a password, so your project file never has to carry a credential.

sudo -u postgres psql -d lizmap -c "\du qgis"

To add a second repository, create the directory, register it, and grant a group access to it. This is useful for separating teams, because rights are granted per repository.

sudo install -d -o www-data -g qgis -m 0750 /srv/lizmap/projects/team-b && echo "directory created"
cd /var/www/lizmap && sudo -u www-data php lizmap/console.php repository:create team-b "Team B" team-b >/dev/null 2>&1 grep -c '^\[repository:team-b\]' /var/www/lizmap/lizmap/var/config/lizmapConfig.ini.php

Registering a repository does not grant anyone access to it. Lizmap gates every repository behind the lizmap.repositories.view right, scoped to that repository. Until you grant it, the repository is invisible to everyone.

cd /var/www/lizmap && sudo -u www-data php lizmap/console.php acl2:add users lizmap.repositories.view team-b >/dev/null 2>&1
sudo -u postgres psql -tAd lizmap -c "SELECT id_aclgrp FROM jacl2_rights WHERE id_aclsbj='lizmap.repositories.view' AND id_aclres='team-b'"

Both commands attempt the change and then prove the result, so they are safe to re-run. repository:create and acl2:add both refuse loudly if the repository or the right already exists.

Step 16 - Confirm the dedicated data volume

Everything that is yours, meaning the published projects and the whole PostgreSQL cluster, lives on a dedicated Azure data disk rather than the OS disk. Your data stays on its own volume, which you can snapshot and grow independently.

df -h /srv/lizmap
sudo -u postgres psql -tAc 'SHOW data_directory'

To grow the volume, resize the disk in the Azure Portal. The VM must be deallocated. Then extend the filesystem online:

sudo resize2fs /dev/disk/azure/scsi1/lun0

Maintenance

Add TLS before exposing this VM on the public internet. Lizmap serves plain HTTP on port 80, so sessions and passwords cross the network in clear text. Point a DNS record at the VM, allow 443/tcp in the NSG, and issue a certificate:

sudo apt-get update && sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d maps.example.com --redirect --agree-tos -m you@example.com

Patching. Every component is package-managed, so ordinary updates cover the whole stack: Lizmap's PHP runtime, QGIS Server (from the QGIS repository), PostgreSQL and PostGIS, and nginx. Unattended security upgrades are enabled by default. To preview pending updates, run:

sudo apt-get update && sudo apt-get -s dist-upgrade | tail -3

Upgrading Lizmap itself. Lizmap is the one component installed from an upstream release archive rather than a package. Back up first, then follow 3Liz's upgrade notes. Unpack the new release over /var/www/lizmap, re-run php lizmap/install/installer.php as www-data, and keep lizmap/var/config/ intact.

Back up the database and the projects. Both live on the data disk. The projects are plain files, and the database has everything else.

sudo -u postgres pg_dump -Fc lizmap > /tmp/lizmap-backup.dump && ls -lh /tmp/lizmap-backup.dump

Logs. Lizmap writes application errors to its own log. The map renderers and the web tier use the journal.

sudo tail -n 5 /var/www/lizmap/lizmap/var/log/errors.log 2>/dev/null || echo "no application errors"
sudo journalctl -u nginx -u php8.3-fpm -u 'qgis-server@*' --no-pager -n 10

Resetting the administrator password. If you lose the password, set a new one from the command line.

cd /var/www/lizmap && sudo -u www-data php lizmap/console.php \
  jcommunity:password:change --force lizmapadmin 'YourNewPassword'

Scaling. The two QGIS Server workers are sized one per vCPU for Standard_B2s. On a larger VM, add worker instances and matching nginx upstream entries, and raise pm.max_children in /etc/php/8.3/fpm/pool.d/www.conf.

grep -E '^(pm|pm.max_children) ' /etc/php/8.3/fpm/pool.d/www.conf

Support

SecureAnyCloud provides 24/7 support for this image. Lizmap is a product of 3Liz. QGIS and QGIS Server are products of the QGIS project. PostgreSQL and PostGIS are products of their respective projects. SecureAnyCloud is not affiliated with, endorsed by or sponsored by any of them.

For questions about the image, contact SecureAnyCloud support. For questions about Lizmap itself, see the Lizmap documentation.

Deploy on Azure

Launch Lizmap 3.9 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