Skip to content
Merged
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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
145 changes: 138 additions & 7 deletions workshop/content/docs/mapfile/config.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,147 @@
# MapServer Configuration File

MapServer 8.0 introduced support for a global [CONFIG](https://mapserver.org/mapfile/config.html) file.
This allows settings to be defined once and applied to all Mapfiles in a MapServer deployment,
reducing duplication and simplifying configuration.

This tutorial provides an introduction to the `CONFIG` file, and highlights the [Index Page](https://mapserver.org/output/index-page.html)
functionality that it enables.

![MapServer Index Page](../assets/images/mapserver-index-page.png)

## Overview

The configuration file used for the workshop can be found at `workshop/exercises/mapfiles/mapserver.conf`.
It uses a structure similar to a Mapfile, with configuration organized into blocks that are terminated with `END`.

```scala
CONFIG
ENV
...
END
MAPS
...
END
PLUGINS
# not currently used in the workshop, this block can be used
# to add plugins for Oracle and Microsoft SQL Server drivers
...
END
END
```

!!! important

If you make changes in the `CONFIG` file you need to restart the web server.
The configuration file is read only when the web server (Apache in this workshop) starts.
The easiest way to do this in the workshop is to restart the `mapserver` container:

```bash
docker restart mapserver
```

## `ENV` Settings

The `ENV` (Environment) block is used to store
[Environment Variables](https://mapserver.org/optimization/environment_variables.html) used by MapServer.
Placing them in the configuration file means they do not have to be duplicated in every Mapfile.
Settings defined in the configuration file can be overridden by settings in individual Mapfiles.
When both are present, the Mapfile value takes precedence.

In the workshop configuration file, the following variables are set:

- `MS_ONLINERESOURCE ""` the `ONLINERESOURCE` is used by various services, such as WMS, and WFS, to generate
links, for example in `GetCapabilities` requests. An option to set this globally in the `CONFIG` file
was added in MapServer 8.8 (see [RFC 141](https://mapserver.org/development/rfc/ms-rfc-141.html)) to avoid having to set
`ows_onlineresource` for different servers (for example in development and production) in every Mapfile.
In this workshop it is set to an empty string, allowing MapServer to automatically generate URLs based
on the incoming request host and path.
- `OGCAPI_HTML_TEMPLATE_DIRECTORY "/usr/local/share/mapserver/ogcapi/templates/html-bootstrap/"`
this setting points MapServer to the folder containing the Bootstrap HTML templates used when generating
the OGC API interface, for example at <http://localhost:7000/timisoara/ogcapi/?f=html>.
- `MS_INDEX_TEMPLATE_DIRECTORY "/usr/local/share/mapserver/ogcapi/templates/html-index-bootstrap/"`
a similar setting, but used to point to the Bootstrap templates used when generating the MapServer
[Index Pages](https://mapserver.org/output/index-page.html).
- `MS_MAP_PATTERN "^/etc/mapserver/"` - This is a required setting used to restrict Mapfiles
to specific filesystem locations. This prevents users from requesting arbitrary Mapfiles,
reducing the risk of unauthorised data access. In the workshop Mapfiles are restricted
to `/etc/mapserver` and subdirectories.

!!! tip

There are several other settings commented out in the configuration file, to show the different
environment variables available.

These can be set globally in the `CONFIG` file, and then overridden in individual Mapfiles,
using the syntax `CONFIG "VARIABLE_NAME" "VARIABLE_VALUE"`, for example `CONFIG "MS_ERRORFILE" "stderr"`.

## `MAPS` Settings

The `MAPS` block contains a list of all Mapfiles available on the server, in the form of
`key "path"`:

```scala
MAPS
# the paths used here, are the paths
# within the MapServer Docker container
CLUSTERS "/etc/mapserver/clusters.map"
CONTOURS "/etc/mapserver/contours.map"
# additional mapfiles...
END
```

The keys allow us to access the Mapfile using the URL in the form `http://server/KEY/`.

!!! note

Mapfiles explicitly registered in the `MAPS` section are considered trusted and are not
subject to `MS_MAP_PATTERN` validation because they are defined server-side rather than
provided by client requests.

`MS_MAP_PATTERN` is only applied when a Mapfile path is supplied by a client
request, for example:

`?map=/etc/mapserver/lines.map`

If we have set the `MS_INDEX_TEMPLATE_DIRECTORY` path in the `ENV` section above, then MapServer
will return an "Index Page", listing all these maps at the root of the MapServer URL: <http://localhost:7000/>.

Clicking on one of these links takes you to an individual Mapfile Landing Page, which lists the
services available for that Mapfile, such as WMS, WFS, WCS, and OGC APIs. For example <http://localhost:7000/timisoara/>.

## Code

!!! example

- MapServer Index Page request: <http://localhost:7000/>
- MapServer Mapfile Landing Page example: <http://localhost:7000/timisoara/>

??? Config file "mapserver.conf"

``` scala
--8<-- "mapserver.conf"
```

??? Example Mapfile file "config.map"

Set this in the config file
MS_ONLINERESOURCE "/"
``` scala
--8<-- "config.map"
```

## Exercises

Include the one used by the workshop
- Add the Mapfile `./workshop/exercises/mapfiles/config.map` to the configuration file
`./workshop/exercises/mapfiles/mapserver.conf`. Check it appears in the MapServer Index page
at <http://localhost:7000/>. You will need to restart the MapServer container to see this change.
- Enable the CGI functionality in the Mapfile by changing `"ms_enable_modes" "!*"`
to `"*"` (or comment-out the whole line). This should create a new "OpenLayers Viewer"
link at <http://localhost:7000/CONFIG_MAP/>.
- Comment and uncomment the various `enable_request` `METADATA` items, and see how they affect
the available services for the Mapfile at <http://localhost:7000/CONFIG_MAP/>.

Any changes in the CONFIG file you need to restart the web server:
!!! tip

```bash
docker restart mapserver
```
When editing a Mapfile, changes are instantly reflected in the HTML Index Pages
(when you refresh the browser). You only need to restart the MapServer Docker container
if you edit the `mapserver.conf` file, as this is read once when the Apache web server
starts.
3 changes: 2 additions & 1 deletion workshop/content/zensical.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ nav = [
{ "Lines" = "mapfile/lines.md" },
{ "Points" = "mapfile/points.md" },
{ "Labels" = "mapfile/labels.md" },
{ "Polygons" = "mapfile/polygons.md" }
{ "Polygons" = "mapfile/polygons.md" },
{ "Configuration File" = "mapfile/config.md" }
]},
{ "Inputs" = [
{ "Raster Data" = "inputs/raster.md" },
Expand Down
34 changes: 34 additions & 0 deletions workshop/exercises/mapfiles/config.map
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
MAP
NAME "CONFIG_MAP"
SIZE 800 400
PROJECTION
"epsg:4326"
END
IMAGECOLOR "#37929E"
WEB
IMAGEPATH "/etc/mapserver/tmp/"
METADATA
#"ms_enable_modes" "!*" # !* disables all CGI requests
# "wms_enable_request" "*"
# "wcs_enable_request" "*"
# "wfs_enable_request" "*"
# "ows_enable_request" "*"
END
END
EXTENT -180 -90 180 90
LAYER
NAME "countries"
TYPE POLYGON
STATUS DEFAULT
CONNECTIONTYPE FLATGEOBUF
DATA "data/naturalearth/ne_110m_admin_0_countries.fgb"

CLASS
STYLE
COLOR "#C7CAB0"
OUTLINECOLOR 255 255 255
WIDTH 0.1
END
END
END
END
2 changes: 1 addition & 1 deletion workshop/exercises/mapfiles/countries.map
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Comment can be added using a hash (#) at the start of a line
# All Mapfiles begin with a MAP block, and finish with a closing END
MAP
NAME "mymap"
NAME "Countries"

# the default size used for image output
SIZE 800 400
Expand Down
35 changes: 21 additions & 14 deletions workshop/exercises/mapfiles/mapserver.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#
# MapServer Config File
# (used by the workshop)
#
CONFIG

Expand All @@ -11,10 +12,22 @@ CONFIG
MS_ONLINERESOURCE ""

#
# Limit Mapfile Access
# OGC API
#
OGCAPI_HTML_TEMPLATE_DIRECTORY "/usr/local/share/mapserver/ogcapi/templates/html-bootstrap/"

#
# Landing page
#
MS_INDEX_TEMPLATE_DIRECTORY "/usr/local/share/mapserver/ogcapi/templates/html-index-bootstrap/"

#
# Limit Mapfile Access
# required - Mapfiles can only be loaded if they match this regex
MS_MAP_PATTERN "^/etc/mapserver/"

# MS_MAP_NO_PATH "1"
# MS_MAP_PATTERN "^/opt/mapserver" ## required
# MS_MAP_PATTERN "^/opt/mapserver"

#
# Global Log/Debug Setup
Expand All @@ -28,9 +41,9 @@ CONFIG
# MS_MAPFILE "/opt/mapserver/test/test.map"

#
# Proj Library
# Proj (path to proj.db)
#
# PROJ_LIB ""
# PROJ_DATA ""

#
# Request Control
Expand All @@ -48,17 +61,8 @@ CONFIG
# MS_XMLMAPFILE_XSLT
# MS_MODE
# MS_OPENLAYERS_JS_URL
# MS_TEMPPATH
# MS_MAX_OPEN_FILES

#
# OGC API
#
OGCAPI_HTML_TEMPLATE_DIRECTORY "/usr/local/share/mapserver/ogcapi/templates/html-bootstrap/"
MS_INDEX_TEMPLATE_DIRECTORY "/usr/local/share/mapserver/ogcapi/templates/html-index-bootstrap/"
MS_MAP_PATTERN "."

# MS_TEMPPATH "/etc/mapserver/tmp"
# MS_MAX_OPEN_FILES
END

#
Expand Down Expand Up @@ -90,6 +94,9 @@ CONFIG
VECTOR-TILES "/etc/mapserver/vector-tiles.map"
WCS "/etc/mapserver/wcs.map"
WFS "/etc/mapserver/wfs.map"

# Example for ./workshop/content/docs/mapfile/config.md
# CONFIG_MAP "/etc/mapserver/config.map"
END

END
25 changes: 25 additions & 0 deletions workshop/exercises/scripts/map_configs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
r"""
C:\VirtualEnvs\mappyfile3\Scripts\Activate.ps1
cd D:\GitHub\getting-started-with-mapserver
python ./workshop/exercises/scripts/map_configs.py
"""

import mappyfile
import json
from pathlib import Path

fn = r"./workshop/exercises/mapfiles/mapserver.conf"
d = mappyfile.open(fn, include_comments=True)

maps = {} # d["maps"]

# get .MAP files

map_files = [p for p in Path("./workshop/exercises/mapfiles").glob("*.map")]

for mf in sorted(map_files):
maps[mf.stem.upper()] = f"/etc/mapserver/{mf.name}"

d["maps"] = maps

print(mappyfile.dumps(d, indent=4))