Install QGIS 3.22 LTS with QGIS-SERVER-3.22 and Apache2 on Ubuntu 22.04 LTS

Install QGIS-SERVER-3.22 

(assuming 'qgis' and 'qgis-plugin-grass' already on Ubuntu 22.04 LTS)

(if not)

:~$ sudo apt install qgis qgis-plugin-grass


:~$ sudo apt install qgis-server

[sudo] password for paul:

Reading package lists... Done

Building dependency tree... Done

Reading state information... Done

qgis-server is already the newest version (3.22.16+dfsg-1~jammy3).

0 to upgrade, 0 to newly install, 0 to remove and 19 not to upgrade.

Check the version installed:

:~$ /usr/lib/cgi-bin/qgis_mapserv.fcgi --version

QGIS 3.22.16-Białowieża 'Białowieża' (exported)

QGIS code branchRelease 3.22

Qt version 5.15.3

Python version 3.10.6

GDAL/OGR version 3.6.2

PROJ version 9.1.1

EPSG Registry database version v10.076 (2022-08-31)

GEOS version 3.11.1-CAPI-1.17.1

SQLite version 3.37.2

OS Ubuntu 22.04.2 LTS

Now Install Apache2

:~$ sudo apt install apache2

[sudo] password for paul: 

Reading package lists... Done

Building dependency tree... Done

Reading state information... Done

The following additional packages will be installed:

  apache2-bin apache2-data apache2-utils libapr1

  libaprutil1 libaprutil1-dbd-sqlite3 libaprutil1-ldap


Suggested packages:

  apache2-doc apache2-suexec-pristine

  | apache2-suexec-custom www-browser

The following NEW packages will be installed

  apache2 apache2-bin apache2-data apache2-utils libapr1

  libaprutil1 libaprutil1-dbd-sqlite3 libaprutil1-ldap


0 to upgrade, 9 to newly install, 0 to remove and 3 not to upgrade.

Need to get 2,057 kB of archives.

After this operation, 8,216 kB of additional disk space will be used.

Do you want to continue? [Y/n] y

Get:1 jammy-updates/main amd64 libapr1 amd64 1.7.0-8ubuntu0.22.04.1 [108 kB]

Get:2 jammy-updates/main amd64 libaprutil1 amd64 1.6.1-5ubuntu4.22.04.1 [92.6 kB]

Get:3 jammy-updates/main amd64 libaprutil1-dbd-sqlite3 amd64 1.6.1-5ubuntu4.22.04.1 [11.3 kB]

Get:4 jammy-updates/main amd64 libaprutil1-ldap amd64 1.6.1-5ubuntu4.22.04.1 [9,168 B]

Get:5 jammy/main amd64 liblua5.3-0 amd64 5.3.6-1build1 [140 kB]

Get:6 jammy-updates/main amd64 apache2-bin amd64 2.4.52-1ubuntu4.5 [1,345 kB]

Get:7 jammy-updates/main amd64 apache2-data all 2.4.52-1ubuntu4.5 [165 kB]

Get:8 jammy-updates/main amd64 apache2-utils amd64 2.4.52-1ubuntu4.5 [89.1 kB]

Get:9 jammy-updates/main amd64 apache2 amd64 2.4.52-1ubuntu4.5 [97.8 kB]

Fetched 2,057 kB in 33s (62.1 kB/s)

Selecting previously unselected package libapr1:amd64.

(Reading database ... 279146 files and directories currently installed.)

Preparing to unpack .../0-libapr1_1.7.0-8ubuntu0.22.04.1_amd64.deb ...

Unpacking libapr1:amd64 (1.7.0-8ubuntu0.22.04.1) ...

Selecting previously unselected package libaprutil1:amd64.

Preparing to unpack .../1-libaprutil1_1.6.1-5ubuntu4.22.04.1_amd64.deb ...

Unpacking libaprutil1:amd64 (1.6.1-5ubuntu4.22.04.1) ...

