Trino Gateway on Ubuntu 24.04 on Azure User Guide
Overview
Trino Gateway is an open source load-balancing proxy and router for the Trino distributed SQL query engine. It presents a single, stable endpoint to query clients and routes each request to a backend Trino cluster by routing group and cluster health, so you can add, drain and balance clusters behind one address without reconfiguring clients. The cloudimg image ships a self-contained appliance: Trino Gateway 20, a bundled single-node Trino 476 coordinator it routes to (with the in-memory tpch sample connector), and a PostgreSQL routing and query-history store — all wired together and ready to route queries on the first boot of every VM. The gateway dashboard and admin API are protected by the gateway's own per-VM form login, and the Trino query surface is protected by an nginx per-VM Basic-auth wall on TCP 80. Backed by 24/7 cloudimg support.
What is included:
- Trino Gateway 20 (
io.trino.gateway) at/opt/trino-gateway, running on a Temurin 25 JRE - A bundled single-node Trino 476 coordinator at
/opt/trino(Temurin 24 JRE) with thetpchsample connector, registered as the gateway's backend - PostgreSQL as the gateway's routing/state and query-history store (loopback only)
- The gateway dashboard, protected by the gateway's own per-VM admin password (form login)
- An nginx reverse proxy on
:80enforcing a per-VM Basic-auth wall over the Trino query path, plus an unauthenticated/healthendpoint - The Trino CLI at
/opt/trino/bin/trino postgresql,trino,trino-gateway,trino-gateway-registerandnginxas systemd units, enabled and active- 24/7 cloudimg support
Prerequisites
An active Azure subscription, an SSH key pair, and a VNet + subnet in the target region. Standard_B4ms (4 vCPU / 16 GiB RAM) is a good starting point; both the gateway and the bundled Trino are JVM services, so scale up for higher concurrency and larger workloads. NSG inbound: allow 22/tcp from your management network and 80/tcp for the dashboard and the query endpoint (front with TLS for public exposure — see Enabling HTTPS).
Step 1 — Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Trino Gateway by cloudimg, and select Create. On Basics pick your subscription, resource group, region and size; under Administrator account choose SSH public key and paste your key; under Inbound port rules allow SSH (22) and HTTP (80). Then Review + create → Create.
Step 2 — Deploy from the Azure CLI
az vm create \
--resource-group <your-rg> \
--name trino-gateway \
--image <marketplace-image-urn> \
--size Standard_B4ms \
--admin-username azureuser \
--ssh-key-values ~/.ssh/id_ed25519.pub \
--vnet-name <your-vnet> --subnet <your-subnet> \
--public-ip-sku Standard
az vm open-port --resource-group <your-rg> --name trino-gateway --port 80 --priority 1010
Step 3 — Connect to your VM
ssh azureuser@<vm-public-ip>
Step 4 — Confirm the services are running
systemctl is-active postgresql.service trino.service trino-gateway.service trino-gateway-register.service nginx.service
All five report active. Both the gateway and the bundled Trino are JVM services, so they take around 30–60 seconds after boot to finish starting; the gateway then routes queries as soon as its backend passes a health check. The gateway (127.0.0.1:8080) and the bundled Trino (127.0.0.1:8081) are bound to loopback — only nginx on :80 is exposed publicly.

Step 5 — Retrieve your dashboard password
The admin password is generated uniquely on the first boot of your VM and written to a root-only file:
sudo cat /root/trino-gateway-credentials.txt
This file contains gateway.user (admin) and gateway.password, plus the dashboard URL. The same per-VM password is used for both the gateway dashboard login and the nginx Basic-auth wall on the query path. The gateway's PostgreSQL role also gets its own per-VM password, injected into the running service and never baked into the shipped image. Store the password somewhere safe.

Step 6 — Check the health endpoint
nginx serves an unauthenticated health endpoint for load balancers and probes:
curl -s http://localhost/health
It returns ok.
Step 7 — Open the Trino Gateway dashboard
Browse to http://<vm-public-ip>/ and sign in as admin with the password from Step 5. The dashboard summarises the routing fleet — how many backends are registered, online and healthy, plus queries-per-hour and a query-distribution chart.

Open the Cluster view to see the registered Trino backend the gateway routes to — the bundled single-node coordinator, its routing group (adhoc) and its proxy address:

