Deploy PostGIS
PostgreSQL 17 with PostGIS 3.5 for maps, geocoding and spatial queries.
PostGIS
Just deployed
/var/lib/postgresql/data
Deploy and Host PostGIS on Railway
![]()
PostGIS turns PostgreSQL into the most widely used open-source spatial database. It adds geometry and geography types, spatial indexes and hundreds of functions for distance, intersection, buffering, projections and geocoding. This template runs the official PostGIS image (PostgreSQL 17 with PostGIS 3.5) on Railway, with the spatial extensions enabled, a generated password and your data on a persistent volume. Supabase's free tier pauses after a week of inactivity and its Pro plan starts at $25/month. A dedicated PostGIS server on Railway costs about $3–8/month and never sleeps.
What This Template Deploys
| Service | Purpose |
|---|---|
| PostGIS | The official postgis/postgis:17-3.5 image: PostgreSQL 17 with PostGIS 3.5, topology, fuzzy string matching and the TIGER geocoder enabled in postgis_db. |
| Persistent Volume | Mounted at /var/lib/postgresql/data. Tables, spatial indexes and roles survive redeploys and restarts. |
It's a single database service. Other services in your Railway project connect over the private network with DATABASE_URL. For desktop GIS tools such as QGIS, turn on a TCP proxy to get a public connection.
About Hosting PostGIS
Plain PostgreSQL can't answer "which stores are within 5 km of this customer?" or "which parcels intersect this flood zone?" efficiently. PostGIS can, with GiST spatial indexes and functions like ST_DWithin, ST_Intersects and ST_Transform. Installing it yourself means matching PostGIS, GEOS, PROJ and GDAL versions to your Postgres build, which is where many managed databases fall short or lag behind.
This template uses the PostGIS project's own Docker image, so every library is compiled and tested together. On Railway, you get a persistent volume, a generated password, private networking for your apps, and one-click backups from the volume settings. Unlike serverless databases, it's always on, so there are no cold starts in the middle of a map render.
Enabling outside access. The template doesn't expose the database publicly by default. To connect from QGIS, DBeaver or psql on your laptop, open the PostGIS service's Settings, Networking, add a TCP Proxy on port 5432, then use DATABASE_PUBLIC_URL.
Typical cost: ~$3–8/month on Railway for a small spatial database, plus storage as your datasets grow. Supabase Pro starts at $25/month, and Neon bills compute by the hour once you pass its free tier.
Deploy PostGIS in Under 3 Minutes
- Click Deploy on Railway. PostgreSQL initialises and enables PostGIS (about a minute).
- Copy
DATABASE_URLinto the app that will query it, or reference it from another Railway service. - Optionally add a TCP proxy on port
5432for access from QGIS or a local SQL client. - Load data with
shp2pgsql,ogr2ogror QGIS's database manager. - Run spatial queries, for example
SELECT name FROM places WHERE ST_DWithin(geom, ST_MakePoint(-0.12, 51.5)::geography, 5000);.
No compiling GEOS or PROJ. No extension version mismatches. No idle shutdowns.
Common Use Cases
- Location search. Find the nearest stores, drivers, listings or events with indexed distance queries.
- Delivery and logistics. Geofences, service areas and route-related lookups for dispatch apps.
- Map backends. Serve vector tiles to MapLibre or Leaflet with tools like Martin or pg_tileserv.
- GIS analysis. Run QGIS workflows against a shared, always-on database instead of local files.
- Real estate and urban planning. Parcel boundaries, zoning layers and spatial joins.
- IoT and fleet tracking. Store GPS points and query trips, dwell times and areas visited.
- US address geocoding. The TIGER geocoder extension is enabled for address-to-coordinate lookups.
- Geospatial APIs. Back a REST or GraphQL API (PostgREST, Hasura, your own code) with spatial filters.
Configuration
| Variable | Required | Description |
|---|---|---|
POSTGRES_USER | ✅ Set | postgis_admin, the superuser created on first boot. |
POSTGRES_PASSWORD | 🔐 Auto-generated | Superuser password. |
POSTGRES_DB | ✅ Set | postgis_db, the database with PostGIS extensions enabled. |
DATABASE_URL | ✅ Auto-injected | Private connection string for services in the same project. |
DATABASE_PUBLIC_URL | Optional | External connection string. It works once you add a TCP proxy on port 5432. |
PGDATA | ✅ Set | /var/lib/postgresql/data/pgdata, a subfolder of the volume. Leave it as is. |
Extensions included. postgis, postgis_topology, fuzzystrmatch and postgis_tiger_geocoder are created in postgis_db on first boot. For raster data, run CREATE EXTENSION postgis_raster;. To use PostGIS in another database, run CREATE EXTENSION postgis; in it.
Connecting from another Railway service. Add a variable such as DATABASE_URL=${{PostGIS.DATABASE_URL}} to your app service. It resolves to the private hostname, so traffic never leaves Railway's network and doesn't count as public egress.
PostGIS on Railway vs. Alternatives
| PostGIS on Railway | Supabase | Neon | AWS RDS for PostgreSQL | |
|---|---|---|---|---|
| Monthly cost | ~$3–8 usage | Free tier, Pro from $25 | Free tier, then usage-based | Instance-hour pricing |
| PostGIS included | ✅ 3.5, enabled | ✅ Extension | ✅ Extension | ✅ Extension |
| Always on, no cold starts | ✅ Yes | ⚠️ Free tier pauses after a week | ⚠️ Scales to zero on free | ✅ Yes |
| Free tier storage | Pay for usage | 500 MB | 1 GB | ⚠️ 12-month free tier only |
| Superuser access | ✅ Yes | ❌ No | ❌ No | ❌ No |
| Private networking to your apps | ✅ Built in | ⚠️ Public endpoint | ⚠️ Public endpoint | ✅ VPC |
| License | ✅ GPL-2.0 PostGIS, PostgreSQL License | ✅ Open-source core, hosted | ✅ Open-source core, hosted | ❌ Proprietary hosting |
Dependencies for PostGIS Hosting
- Railway account. The Hobby plan ($5/month including $5 of usage) covers small datasets; add storage as you grow.
- A client: your app's Postgres driver, QGIS, DBeaver, psql or GDAL's
ogr2ogr. - Optional: a TCP proxy for connections from outside Railway.
Deployment Dependencies
- PostGIS Documentation: functions and guides
- PostGIS Docker image: the image this template runs
- PostgreSQL Documentation: core database reference
- Railway Volumes Documentation: persistence and backups
Implementation Details
The image is the PostGIS project's official build on PostgreSQL 17, with GEOS, PROJ and GDAL bundled. On first boot, its init script creates the spatial extensions in postgis_db, and in template_postgis for new databases. Data lives in a subfolder of the volume, so the volume's root lost+found folder never blocks initialisation.
The image tag is pinned to 17-3.5. Upgrading PostGIS within PostgreSQL 17 means changing the tag and running ALTER EXTENSION postgis UPDATE;. A PostgreSQL major upgrade needs a dump and restore. Back up first.
Performance tips. Create a GiST index on every geometry column you filter on (CREATE INDEX ON places USING gist (geom);), store data in one SRID and use geography for metre-based distances, and run ANALYZE after bulk loads. For large imports, give the service more RAM in Railway while loading, then scale it back down.
Frequently Asked Questions
What is PostGIS? PostGIS is an extension that adds spatial types, indexes and functions to PostgreSQL, so you can store points, lines and polygons and query them by distance, area and intersection.
How much does PostGIS on Railway cost compared to Supabase or Neon? About $3–8/month for a small database that's always on. Supabase Pro starts at $25/month, and its free tier pauses after a week. Neon's free tier scales to zero, and paid use is billed per compute hour.
Why is DATABASE_PUBLIC_URL empty? The template doesn't enable public access by default. Add a TCP proxy on port 5432 in the service's Networking settings, and the variable fills in.
Do I lose data when Railway redeploys?
No. The database files are on the volume at /var/lib/postgresql/data, so redeploys and restarts keep every table and index. Enable volume backups for extra safety.
Can I connect QGIS to this database?
Yes. Add a TCP proxy, then create a PostGIS connection in QGIS with the proxy host, port, postgis_db and the postgis_admin credentials.
Does it include pgRouting? No. The official PostGIS image includes PostGIS, topology, raster and the TIGER geocoder, but not pgRouting. For routing, use a pgRouting image instead.
Why Deploy and Host PostGIS on Railway?
Railway is a singular platform to deploy your infrastructure stack. Railway will host your infrastructure so you don't have to deal with configuration, while allowing you to vertically and horizontally scale it.
By deploying PostGIS on Railway, you get an always-on spatial database with full superuser access, private networking to your apps and persistent storage, for a few dollars a month.
Template Content
PostGIS
postgis/postgis:17-3.5