Selecting previously unselected package libaprutil1-dbd-sqlite3:amd64.

Preparing to unpack .../2-libaprutil1-dbd-sqlite3_1.6.1-5ubuntu4.22.04.1_amd64.deb ...

Unpacking libaprutil1-dbd-sqlite3:amd64 (1.6.1-5ubuntu4.22.04.1) ...

Selecting previously unselected package libaprutil1-ldap:amd64.

Preparing to unpack .../3-libaprutil1-ldap_1.6.1-5ubuntu4.22.04.1_amd64.deb ...

Unpacking libaprutil1-ldap:amd64 (1.6.1-5ubuntu4.22.04.1) ...

Selecting previously unselected package liblua5.3-0:amd64.

Preparing to unpack .../4-liblua5.3-0_5.3.6-1build1_amd64.deb ...

Unpacking liblua5.3-0:amd64 (5.3.6-1build1) ...

Selecting previously unselected package apache2-bin.

Preparing to unpack .../5-apache2-bin_2.4.52-1ubuntu4.5_amd64.deb ...

Unpacking apache2-bin (2.4.52-1ubuntu4.5) ...

Selecting previously unselected package apache2-data.

Preparing to unpack .../6-apache2-data_2.4.52-1ubuntu4.5_all.deb ...

Unpacking apache2-data (2.4.52-1ubuntu4.5) ...

Selecting previously unselected package apache2-utils.

Preparing to unpack .../7-apache2-utils_2.4.52-1ubuntu4.5_amd64.deb ...

Unpacking apache2-utils (2.4.52-1ubuntu4.5) ...

Selecting previously unselected package apache2.

Preparing to unpack .../8-apache2_2.4.52-1ubuntu4.5_amd64.deb ...

Unpacking apache2 (2.4.52-1ubuntu4.5) ...

Setting up libapr1:amd64 (1.7.0-8ubuntu0.22.04.1) ...

Setting up liblua5.3-0:amd64 (5.3.6-1build1) ...

Setting up apache2-data (2.4.52-1ubuntu4.5) ...

Setting up libaprutil1:amd64 (1.6.1-5ubuntu4.22.04.1) ...

Setting up libaprutil1-ldap:amd64 (1.6.1-5ubuntu4.22.04.1) ...

Setting up libaprutil1-dbd-sqlite3:amd64 (1.6.1-5ubuntu4.22.04.1) ...

Setting up apache2-utils (2.4.52-1ubuntu4.5) ...

Setting up apache2-bin (2.4.52-1ubuntu4.5) ...

Setting up apache2 (2.4.52-1ubuntu4.5) ...

Enabling module mpm_event.

Enabling module authz_core.

Enabling module authz_host.

Enabling module authn_core.

Enabling module auth_basic.

Enabling module access_compat.

Enabling module authn_file.

Enabling module authz_user.

Enabling module alias.

Enabling module dir.

Enabling module autoindex.

Enabling module env.

Enabling module mime.

Enabling module negotiation.

Enabling module setenvif.

Enabling module filter.

Enabling module deflate.

Enabling module status.

Enabling module reqtimeout.

Enabling conf charset.

Enabling conf localized-error-pages.

Enabling conf other-vhosts-access-log.

Enabling conf security.

Enabling conf serve-cgi-bin.

Enabling site 000-default.

Created symlink /etc/systemd/system/ → /lib/systemd/system/apache2.service.

Created symlink /etc/systemd/system/ → /lib/systemd/system/apache-htcacheclean.service.

Processing triggers for ufw (0.36.1-4build1) ...

Processing triggers for man-db (2.10.2-1) ...

Processing triggers for libc-bin (2.35-0ubuntu3.1) ...

Install libapache2-mod-fcgid

:~$ sudo apt install qgis-server libapache2-mod-fcgid

Reading package lists... Done

Building dependency tree... Done

Reading state information... Done