Step 8 — Send a query through the gateway
A standard Trino client points straight at the gateway's endpoint and the gateway transparently forwards the query to a healthy backend. The bundled tpch catalog exposes the standard TPC-H schemas (tiny, sf1, …) so you can query real sample data with no external data source. Run a query through the gateway (port 8080) with the bundled CLI:
/opt/trino/bin/trino --server http://127.0.0.1:8080 --user admin --catalog tpch --schema tiny --execute 'SELECT count(*) FROM nation'
It returns 25 — the query was routed through Trino Gateway to the bundled Trino coordinator and back. The nginx Basic-auth wall guards the same query path off-host, and the gateway dashboard has its own per-VM login (the image ships no default admin):

Try a richer query — total order value by market segment, routed through the gateway:
/opt/trino/bin/trino --server http://127.0.0.1:8080 --user admin --catalog tpch --schema tiny --execute "SELECT c.mktsegment, round(sum(o.totalprice), 2) AS revenue FROM orders o JOIN customer c ON o.custkey = c.custkey GROUP BY c.mktsegment ORDER BY revenue DESC"
Step 9 — View routed-query history
Every query the gateway routes is recorded in its PostgreSQL history store. Inspect the registered backend and the recorded routing history directly:
sudo -u postgres psql -d trinogateway -c "SELECT name, routing_group, backend_url, active FROM gateway_backend"
sudo -u postgres psql -d trinogateway -c "SELECT to_char(to_timestamp(created/1000),'HH24:MI:SS') AS at, user_name, backend_url, left(query_text,40) AS query FROM query_history ORDER BY created DESC LIMIT 5"
The same history is browsable in the dashboard's History tab — each row shows the routing group, the backend the query was routed to, the user, the client source and the SQL text:


Step 10 — Add more Trino clusters and routing groups
The whole point of Trino Gateway is to sit in front of many Trino clusters. To add another backend, register it through the gateway's admin API (obtain a session token by signing in), or add it in the dashboard's Cluster view. Backends are grouped by routing group; a client can target a group with the X-Trino-Routing-Group header, and requests with no header fall to the default adhoc group. The Routing rules view controls how requests map to groups:

Point a new cluster's proxyTo at its coordinator URL and set active: true; the gateway health-checks each backend (via its v1/info endpoint) and only routes to healthy clusters, so you can drain a cluster for maintenance by marking it inactive without dropping client connections.
Step 11 — Connect BI tools and applications
Because the gateway speaks the standard Trino client protocol, most BI and analytics tools connect through the official Trino JDBC/ODBC drivers or a native Trino connector — pointed at the gateway, not at an individual cluster. Point the client at the VM on port 80 and select the tpch catalog (or any catalog you add to a backend). For example, the JDBC URL is:
jdbc:trino://<vm-public-ip>:80/tpch/tiny
Tools such as DBeaver, Superset, Tableau, Power BI and Metabase all connect this way. For production use, terminate TLS in front of nginx (see Enabling HTTPS) and use jdbc:trino://<host>:443/... with SSL enabled. As you add real Trino clusters behind the gateway, clients keep using this one endpoint while the gateway load-balances across the healthy backends.
Enabling HTTPS
The nginx reverse proxy terminates plain HTTP on port 80. For public exposure, put a certificate in front of it: add a DNS name for the VM and either use the companion cloudimg nginx-ssl-certbot image as a TLS reverse proxy, or install certbot and extend the existing nginx site with a listen 443 ssl; server block and your certificate paths. Keep the gateway and the bundled Trino bound to loopback so the only public surface is the authenticated, TLS-terminated proxy.
Maintenance
- Gateway configuration: the gateway config lives at
/etc/trino-gateway/config.yaml(datastore, health monitor, authentication). The per-VM DB password is injected from/etc/trino-gateway/gateway.env. Edit andsudo systemctl restart trino-gatewayto apply changes. - Bundled Trino configuration: Trino's config is under
/opt/trino/etc/; catalogs live in/opt/trino/etc/catalog/. Edit andsudo systemctl restart trino. - Adding backends: register additional Trino clusters through the gateway (Step 10) — the routing state is persisted in PostgreSQL and survives restarts.
- Backups: back up the
trinogatewayPostgreSQL database (routing config + query history). - Upgrades: replace
/opt/trino-gateway/gateway-ha.jar(or/opt/trino) with a newer release matching the required JDK, and restart the service. - Security patches: unattended-upgrades remains enabled so the OS continues to receive security updates automatically.
Support
cloudimg provides 24/7 expert support for this image. Contact support@cloudimg.co.uk.
Trino and Trino Gateway are trademarks of the Trino Software Foundation. This image is produced by cloudimg and is not affiliated with or endorsed by the Trino project. Trino and Trino Gateway are distributed under the Apache License 2.0.