tegola icon indicating copy to clipboard operation
tegola copied to clipboard

Best practices for deploying Tegola

Open pnorman opened this issue 7 years ago • 7 comments

Is there any documentation about deploying Tegola?

If approaching it myself I'd probably do, with some notes

  • Daemonize the process and handle it with init.d/upstart/etc Some way to run the process is needed, and it needs to log to a file, etc. There are standard ways to do this. It looks like the best ways are done outside of Go
    • https://github.com/fiorix/go-daemon
    • https://stackoverflow.com/questions/10067295/how-to-start-a-go-program-as-a-daemon-in-ubuntu
    • https://www.reddit.com/r/golang/comments/35v5bm/best_way_to_run_go_server_as_a_daemon/
  • Use Apache and <Proxy> to redirect from port 80/443 to Tegola Or really any web server that allows URL rewriting. This is needed for a few reasons
    • SSL is needed for many browsers and vector tiles
    • URLs can be rewritten to a better scheme
    • Blocking can be done
    • The attack surface of Tegola can be narrowed with URL rewriting
    • Creating and handling the connection with clients can be expensive, and apache is better understood for that

What I'm not sure about is

  • Reporting. Cache status reporting on a disk cache is easy with find and du, but there are other metrics which are conventional for a tile server, including

    • requests per second,
    • % of tiles from cache,
    • time to generate new tiles, and
    • error rates. Most of these should be by zoom and map.
  • Tegola configuration management. Some properties in the config file will need overwriting from defaults for a vector style config. In particular,

    • cache paths,
    • database connection information,
    • hostname,
    • CORS, and
    • S3 information are all likely to need to vary depending on the deployment.

What are the current practices of others deploying Tegola, or considering doing so?

pnorman avatar Mar 08 '18 23:03 pnorman

I pinged people who have been deploying Tegola into production like environments, to have them chime in on here. It would be good to document all their experience.

gdey avatar Mar 08 '18 23:03 gdey

@pnorman unfortunately no. I would love to add a section to the docs around deployment best practices. We have been working on some new docs which would be able to accommodate a section around deployment best practices. The docs were built using hugo but I need to update the readme. You can see the new repo (name to change soon) at: https://github.com/go-spatial/tegola-ui-docs. Github page: https://go-spatial.github.io/tegola-ui-docs/

I like your idea about some server metrics. We should think about adding those in at some point.

Regarding the config management, that's another feature that needs to be documented. As of v0.6.0 our config supports environment variable injection via the ${ENV_VAR} syntax.

ARolek avatar Mar 09 '18 00:03 ARolek

Handling multiple style versions is another issue, but I think that needs its own issue, so once I figure more of that out I'll write up an issue specific to that.

pnorman avatar Mar 09 '18 09:03 pnorman

Just a note that the only folks really using this in production are using Pivotal Cloud Foundry which handles alot of these metics you mention. Our devops repos are private, but the Pivotal guys have stood one up on their own. An example of the the operative files are here https://github.com/vchrisb/cf-tegola-osm/blob/master/manifest.yml and elsewhere in this repo.

jj0hns0n avatar Mar 09 '18 13:03 jj0hns0n

Here are some notes that I used for nixos (systemd and nginx), including tegola behind https:

systemd.services.tegola = {
   description = "Tegola - Mapbox Vector Tiles Server";
   serviceConfig = {
     Type = "simple";
     ExecStart = "/path/to/tegola server --config=/path/to/tegola.toml";
     ExecStop = "/run/current-system/sw/bin/pkill tegola";
     Restart = "on-failure";
     User= "puertico";
   };
   wantedBy = [ "default.target" ];
   after = [ "postgresql.service"];
   requires = [ "postgresql.service" ]; 
};

and nginx

      listen 443 ssl http2;
      server_name puerti.co;
      ssl_certificate /var/lib/acme/puerti.co/fullchain.pem;
      ssl_certificate_key /var/lib/acme/puerti.co/key.pem;
      add_header Strict-Transport-Security "max-age=15768000; includeSubDomains" always;
    
      ssl_protocols TLSv1.2 TLSv1.3;
      ssl_prefer_server_ciphers on;
      ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+aRSA+SHA384 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS";
      ssl_session_cache shared:ssl_session_cache:10m;

  location /tegola {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto https;
        proxy_redirect     off;
        proxy_pass http://localhost:9090/;
      }

  location /tegola {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto https;
        proxy_redirect     off;
        proxy_pass http://localhost:9090/;
      }

ingenieroariel avatar Feb 18 '19 15:02 ingenieroariel

So, I've been giving this some thought on an architecture level. The deployment I'm considering is worldwide with pre-rendering, and needs to handle schema-incompatible map upgrades without shutting down or trying to have simultaneous updates of the client-side style and actions on the backend. This means serving old tiles still, which with #579 means either keeping around multiple configs on the backend or serving directly out of the object store.

Once I got to serving out of the object store, I realized that I might as well do this for all the maps, which takes tegola out of the path serving user requests.

Normal state

image

Diff updates are creating an expiry list which get passed to tegola cache seed tile-list --overwrite, pushing new tiles to the object store. You need some way to trigger tegola cache seed --min-zoom 0 --max-zoom 15 for new styles and some way to trigger tegola cache seed --min-zoom 0 --max-zoom 11 --overwrite for low zoom rerenders.

Requests for the current version or the previous version get proxied to the object store.

New map

image

When a new style comes out with schema-breaking changes, you have a new map and tegola no longer knows about the current map. Clients continue keep requesting the current map

When the cache seed --min-zoom --max-zoom job is done, you switch over the client-side style on the front-end and all the clients are now requesting the new map as the new client-side style makes it through the caching to their browsers.


This eliminates the need to run tegola as a daemon. You can run like the current setup, just substituting tegola cache seed tile-list for render_list. If you have a renderd tile server in production right now, daemonizing this is a solved problem.

You need to run apache, nginix, or something which terminates the public HTTP SSL connections and fetches from ceph, but deploying HTTPS servers and proxies is a solved problem.

pnorman avatar Mar 03 '19 02:03 pnorman

This is what I used

  • Create service file:
sudo nano /lib/systemd/system/tegola.service
  • Insert following content and replace whatever necessary:
[Unit]
Description=Tegola app service
After=postgresql.service
Requires=postgresql.service

[Service]
Type=simple
User=<username>
ExecStart=/path/to/tegola serve --config=/path/to/tegola.toml
ExecStop=/usr/bin/pkill tegola
Restart=on-failure

[Install]
WantedBy=default.target
  • Enable service:
sudo systemctl enable tegola.service
  • Start service:
sudo systemctl start tegola.service
  • Check status of the service:
systemctl status tegola.service

Tested on Ubuntu 18.04 LTS and working fine.

aaj013 avatar Sep 04 '19 10:09 aaj013