Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Configuration File

If you don’t want to expose all of your tables and functions, you can list your sources in a configuration file. To start Martin with a configuration file you need to pass a path to a file with a --config argument. Config files may contain environment variables, which will be expanded before parsing. For example, to use MY_DATABASE_URL in your config file: connection_string: ${MY_DATABASE_URL}, or with a default connection_string: ${MY_DATABASE_URL:-postgresql://postgres@localhost/db}

martin --config config.yaml

You may wish to auto-generate a config file with --save-config argument. This will generate a config yaml file with all of your configuration, which you can edit to remove any sources you don’t want to expose.

martin  ... ... ...  --save-config config.yaml

Config Example

# Connection keep alive timeout [default: 75]
keep_alive: 75

# The socket address to bind [default: 0.0.0.0:3000]
listen_addresses: '0.0.0.0:3000'

# Set TileJSON URL path prefix.
# This overrides the default of respecting the X-Rewrite-URL header.
# Only modifies the JSON (TileJSON) returned; Martin's API-URLs remain unchanged.
# If you need to rewrite URLs, please use a reverse proxy.
# Must begin with a `/`.
# Examples: `/`, `/tiles`
base_path: /tiles

# Number of web server workers
worker_processes: 8

# Amount of memory (in MB) to use for caching tiles [default: 512, 0 to disable]
cache_size_mb: 1024

# Which compression should be used if the
# - client accepts multiple compression formats, and
# - tile source is not pre-compressed.
#
# `gzip` is faster, but `brotli` is smaller, and may be faster with caching.
# Default could be different depending on Martin version.
preferred_encoding: gzip

# Enable or disable Martin web UI. [default: disable]
#
# At the moment, only allows `enable-for-all`, which enables the web UI for all connections.
# This may be undesirable in a production environment
web_ui: disable

# Advanced monitoring options
observability:
  # Configure metrics reported under `/_/metrics`
  metrics:
    # Add these labels to every metric
    # Example: `{ env: prod, server: martin }`
    add_labels: {}

# CORS Configuration
#
# Defaults to `cors: true`, which allows all origins.
# Sending/Acting on CORS headers can be completely disabled via `cors: false`
cors:
  # Sets the `Access-Control-Allow-Origin` header [default: *]
  # '*' will use the requests `ORIGIN` header
  origin:
    - https://example.org
  # Sets `Access-Control-Max-Age` Header. [default: null]
  # null means not setting the header for preflight requests
  max_age: 3600

# Database configuration. This can also be a list of PG configs.
postgres:
  # Database connection string.
  #
  # You can use environment variables too, for example:
  # connection_string: $DATABASE_URL
  # connection_string: ${DATABASE_URL:-postgresql://postgres@localhost/db}
  connection_string: 'postgresql://postgres@localhost:5432/db'

  # Same as PGSSLCERT for psql
  ssl_cert: './postgresql.crt'
  # Same as PGSSLKEY for psql
  ssl_key: './postgresql.key'
  # Same as PGSSLROOTCERT for psql
  ssl_root_cert: './root.crt'

  # If a spatial table has SRID 0, then this SRID will be used as a fallback
  default_srid: 4326

  # Maximum Postgres connections pool size [default: 20]
  pool_size: 20

  # Limit the number of geo features per tile.
  #
  # If the source table has more features than set here, they will not be
  # included in the tile and the result will look "cut off"/incomplete.
  # This feature allows you to put a maximum latency bound on tiles with an
  # extreme amount of detail at the cost of not returning all data.
  # It is sensible to set this limit if you have user generated/untrusted
  # geodata, e.g. a lot of data points at [Null Island]
  # (https://en.wikipedia.org/wiki/Null_Island).
  max_feature_count: null # either a positive integer, or null=unlimited (default)

  # Specify how bounds should be computed for the spatial PG tables [default: quick]
  #
  # Options:
  # - `calc` compute table geometry bounds on startup.
  # - `quick` same as 'calc', but the calculation will be aborted after 5 seconds.
  # - `skip` does not compute table geometry bounds on startup.
  auto_bounds: quick

  # Enable automatic discovery of tables and functions.
  # You may set this to `false` to disable.
  auto_publish:
    # Optionally limit to just these schemas
    from_schemas:
      - public
      - my_schema
    # Here we enable both tables and functions auto discovery.
    # You can also enable just one of them by not mentioning the other, or
    # setting it to false. Setting one to true disables the other one as well.
    # E.g. `tables: false` enables just the functions auto-discovery.
    tables:
      # Optionally set how source ID should be generated based on the table's name,
      # schema, and geometry column
      source_id_format: 'table.{schema}.{table}.{column}'
      # Add more schemas to the ones listed above
      from_schemas: my_other_schema
      # A table column to use as the feature ID
      # If a table has no column with this name, `id_column` will not be set for
      # that table.
      # If a list of strings is given, the first found column will be treated as a
      # feature ID.
      id_columns: feature_id
      # Controls if geometries should be clipped or encoded as is [default: true]
      clip_geom: true
      # Buffer distance in tile coordinate space to optionally clip geometries,
      # optional, default to 64
      buffer: 64
      # Tile extent in tile coordinate space, optional, default to 4096
      extent: 4096
    functions:
      # Optionally limit to just these schemas
      from_schemas:
        - public
        - my_schema
      # Optionally set how source ID should be generated based on the function's
      # name and schema
      source_id_format: '{schema}.{function}'

  # Associative arrays of table sources
  tables:
    table_source_id:
      # ID of the MVT layer (optional, defaults to table name)
      layer_id: table_source

      # Table schema (required)
      schema: public

      # Table name (required)
      table: table_source

      # Geometry SRID (required)
      srid: 4326

      # Geometry column name (required)
      geometry_column: geom

      # Feature id column name
      id_column: ~

      # An integer specifying the minimum zoom level
      minzoom: 0

      # An integer specifying the maximum zoom level. MUST be >= minzoom
      maxzoom: 30

      # The maximum extent of available map tiles. Bounds MUST define an area
      # covered by all zoom levels. The bounds are represented in WGS:84 latitude
      # and longitude values, in the order left, bottom, right, top. Values may
      # be integers or floating point numbers.
      bounds: [ -180.0, -90.0, 180.0, 90.0 ]

      # Tile extent in tile coordinate space
      extent: 4096

      # Buffer distance in tile coordinate space to optionally clip geometries
      buffer: 64

      # Boolean to control if geometries should be clipped or encoded as is
      clip_geom: true

      # Geometry type
      geometry_type: GEOMETRY

      # List of columns, that should be encoded as tile properties (required)
      properties:
        gid: int4

  # Associative arrays of function sources
  functions:
    function_source_id:
      # Schema name (required)
      schema: public

      # Function name (required)
      function: function_zxy_query

      # An integer specifying the minimum zoom level
      minzoom: 0

      # An integer specifying the maximum zoom level. MUST be >= minzoom
      maxzoom: 30

      # The maximum extent of available map tiles. Bounds MUST define an area
      # covered by all zoom levels. The bounds are represented in WGS:84
      # latitude and longitude values, in the order left, bottom, right, top.
      # Values may be integers or floating point numbers.
      bounds: [ -180.0, -90.0, 180.0, 90.0 ]

# Publish PMTiles files from local disk or proxy to a web server
pmtiles:
  # Allows forcing path style URLs for S3 buckets [default: false]
  #
  # A path style URL is a URL that uses the bucket name as part of the path like
  # example.org/some_bucket instead of the hostname some_bucket.example.org
  force_path_style: false
  # Skip loading credentials for S3 buckets [default: false]
  #
  # Set this to true to request anonymously for publicly available buckets.
  skip_credentials: false
  paths:
    # scan this whole dir, matching all *.pmtiles files
    - /dir-path
    # specific pmtiles file will be published as a pmt source (filename without extension)
    - /path/to/pmt.pmtiles
    # A web server with a PMTiles file that supports range requests
    - https://example.org/path/tiles.pmtiles
  sources:
    # named source matching source name to a single file
    pm-src1: /path/to/pmt.pmtiles
    # A named source to a web server with a PMTiles file that supports range requests
    pm-web2: https://example.org/path/tiles.pmtiles

# Publish MBTiles files
mbtiles:
  paths:
    # scan this whole dir, matching all *.mbtiles files
    - /dir-path
    # specific mbtiles file will be published as mbtiles2 source
    - /path/to/mbtiles.mbtiles
  sources:
    # named source matching source name to a single file
    mb-src1: /path/to/mbtiles1.mbtiles

# Cloud Optimized GeoTIFF File Sources
cog:
  paths:
    # scan this whole dir, matching all *.tif and *.tiff files
    - /dir-path
    # specific TIFF file will be published as a cog source
    - /path/to/cog_file1.tif
    - /path/to/cog_file2.tiff
  sources:
    # named source matching source name to a single file
     cog-src1: /path/to/cog1.tif
     cog-src2: /path/to/cog2.tif

# Sprite configuration
sprites:
  paths:
    # all SVG files in this dir will be published as a "my_images" sprite source
    - /path/to/my_images
  sources:
    # SVG images in this directory will be published as a "my_sprites" sprite source
    my_sprites: /path/to/some_dir

# Font configuration
fonts:
  # A list of *.otf, *.ttf, and *.ttc font files and dirs to search recursively.
  - /path/to/font/file.ttf
  - /path/to/font_dir

# Publish MapLibre style files
# In the future, the style files will be used for the server-side rendering as well
styles:
   paths:
     # publish all *.json files in this directory
     # The name of the file will be used as the style name
     - /path/to/styles_dir
     # publish a single file - here `maplibre_style` will be the style name
     - /path/to/maplibre_style.json
   sources:
     # publish a JSON file found at this path as `some_style_name`
     #
     # Contrairy to paths, if directories are specified, Martin will print a
     # warning and ignore them.
     # To serve a style-directory, use the `paths` section above or name each
     # style individually. This prevents footguns with names being unclear.
     some_style_name: /path/to/this/style.json
     #  Publish specific file as `other_style_name`
     other_style_name: /path/to/other_style.json