Shigola Configuration
Overview
The Shigola config file uses TOML syntax with additional support for environment variables. It is comprised of five primary sections:
- Global: global options
- Webserver: webserver configuration.
- Providers: data provider configuration (i.e. PostGIS).
- Maps: map configuration including map names, layers and zoom levels.
- Cache: cache configurations.
Two further sections are optional and documented on their own pages:
- Tracing:
[tracing], OpenTelemetry export over OTLP. [observer]: Prometheus metrics.
Two optional keys are worth knowing about up front:
- A map may name the tiling schemes it serves with
tile_matrix_sets.[cache]acceptstype = "multi"for a layered cache, andtimeout_mson any cache.
Global
Unlike the other sections, global config options do not have [[]] heading.
| Param | Requered | Default | Description |
|---|---|---|---|
| tile_buffer | No | 64 | The number of pixels to extend a tile's clipping area |
Webserver
The webserver part of the config has the following parameters:
| Param | Required | Default | Description |
|---|---|---|---|
| port | No | :8080 | A string with the value for port. |
| hostname | No | HTTP Hostname in request | Set the hostname used to generate URLs for JSON based responses. |
| uri_prefix | No | A prefix to add to all API routes. This is useful when shigola is behind a proxy (i.e. example.com/shigola). The prefix will be added to all URLs Shigola includes in its responses. |
Headers
Allows shigola to respond to tile request with user defined headers. Default CORS headers values:
| Header | Default |
|---|---|
| Access-Control-Allow-Origin | "*" |
| Access-Control-Allow-Methods | "GET, OPTIONS" |
Example Webserver config
[webserver]
port = ":8080"
hostname = "tiles.example.com"
[webserver.headers]
# redefine default cors origin
Access-Control-Allow-Origin = "http://map.example.com"
# define CDN max age
Cache-Control = "s-maxage=300"
Providers
The providers configuration tells Shigola where your data lives. Data providers each have their own specific configuration, but all are required to have the following two config params:
| Param | Description |
|---|---|
| name | User defined data provider name. This is used by map layers to reference the data provider. |
| type | The type of data provider. mvt_postgis is the only one. |
PostGIS
Load data from a Postgres/PostGIS database. The type is mvt_postgis: the tile is encoded by the
database with ST_AsMVT, and Shigola serves the bytes it
returns.
postgis was removed — use mvt_postgis. A second type, postgis, pulled raw geometry into
Shigola and encoded the tile in Go. It returned distorted polygon and multipolygon geometries
(go-spatial/tegola#1104),
which mvt_postgis renders correctly, and it no longer exists in this fork.
A config still naming it is rejected at startup rather than ignored:
config: provider test_postgis uses type (postgis), which has been removed; use type (mvt_postgis) instead
Changing the type is usually not enough on its own — see Provider Layers, since an MVT
layer's sql must wrap the geometry in ST_AsMVTGeom.
In addition to the required name and type parameters, a PostGIS data provider supports the following parameters:
| Param | Required | Default | Description |
|---|---|---|---|
| uri | Yes | The database connection string. | |
| srid | No | 3857 | The default SRID for this data provider |
Example
# {protocol}://{user}:{password}@{host}:{port}/{database}?{options}=
postgres://shigola:supersecret@localhost:5432/shigola?sslmode=prefer&pool_max_conns=10
Options
sslmode: [Optional] PostGIS SSL mode. Default: "prefer"pool_max_conns: [Optional] The max connections to maintain in the connection pool. Defaults to 100. 0 means no max.pool_min_conns: [Optional] The min connections to maintain in the connection pool. Defaults to 0. 0 mean there are no open connections in the pool if not needed.pool_max_conn_idle_time: [Optional] The maximum time an idle connection is kept alive. Defaults to "30m".pool_max_conn_lifetime[Optional] The maximum time a connection lives before it is terminated and recreated. Defaults to "1h".pool_health_check_period[Optional] Time in between health checks. Defaults to "1m".
Example PostGIS Provider config
[[providers]]
name = "test_postgis" # provider name is referenced from map layers (required)
type = "mvt_postgis" # the type of data provider must be "mvt_postgis" for this data provider (required)
uri = "postgres://shigola:supersecret@localhost:5432/shigola?sslmode=prefer" # PostGIS connection string (required)
srid = 3857 # The default srid for this provider. If not provided it will be WebMercator (3857)
Provider Layers
Provider Layers are referenced by Map Layers using the dot syntax provder_name.provider_layer_name (i.e. my_postgis.rivers). Provider Layers are required to have a name and will typically have additional parameters which are specific to that Provider. A Provider Layer has the following top level configuration parameters:
| Param | Required | Description |
|---|---|---|
| name | Yes | The name that will be referenced from a map layer. |
PostGIS
PostGIS Provider Layers define how Shigola will fetch data for a layer from a PostGIS
Provider. A layer is defined by sql, and the geometry it selects MUST be wrapped in
ST_AsMVTGeom(): Shigola wraps the layer's sql in
ST_AsMVT() and serves what the database returns, so the transform into tile coordinates has to
happen in the query.
| Param | Required | Default | Description |
|---|---|---|---|
| sql | Yes | Custom SQL. Requires a !BBOX! token, and ST_AsMVTGeom around the geometry — see Layer SRID and tiling scheme CRS | |
| geometry_fieldname | No | geom | The name of the geometry field in the table |
| id_fieldname | No | gid | The name of the feature ID field in the table. Only positive integer IDs are supported. |
| srid | No | 3857 | The SRID for the table. Can be 3857 or 4326. |
| geometry_type | In practice, yes | The layer geometry type. Valid values are: Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon, GeometryCollection. See below. |
Declare geometry_type. It is optional in the sense that Shigola will try to infer it, and the
way it infers it is to run the layer's SQL at startup and look at what comes back. A query ending in
ST_AsMVTGeom returns tile-space geometry that cannot be typed, so inference fails and the provider
refuses to start:
error fetching geometry type for layer (land): layer (land) returned unsupported geometry type (<nil>)
A tablename may be given instead of sql, along with fields to choose the columns it selects.
Both are accepted rather than rejected, and neither is usable here: Shigola generates a whole-table
select with no ST_AsMVTGeom and no bounding-box filter, which ST_AsMVT cannot make a correct tile
out of. They are leftovers of the removed postgis type, which is what that path was shaped for.
Which way a tablename layer fails depends on something unrelated to it. Without geometry_type
the provider refuses to start, because inferring the type means reading that generated query back.
With geometry_type — which you are told above to always declare — it starts, and serves
whole-table tiles. Write the sql.
Supported SQL Tokens
The sql configuration supports the following tokens
| Token | Required | Description |
|---|---|---|
| !BBOX! | Yes | The tile's bounding box in the layer's SRID — the one to select rows with, because it matches the SRID the spatial index is built in. !bbox! and !BOX! are supported as well for compatibility with queries from Mapnik and MapServer styles. |
| !TILE_BBOX! | Yes, for ST_AsMVTGeom | The same bounding box in the tiling scheme's CRS — the one to clip against. See Layer SRID and tiling scheme CRS. |
| !TILE_SRID! | No | The EPSG code of the tiling scheme's CRS. |
| !ZOOM! | No | Will be replaced with the "Z" (zoom) value of the requested tile. |
| !X! | No | Will be replaced with the "X" value of the requested tile. |
| !Y! | No | Will be replaced with the "Y" value of the requested tile. |
| !Z! | No | Will be replaced with the "Z" value of the requested tile. |
| !WEB_MERCATOR_ZOOM! | No | The WebMercatorQuad zoom with the same scale denominator as this tile's. Equal to !ZOOM! in WebMercatorQuad; one higher in WorldCRS84Quad and WGS1984Quad. Use it where a query's generalisation thresholds were tuned against the mercator zoom ladder. |
| !SCALE_DENOMINATOR! | No | Scale denominator, assuming 90.7 DPI (i.e. 0.28mm pixel size) |
| !PIXEL_WIDTH! | No | The pixel width in meters. |
| !PIXEL_HEIGHT! | No | The pixel height in meters. |
| !ID_FIELD! | No | The id field name. |
| !GEOM_FIELD! | No | The geom field name. |
| !GEOM_TYPE! | No | The geom type if defined otherwise. |
Example minimum Provider Layer config
[[providers.layers]]
name = "landuse"
# this table uses 'geom' for the geometry_fieldname and 'gid' for the id_fieldname (the defaults),
# so neither needs to be configured. Wrapping the geom in ST_AsMVTGeom is required.
geometry_type = "multipolygon"
sql = "SELECT ST_AsMVTGeom(ST_Transform(geom,!TILE_SRID!),!TILE_BBOX!) AS geom, gid FROM gis.landuse WHERE geom && !BBOX!"
Layer SRID and tiling scheme CRS
ST_AsMVTGeom maps a geometry onto the tile's 0–4096 grid affinely, across whatever envelope it is
handed. That makes the envelope's CRS the CRS the tile is spaced by — so it has to be the tiling
scheme's, and the geometry has to be in the same one.
Those coincide for a 3857 layer served in WebMercatorQuad, which is why a single !BBOX! did both
jobs while that was the only combination Shigola served. They do not coincide for a 3857 layer served
in WorldCRS84Quad: hand ST_AsMVTGeom the mercator envelope there and the tile comes back spaced by
mercator y inside a frame the client draws as linear in latitude. At zoom 1 that puts everything
between the equator and 85°N into the bottom 8.4% of the tile.
So the two tokens do different jobs, and a layer that may be served in more than one scheme uses both:
!BBOX!selects. It arrives in the layer's own SRID, sogeom && !BBOX!can use the spatial index.!TILE_BBOX!clips. It arrives in the scheme's CRS, and the geometry given alongside it has to be transformed to!TILE_SRID!to match.
ST_Transform is a no-op when the layer is already in the scheme's CRS, so this form is correct in
every scheme and there is no reason to write anything else — including for a 4326 layer:
[[providers.layers]]
name = "landuse"
# !BBOX! is converted into the layer's SRID, so it matches the 4326 data as stored;
# !TILE_BBOX! and !TILE_SRID! follow whichever scheme the request named.
geometry_type = "multipolygon"
sql = "SELECT ST_AsMVTGeom(ST_Transform(geom,!TILE_SRID!),!TILE_BBOX!) AS geom, gid FROM gis.landuse WHERE geom && !BBOX!"
Maps
Shigola is responsible for serving vector map tiles, which are made up of numerous Map Layers. The name of the Map is its OGC collection id, and so appears in the URL of every tile request (i.e. /collections/:map_name/tiles/:tile_matrix_set_id/:tile_matrix/:tile_row/:tile_col). Maps have the following configuration parameters:
| Param | Required | Description |
|---|---|---|
| name | Yes | The map's collection id, referenced in the URL (i.e. /collections/:map_name/tiles/...). |
| attribution | No | Attribution string to be included in the TileJSON. |
| bounds | No | The bounds in latitude and longitude values, in the order left, bottom, right, top. Default: [-180.0, -85.0511, 180.0, 85.0511] |
| center | No | The center of the map to be displayed in the preview. ([lon, lat, zoom]). |
| tile_buffer | No | The number of pixels to extend a tile's clipping area, defaults to 64 or the global value |
| tile_matrix_sets | No | The tiling schemes this map may be requested in. Omitted, every scheme the build serves. |
| serve_layer_collections | No | Whether this map's layers are addressable on their own. Default true. |
[[maps]]
name = "zoning" # the collection id: /collections/zoning/tiles/...
attribution = "Natural Earth v4"
center = [-76.275329586789, 39.153492567373, 5.0]
Tile matrix sets
tile_matrix_sets names the tiling schemes a map may be requested in. It is configured per map, not
per layer or per provider.
[[maps]]
name = "parks"
# Omit for every scheme this build serves.
tile_matrix_sets = ["WebMercatorQuad", "WorldCRS84Quad"]
This build serves the schemes that need no coordinate transformation backend:
| tileMatrixSetId | CRS | Matrix at zoom z |
|---|---|---|
WebMercatorQuad | EPSG:3857 | 2^z × 2^z |
WorldCRS84Quad | OGC:CRS84 | 2·2^z × 2^z |
WGS1984Quad | EPSG:4326 | 2·2^z × 2^z |
Naming a scheme this build cannot serve is a startup error that lists the available ones. The other
schemes in the OGC register ship with the build but are not servable; /tileMatrixSets lists only
what can be served.
Changing a map's schemes changes its cache keys — purge and re-seed that map.
Full detail: Tile Matrix Sets.
Serve layer collections
A map publishes one collection for itself and one for each of its layers, so a client can ask for
the whole map or for a single layer of it. serve_layer_collections = false drops the layer tier
for that map: it publishes its whole-map collection only.
[[maps]]
name = "parks"
# /collections/parks works; /collections/parks:trees is not found.
serve_layer_collections = false
The layer ids stop resolving everywhere — the collections listing omits them, and asking for one by id, for its tilesets or for one of its tiles is a 404. Nothing else changes: the whole-map collection, its tilesets and its tiles are exactly what they were, and its tiles still carry every layer.
It is configured per map, so a map that declines the tier and a map that says nothing about it work side by side in one config.
Cache entries a layer collection already served become unreachable. A tile's cache key carries
the layer it was served for, and nothing reads those keys once the layer ids stop resolving. The
cache seed and cache purge commands only ever address a map's own key — they pass an empty layer
— so neither can clear them, and removing them means deleting them from the cache backend. The key
is {tileMatrixSetId}/{map}/{layer}/{z}/{x}/{y}, so a file or S3 cache holds one layer directory
per scheme the map is served in, not one per map.
See OGC API - Tiles for how the two collection tiers are addressed.
Map Layers
Map Layers define which Provider Layers to render at what zoom levels. Map Layers have the following configuration parameters:
| Param | Required | Description |
|---|---|---|
| provider_layer | Yes | The name of the provider and provider layer using dot syntax. (i.e. my_postgis.rivers). |
| name | No | Overrides the provider_layer name. Can also be used to group multiple provider_layers under the same namespace. |
| min_zoom | No | The minimum zoom to render this layer at. |
| max_zoom | No | The maximum zoom to render this layer at. |
Example Map Layer
[[maps.layers]]
provider_layer = "test_postgis.landuse" # must match a data provider layer
min_zoom = 12 # minimum zoom level to include this layer
max_zoom = 16 # maximum zoom level to include this layer
Cache
This section configures caches for generated tiles. There is exactly one [cache] table for the
whole process — per-map cache selection is not a feature. All cache configs have the following
parameters:
| Param | Required | Description |
|---|---|---|
| type | Yes | The type of cache to use (file, redis, s3, azblob, gcs, or multi) |
| max_zoom | No | The max zoom which should be cached. |
| timeout_ms | No | A read deadline for this cache, in integer milliseconds. See below. |
Cache writes do not block the response — every cache, chained or not, hands its write to a bounded pool after the response is flushed, including single-backend deployments. See Layered cache.
timeout_ms
An optional per-cache read deadline, in integer milliseconds. It carries its unit where the
adjacent ttl takes bare seconds. It applies to any cache at any nesting depth, including a plain
non-chained [cache] table, and affects Get only.
It is enforced by redis, s3, azblob and gcs, and only advisory for file, whose
os.Open/Stat calls block before any cancellation check — on an NFS/EFS mount use the mount's own
soft and timeo= options instead.
A read that times out is a miss, not an error.
Layered cache
type = "multi" puts an ordered chain of cache backends behind the single [cache] table. Reads walk
the tiers in declaration order and promote a hit into the earlier ones; writes fan out; purges run in
reverse.
| Param | Required | Default | Description |
|---|---|---|---|
| layers | Yes | The ordered list of tiers, as [[cache.layers]] tables. Declaration order is read order. | |
| promote_on_hit | No | true | Promote a later-tier hit into the earlier tiers. false gives a read-only fan-out. |
Each [[cache.layers]] entry takes its backend's own parameters, plus timeout_ms and an optional
name that pins the tier's metric label and --cache-tiers value.
[cache]
type = "multi"
promote_on_hit = true
[[cache.layers]]
type = "redis"
ttl = 3600
timeout_ms = 35
name = "hot"
[[cache.layers]]
type = "s3"
bucket = "tiles"
Note that [[cache.layers]] headers are siblings however deeply they are indented — TOML
indentation is cosmetic. Real nesting needs [[cache.layers.layers]].
Full detail, including metrics and operations: Layered cache.
File
Cache tiles in a directory on the local filesystem.
| Param | Required | Default | Description |
|---|---|---|---|
| basepath | Yes | A directory on the file system to write the cached tiles to. | |
| ttl | No | 0 | Seconds after which a cached tile is treated as expired. 0 means no expiry. |
Redis
Cache tiles in Redis.
When no parameters are supplied, this cache will try and connect to a local Redis instance with default configuration.
| Param | Required | Default | Description |
|---|---|---|---|
| uri | No | redis:// or rediss:// followed by <user>:<password>@<host>:<port>/<database>. The preferred form. | |
| network | No | tcp | Deprecated. The type of connection (tcp or unix) |
| address | No | 127.0.0.1:6379 | Deprecated. The address of Redis in the form ip:port. |
| password | No | Password to use when connecting. Takes precedence over a password in uri. | |
| db | No | Deprecated. Database to use (int). | |
| ttl | No | 0 | Key TTL in seconds. 0 means the key has no expiration. |
| key_prefix | No | A string prepended to every cache key, so one Redis instance can be shared. | |
| ssl | No | false | Deprecated. Encrypt connection to the Redis server. |
Connecting via uri is the default from v0.22.0 onwards; network, address, db and ssl are
deprecated in its favour. password is not deprecated — when both are given the password key
wins over the credential in the uri, including when it is present and empty, which asks for no
password rather than falling back to the uri's.
key_prefix is concatenated verbatim, so supply your own separator: key_prefix = "shigola:"
gives keys like shigola:WebMercatorQuad/mymap/mylayer/10/511/340, whereas key_prefix = "shigola"
gives shigolaWebMercatorQuad/....
Passwords with special characters
A uri is parsed as a URL, so a password inside one must be percent-encoded. Unencoded, the outcome
depends on the character:
| In the uri | Result |
|---|---|
^ [ ] { } | < > \ " space | startup fails with net/url: invalid userinfo |
% | startup fails with invalid URL escape |
/ ? | startup fails — the authority ends there |
# | truncates the uri at that point. Usually a startup error, but when what remains still parses it silently yields the wrong password |
$ @ & ! * ( ) + = : ~ , ; ' | works unencoded |
Percent-encode, or use the separate password key, which is not subject to URL rules:
[cache]
type = "redis"
uri = "redis://user@localhost:6379/0"
password = "${SECRET_REDIS_PASSWORD}"
S3
Cache tiles in Amazon S3, or any S3-compatible store via endpoint.
| Param | Required | Default | Description |
|---|---|---|---|
| bucket | Yes | The name of the S3 bucket to use. | |
| basepath | No | A path prefix added to all cache operations inside the S3 bucket | |
| region | No | us-east-1 | The region the bucket is in. |
| endpoint | No | A non-AWS S3-compatible endpoint. | |
| aws_access_key_id | No | The AWS access key id to use. | |
| aws_secret_access_key | No | The AWS secret access key to use. | |
| access_control_list | No | The canned ACL to apply to written objects. | |
| cache_control | No | The Cache-Control header to store with written objects. | |
| content_type | No | application/vnd.mapbox-vector-tile | The Content-Type to store with written objects. |
If the aws_access_key_id and aws_secret_access_key are not set, then the
credential provider chain
will be used. The provider chain supports multiple methods for passing credentials, one of which is
through environment variables. For example:
$ export AWS_REGION=us-west-2
$ export AWS_ACCESS_KEY_ID=YOUR_AKID
$ export AWS_SECRET_ACCESS_KEY=YOUR_SECRET_KEY
Azure Blob Storage
Cache tiles in an Azure Blob Storage container.
| Param | Required | Default | Description |
|---|---|---|---|
| container_url | Yes | The URL of the blob container to write to. | |
| az_account_name | No | The storage account name. | |
| az_shared_key | No | The storage account shared key. | |
| basepath | No | A path prefix added to all cache operations. | |
| read_only | No | false | Serve from the container without writing to it. |
Google Cloud Storage
Cache tiles in a GCS bucket.
| Param | Required | Default | Description |
|---|---|---|---|
| bucket | Yes | The name of the GCS bucket to use. | |
| basepath | No | A path prefix added to all cache operations. |
Tracing
[tracing] configures OpenTelemetry trace export over OTLP. It is off unless
the section says otherwise, and it is independent of [observer]: metrics and
traces are switched on separately.
[tracing]
enabled = true
exporter = "otlp_grpc"
endpoint = "tempo.observability:4317"
insecure = true
sample_ratio = 0.01
endpoint takes either host:port or a full URL; anything that cannot work is
rejected at startup.
Do not run a production tile server at sample_ratio = 1.0 — each tile
request produces several spans, so full sampling multiplies request rate by the
span tree's width. See Tracing for every parameter, the sampling
argument in full, and what the resulting span tree looks like.
Env Var
Environmental variables can be used in any configuration option. However, they must be written within quotes as a string:
tile_buffer = "${SHIGOLA_TILE_BUFFER}" # note that tile buffer expects an integer, shigola will handle the conversion
[cache]
type = "redis"
password = "${SECRET_REDIS_PASSWORD}"
Full Config Example
The following config demonstrates the various concepts discussed above:
tile_buffer = 64
[webserver]
port = ":9090"
[cache]
type="file" # cache type
basepath="/tmp/shigola" # cache specific config
# register data providers
[[providers]]
name = "test_postgis" # provider name is referenced from map layers
type = "mvt_postgis" # PostGIS does the MVT encoding, via ST_AsMVT
uri = "postgres://shigola:supersecret@localhost:5432/shigola?sslmode=prefer" # PostGIS connection string (required)
srid = 3857 # The default srid for this provider. If not provided it will be WebMercator (3857)
# `sql` is what a layer is defined by, and the geometry must be wrapped in
# ST_AsMVTGeom — which shigola cannot generate from a `tablename`. A layer
# using `tablename` is parsed rather than rejected, and then fails at
# startup while shigola tries to infer its geometry type.
#
# geometry_type is declared for the same reason: that inference reads the
# layer's SQL back, and cannot type what ST_AsMVTGeom returns.
[[providers.layers]]
name = "landuse" # will be encoded as the layer name in the tile
geometry_fieldname = "geom" # geom field. default is geom
id_fieldname = "gid" # geom id field. default is gid
geometry_type = "multipolygon"
sql = "SELECT ST_AsMVTGeom(ST_Transform(geom,!TILE_SRID!), !TILE_BBOX!) AS geom, gid FROM gis.zoning_base_3857 WHERE geom && !BBOX!"
[[providers.layers]]
name = "roads" # will be encoded as the layer name in the tile
geometry_fieldname = "geom" # geom field. default is geom
id_fieldname = "gid" # geom id field. default is gid
geometry_type = "multilinestring"
# Extra columns in the SELECT become feature tags.
sql = "SELECT ST_AsMVTGeom(ST_Transform(geom,!TILE_SRID!), !TILE_BBOX!) AS geom, gid, class, name FROM gis.zoning_base_3857 WHERE geom && !BBOX!"
[[providers.layers]]
name = "rivers" # will be encoded as the layer name in the tile
geometry_type = "multilinestring"
sql = "SELECT ST_AsMVTGeom(ST_Transform(geom,!TILE_SRID!), !TILE_BBOX!) AS geom, gid FROM gis.rivers WHERE geom && !BBOX!"
# maps are made up of layers
[[maps]]
name = "zoning" # the collection id: /collections/zoning/tiles/...
tile_buffer = 0 # number of pixels to extend a tile's clipping area
tile_matrix_sets = ["WebMercatorQuad"] # tiling schemes this map may be requested in.
# omit for all servable schemes.
# A map using an MVT provider may use ONLY that provider — every layer here
# has to come from test_postgis. Mixing in a second provider, MVT or not, is
# a startup error.
[[maps.layers]]
provider_layer = "test_postgis.landuse" # must match a data provider layer
min_zoom = 12 # minimum zoom level to include this layer
max_zoom = 16 # maximum zoom level to include this layer
[[maps.layers]]
provider_layer = "test_postgis.rivers" # must match a data provider layer
min_zoom = 10 # minimum zoom level to include this layer
max_zoom = 18 # maximum zoom level to include this layer
Two things about an MVT provider are worth knowing, and neither reports an error:
- A map draws its layers from exactly one provider. This is enforced at startup: a map naming two fails to load rather than serving a partial tile. An MVT provider returns a tile that is already encoded, so there is nothing to merge a second provider's features into.
Layered Cache Example
A Redis hot tier in front of an S3 durable tier, serving two tiling schemes — both fork-only features:
tile_buffer = 64
[webserver]
port = ":8080"
# Exactly one [cache] table for the process. `multi` makes it a chain.
[cache]
type = "multi"
promote_on_hit = true # default: a hit in s3 is written back into redis
# Tier 0 — read first, promoted into. Fast, evicting, bounded.
[[cache.layers]]
type = "redis"
name = "hot" # pins the metric label and --cache-tiers value
uri = "redis://localhost:6379/0"
password = "${SECRET_REDIS_PASSWORD}"
key_prefix = "shigola:" # supply your own separator
ttl = 3600 # seconds; bounds redis memory, not staleness
timeout_ms = 35 # abandon this tier's read after 35ms; a timeout is a miss
# Tier 1 — the durable one, and what `cache seed` writes by default.
[[cache.layers]]
type = "s3"
bucket = "${S3_BUCKET}"
region = "us-east-2"
basepath = "tiles"
# timeout_ms omitted: the durable tier is allowed to be slow.
[[providers]]
name = "osm"
type = "mvt_postgis" # PostGIS does the MVT encoding, via ST_AsMVT
uri = "postgres://shigola:supersecret@localhost:5432/shigola?sslmode=prefer"
[[providers.layers]]
name = "landuse"
geometry_type = "multipolygon"
sql = "SELECT ST_AsMVTGeom(ST_Transform(geom,!TILE_SRID!), !TILE_BBOX!) AS geom, gid FROM gis.landuse WHERE geom && !BBOX!"
[[maps]]
name = "osm"
# The schemes this map may be requested in. A seed run scoped to this map with
# --map, and given no --tile-matrix-set, takes the first and warns which it took.
tile_matrix_sets = ["WebMercatorQuad", "WorldCRS84Quad"]
[[maps.layers]]
provider_layer = "osm.landuse"
min_zoom = 10
max_zoom = 16