qgis-server is already the newest version (3.22.16+dfsg-1~jammy3).

The following NEW packages will be installed


0 to upgrade, 1 to newly install, 0 to remove and 3 not to upgrade.

Need to get 64.9 kB of archives.

After this operation, 242 kB of additional disk space will be used.

Do you want to continue? [Y/n] y

Get:1 jammy/universe amd64 libapache2-mod-fcgid amd64 1:2.3.9-4 [64.9 kB]

Fetched 64.9 kB in 5s (12.3 kB/s)             

Selecting previously unselected package libapache2-mod-fcgid.

(Reading database ... 279851 files and directories currently installed.)

Preparing to unpack .../libapache2-mod-fcgid_1%3a2.3.9-4_amd64.deb ...

Unpacking libapache2-mod-fcgid (1:2.3.9-4) ...

Setting up libapache2-mod-fcgid (1:2.3.9-4) ...

apache2_invoke: Enable module fcgid

Enable the 'fcgid' module

:~$ sudo a2enmod fcgid

Module fcgid already enabled

Configure 'serve-cgi-bin' 

ThinkPad-E570:~$ sudo a2enconf serve-cgi-bin

Conf serve-cgi-bin already enabled

Restart 'apache2' service

:~$ sudo service apache2 restart

Check that the 'apache2' main config file looks as below

:~$ sudo nano /etc/apache2/sites-available/000-default.conf

<VirtualHost *:80>
       # The ServerName directive sets the request scheme, hostname and port that
       # the server uses to identify itself. This is used when creating
       # redirection URLs. In the context of virtual hosts, the ServerName
       # specifies what hostname must appear in the request's Host: header to
       # match this virtual host. For the default virtual host (this file) this
       # value is not decisive as it is used as a last resort host regardless.
       # However, you must set it for any further virtual host explicitly.

       ServerAdmin webmaster@localhost
       DocumentRoot /var/www/html

       # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
       # error, crit, alert, emerg.
       # It is also possible to configure the loglevel for particular
       # modules, e.g.
       #LogLevel info ssl:warn

       ErrorLog ${APACHE_LOG_DIR}/error.log
       CustomLog ${APACHE_LOG_DIR}/access.log combined

       # For most configuration files from conf-available/, which are
       # enabled or disabled at a global level, it is possible to
       # include a line for only one particular virtual host. For example the
       # following line enables the CGI configuration for this host only
       # after it has been globally disabled with "a2disconf".
       #Include conf-available/serve-cgi-bin.conf

We will now create a new site called 'qgisserver.conf'

:~$ sudo nano /etc/apache2/sites-available/qgisserver.conf

<VirtualHost *:80>
      ServerAdmin webmaster@localhost
      ServerName qgisserver

      DocumentRoot /var/www/html

      # Apache logs (different than QGIS Server log)
      ErrorLog ${APACHE_LOG_DIR}/qgisserver.error.log
      CustomLog ${APACHE_LOG_DIR}/qgisserver.access.log combined

      # Longer timeout for WPS... default = 40
      FcgidIOTimeout 120

      FcgidInitialEnv LC_ALL "en_US.UTF-8"
      FcgidInitialEnv PYTHONIOENCODING UTF-8
      FcgidInitialEnv LANG "en_US.UTF-8"

      # QGIS log
      FcgidInitialEnv QGIS_SERVER_LOG_STDERR 1
      FcgidInitialEnv QGIS_SERVER_LOG_LEVEL 0

      # default QGIS project
      SetEnv QGIS_PROJECT_FILE /home/qgis/projects/world.qgs

      # QGIS_AUTH_DB_DIR_PATH must lead to a directory writeable by the Server's FCGI  proces>
      FcgidInitialEnv QGIS_AUTH_DB_DIR_PATH "/home/qgis/qgisserverdb/"
      FcgidInitialEnv QGIS_AUTH_PASSWORD_FILE "/home/qgis/qgisserverdb/qgis-auth.db"

      # Set pg access via pg_service file
      SetEnv PGSERVICEFILE /home/qgis/.pg_service.conf
      FcgidInitialEnv PGPASSFILE "/home/qgis/.pgpass"

      # if qgis-server is installed from packages in debian based distros this is   usually /u>
      # run "locate qgis_mapserv.fcgi" if you don't know where qgis_mapserv.fcgi is

      ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
      <Directory "/usr/lib/cgi-bin/">
      AllowOverride None
      Options +ExecCGI -MultiViews -SymLinksIfOwnerMatch
      Require all granted

      <IfModule mod_fcgid.c>
      FcgidMaxRequestLen 26214400
      FcgidConnectTimeout 60


