Deploy PostGIS | (Just Updated) Spatial Database With Routing, H3 and pgvector
Spatial Postgres with pgRouting, H3 and pgvector, tuned to your plan size
Just deployed
/var/lib/postgresql
Deploy and Host PostGIS on Railway
PostGIS turns PostgreSQL into a spatial database: geometry and geography columns, GiST
indexes, ST_Intersects / ST_DWithin / ST_Distance, raster, topology, and the tiger
geocoder. This template runs PostgreSQL 18.4 with PostGIS 3.6.4, and adds the three
extensions a real spatial project reaches for next — pgRouting 4.0.1 for shortest
path and driving distance, H3 4.2.3 for hexagonal indexing, and pgvector 0.8.6
for embeddings — already installed and already enabled in your database.
About Hosting PostGIS
The database is exposed over a Railway TCP proxy, so any client — psql, QGIS, GDAL,
Prisma, PostgREST, a GIS worker in another project — connects with an ordinary
postgresql:// URL. The DATABASE_URL and DATABASE_PRIVATE_URL variables are filled
in for you, the password is generated per deploy, and everything durable lives on a
volume mounted at /var/lib/postgresql, the parent of the data directory, so a redeploy
keeps your data.
Three things are handled that a stock postgis/postgis container does not handle on
Railway:
- The server is sized from the container's own cgroup limits at boot. PostgreSQL
ships 128 MB
shared_buffers, 4 MBwork_mem, 64 MBmaintenance_work_memand a 4 GBeffective_cache_sizethat describes no container in particular. Those are the settings a spatial workload feels first: GiST index builds aremaintenance_work_mem-bound and spatial joins spill to disk on 4 MB. On an 8 GB instance this deploy comes up with 1907 MBshared_buffersand 119 MBwork_meminstead; measured on the same 5-million-pointST_Intersectsjoin in a 2 GB / 2 vCPU container, 2.20 s becomes 1.23 s. Every value is passed as a start-up argument, so your ownALTER SYSTEMstill overrides it. - TLS uses a key pair generated for your deploy, on your volume. The usual shortcut
is to point
ssl_key_fileat Debian'sssl-cert-snakeoilfiles, which are created when the image is built — so every container started from that public image shares one private key that anybody can pull and read. This deploy generates its own on first boot and keeps it across redeploys. - The listener is pinned to 5432. Railway injects
PORTinto every service and PostgreSQL reads it, which would move the server off the port the TCP proxy dials.
Why Deploy PostGIS?
Managed spatial databases are priced as a premium tier, and the free tiers cap rows or area. Self-hosting on Railway gives you the full extension set with no row limits, usage billing instead of a fixed plan, and private networking to the rest of your project, so your API talks to the database over the internal network at no egress cost.
Running it here rather than on a VPS also means no apt-get install postgresql-18-postgis,
no initdb tuning pass, no certificate to renew, and no server to patch.
Common Use Cases
- Store locator / nearest-neighbour search —
ST_DWithinwith a GiST index over points of interest, with the trigram and fuzzy-string extensions already present for the name search beside it. - Delivery and field-service routing — pgRouting over an OpenStreetMap extract for shortest path, driving distance and the travelling-salesperson solver.
- Geospatial analytics and dashboards — H3 hex aggregation over event data, raster
overlays, and
pg_stat_statementsfor finding the query that costs the most. - RAG over places — pgvector embeddings and geometry in the same row, so a single query can filter by similarity and by distance.
- A GIS backend for QGIS, GeoServer, PostGREST or Prisma — connect over the public
TCP proxy with
sslmode=require.
Dependencies for PostGIS
- The image ghcr.io/bon5co/postgis-railway,
built from
postgis/postgis:18-3.6(PostgreSQL 18.4, PostGIS 3.6.4, GEOS 3.13.1, PROJ 9.6.0, GDAL 3.10.3) with pgRouting, H3 and pgvector added. - A Railway volume for the data directory and the TLS material.
Deployment Dependencies
- No external service is required. The database runs alone.
POSTGRES_PASSWORDis generated for you;DATABASE_URLandDATABASE_PRIVATE_URLare derived from it, so nothing has to be filled in on the deploy form.- Source: PostGIS · pgRouting · H3 · pgvector
Extensions enabled on first boot
postgis, postgis_topology, postgis_raster, postgis_tiger_geocoder,
fuzzystrmatch, pgrouting, h3, h3_postgis, vector, hstore, pg_trgm,
btree_gist, uuid-ossp, pg_stat_statements — in your database and in
template_postgis, so every database you create from that template starts spatial.
Template Content