tilegroxy Docs

Configuration

  • YAML

  • JSON

server:
  bindhost: 0.0.0.0 (1)
  production: true (2)
  timeout: 30
  cors: (3)
    enabled: true
    origins:
      - https://maps.example.com
  cachecontrol: (4)
    enabled: true
    visibility: private
    maxage: 3600
client:
  useragent: example-maps/1.0 (ops@example.com) (5)
  timeout: 5
logging:
  main:
    level: warn (6)
    format: json
  access:
    console: false
    path: /var/log/tilegroxy/access.log
  audit: (7)
    enabled: true
    console: false
    path: /var/log/tilegroxy/audit.log
health: (8)
  enabled: true
  port: 3000
  checks:
    - name: tile
      layer: basemap
      z: 0
      x: 0
      y: 0
      validation: success
      delay: 60
    - name: cache
      delay: 600
authentication: (9)
  name: jwt
  key: env.JWT_SIGNING_KEY
  algorithms:
    - HS256
  expectedissuer: https://auth.example.com
error:
  mode: image (10)
cache: (11)
  name: multi
  tiers:
    - name: memory
      maxsize: 1000
      ttl: 300
    - name: disk
      path: /var/cache/tilegroxy
layers:
  - id: basemap
    provider:
      name: proxy
      url: https://tiles.example.com/basemap/{z}/{x}/{y}.png
1 The default of 127.0.0.1 only accepts connections from the same machine. Binding to all interfaces is needed inside a container or behind a load balancer.
2 This is already the default. Setting it explicitly guards against an environment variable or a copied development config turning it off, which would expose the documentation and layer preview pages.
3 Browsers only let scripts on these origins read tiles. Map libraries that fetch tiles with scripts or WebGL need this; plain <img> tags don’t. See CORS.
4 Lets the requester’s browser reuse each tile for an hour. The visibility is private because the tiles require a token: a public tile could be stored by a CDN and served to anyone. maxage is required here since the memory cache’s ttl isn’t something tilegroxy can derive a freshness from. See Cache Control.
5 Identify yourself to upstream servers so their operators can contact you. The client timeout is kept well under the server’s 30 seconds so a slow upstream fails with an error tile rather than a dropped connection.
6 warn keeps routine messages out of your log aggregator and json makes them easy to parse. See Log.
7 Rejected requests and configuration reloads are written to their own file. Consider forwarding it to your SIEM.
8 Health checks are served on their own port so they can stay off the internet. The tile check generates a real tile from the basemap layer every minute and the cache check confirms each cache is reachable every 10 minutes. See Health.
9 The signing key is read from the JWT_SIGNING_KEY environment variable so it never appears in the file. Tokens must also come from the expected issuer. See JWT.
10 Errors are returned as an image tile that indicates the general problem without exposing the error message. See Error.
11 A small, fast memory cache sits in front of a larger disk cache. A tile evicted from memory is still on disk, and a restart only loses the memory tier. See Multi.
{
  "server": {
    "bindhost": "0.0.0.0", (1)
    "production": true, (2)
    "timeout": 30,
    "cors": { (3)
      "enabled": true,
      "origins": [
        "https://maps.example.com"
      ]
    },
    "cachecontrol": { (4)
      "enabled": true,
      "visibility": "private",
      "maxage": 3600
    }
  },
  "client": {
    "useragent": "example-maps/1.0 (ops@example.com)", (5)
    "timeout": 5
  },
  "logging": {
    "main": {
      "level": "warn", (6)
      "format": "json"
    },
    "access": {
      "console": false,
      "path": "/var/log/tilegroxy/access.log"
    },
    "audit": { (7)
      "enabled": true,
      "console": false,
      "path": "/var/log/tilegroxy/audit.log"
    }
  },
  "health": { (8)
    "enabled": true,
    "port": 3000,
    "checks": [
      {
        "name": "tile",
        "layer": "basemap",
        "z": 0,
        "x": 0,
        "y": 0,
        "validation": "success",
        "delay": 60
      },
      {
        "name": "cache",
        "delay": 600
      }
    ]
  },
  "authentication": { (9)
    "name": "jwt",
    "key": "env.JWT_SIGNING_KEY",
    "algorithms": [
      "HS256"
    ],
    "expectedissuer": "https://auth.example.com"
  },
  "error": {
    "mode": "image" (10)
  },
  "cache": {
    "name": "multi", (11)
    "tiers": [
      {
        "name": "memory",
        "maxsize": 1000,
        "ttl": 300
      },
      {
        "name": "disk",
        "path": "/var/cache/tilegroxy"
      }
    ]
  },
  "layers": [
    {
      "id": "basemap",
      "provider": {
        "name": "proxy",
        "url": "https://tiles.example.com/basemap/{z}/{x}/{y}.png"
      }
    }
  ]
}
1 The default of 127.0.0.1 only accepts connections from the same machine. Binding to all interfaces is needed inside a container or behind a load balancer.
2 This is already the default. Setting it explicitly guards against an environment variable or a copied development config turning it off, which would expose the documentation and layer preview pages.
3 Browsers only let scripts on these origins read tiles. Map libraries that fetch tiles with scripts or WebGL need this; plain <img> tags don’t. See CORS.
4 Lets the requester’s browser reuse each tile for an hour. The visibility is private because the tiles require a token: a public tile could be stored by a CDN and served to anyone. maxage is required here since the memory cache’s ttl isn’t something tilegroxy can derive a freshness from. See Cache Control.
5 Identify yourself to upstream servers so their operators can contact you. The client timeout is kept well under the server’s 30 seconds so a slow upstream fails with an error tile rather than a dropped connection.
6 warn keeps routine messages out of your log aggregator and json makes them easy to parse. See Log.
7 Rejected requests and configuration reloads are written to their own file. Consider forwarding it to your SIEM.
8 Health checks are served on their own port so they can stay off the internet. The tile check generates a real tile from the basemap layer every minute and the cache check confirms each cache is reachable every 10 minutes. See Health.
9 The signing key is read from the JWT_SIGNING_KEY environment variable so it never appears in the file. Tokens must also come from the expected issuer. See JWT.
10 Errors are returned as an image tile that indicates the general problem without exposing the error message. See Error.
11 A small, fast memory cache sits in front of a larger disk cache. A tile evicted from memory is still on disk, and a restart only loses the memory tier. See Multi.

Try it

The disk cache and log directories must exist and be writable by the user running tilegroxy. Then validate the configuration and start the server:

export JWT_SIGNING_KEY=change-me
tilegroxy config check -c production.yml
tilegroxy serve -c production.yml

Requests now need a token signed with that key, with an iss claim of https://auth.example.com and an exp claim no more than a day away:

curl -H "Authorization: Bearer $TOKEN" -o tile.png http://127.0.0.1:8080/tiles/basemap/0/0/0

Replace tiles.example.com with your real upstream before deploying.