Make a 'log' directory

:~$ sudo mkdir -p /var/log/qgis

Add some 'permissions'

:~$ sudo chown www-data:www-data /var/log/qgis

:~$ sudo mkdir -p /home/qgis/qgisserverdb

:~$ sudo chown www-data:www-data /home/qgis/qgisserverdb

Now lets enable 'qgisserver'

:~$ sudo a2ensite qgisserver

Enabling site qgisserver.

To activate the new configuration, you need to run:

  systemctl reload apache2

Restart apache2 after configuration

:~$ systemctl restart apache2

:~$ sudo sh -c "echo ' qgisserver' >> /etc/hosts"




The home path should always be '/home/qgis' and NOT '/home/my-home-name/qgis'


Add a 'projects' folder inside the 'cgi-bin' folder

If you choose to create a 'projects' folder within the 'cgi-bin' folder (as for example in /usr/lib/cgi-bin/projects/) remember to symlink in both the 'wms_metadata.xml' and the 'qgis_mapserv.fcgi' as well as linking your 'world.qgs' file (in my case from my...'/home/qgis/projects' directory) into the '/usr/lib/cgi-bin/projects' folder:-

:~$ sudo mkdir /usr/lib/cgi-bin/projects

:~$ cd /usr/lib/cgi-bin/projects

:~$ sudo ln -s ../qgis_mapserv.fcgi .

:~$ sudo ln -s ../wms_metadata.xml .

:~$ sudo ln -s /home/qgis/projects/world.qgs /usr/lib/cgi-bin/projects/world.qgs

:~$ sudo ln -s /home/qgis/projects/world.qgs.cfg /usr/lib/cgi-bin/projects/world.qgs.cfg

There be extra accompanying (gpkg) layers from the local 'projects' which needs to be 'symlinked' across too:-

:~$ sudo ln -s /home/qgis/projects/mylayer.gpkg /usr/lib/cgi-bin/projects/

Now check your 'QGIS-SERVER' output in a browser with a 'GetCapabilities' request


If you see this error:-


Project file error. For OWS services: please provide a SERVICE and a MAP parameter pointing to a valid QGIS project file


Ensure your 'qgis' directory is  '/home/qgis'  NOT  '/home/my-home-directory-name/qgis'

Now lets add some more server parameters to the url and a 'GetMap' request












URL will provide a 'GetMap' request for the layers as a stack of 'png' files.


Showing the result of the browser output from the above url in Firefox

And...the same server through QGIS Web Client 2 as a series of WMS Services. 

LAYER ORDER STACKING (is in reverse order):-




UPDATES TO YOUR MAIN 'MASTER' PROJECT (which is stored in my 'Documents' directory in my case)

:~$ sudo cp -r /home/paul/Documents/world.qgs /home/qgis/projects/

**It is already 'symlinked' to '/usr/lib/cgi-bin/projects/world.qgs'**

Now you have a working QGIS -SERVER ready to deliver your layers as a WMS Service


Popular posts from this blog

Qgis-server...Installing the QGIS Lizmap Plugin & Lizmap Web Client

Qgis-server...Installation on Ubuntu 16.04 LTS

Qgis-server...Bringing a map image into the browser on Ubuntu 16.04 LTS